Lesson 11 of 51 beginner

Classes & Objects

Blueprints for Building Anything in Dart

Open interactive version (quiz + challenge)

Real-world analogy

A class is like a cookie cutter -- it defines the shape, and every cookie you stamp out is an object. The cookie cutter says 'heart-shaped, 3 inches wide' but each actual cookie can have different frosting (property values). In team_mvp_kit, classes like UserEntity are cookie cutters that stamp out individual user objects with unique names, emails, and IDs.

What is it?

A class is a blueprint that defines a type of object by bundling together properties (data) and methods (behavior). When you create an object from a class, you get an instance with its own copy of the properties. Dart is a fully object-oriented language -- even numbers and functions are objects. In Flutter, everything from the app itself (MaterialApp) to the tiniest icon is an instance of a class.

Real-world relevance

Classes are the fundamental building blocks of every Flutter app. In team_mvp_kit, UserEntity represents a user, AuthRepository handles login logic, and AuthBloc manages authentication state. Without classes, you would have loose variables and functions with no organization -- like having a kitchen with no drawers or cabinets. Classes give your code structure, reusability, and clarity.

Key points

Code example

class UserEntity {
  final String id;
  final String name;
  final String email;

  const UserEntity({
    required this.id,
    required this.name,
    required this.email,
  });

  String get initials {
    final parts = name.split(' ');
    if (parts.length >= 2) {
      return '${parts[0][0]}${parts[1][0]}'.toUpperCase();
    }
    return name[0].toUpperCase();
  }

  @override
  String toString() => 'UserEntity(id: $id, name: $name)';
}

void main() {
  final user = UserEntity(
    id: 'u-001',
    name: 'Alice Smith',
    email: 'alice@example.com',
  );
  print(user.initials); // AS
  print(user); // UserEntity(id: u-001, name: Alice Smith)
}

Line-by-line walkthrough

  1. 1. Define a class called UserEntity -- this is our blueprint for user objects
  2. 2. Declare a final String property id -- each user has a unique identifier
  3. 3. Declare a final String property name -- stores the user's display name
  4. 4. Declare a final String property email -- stores the user's email address
  5. 5. Mark the constructor as const since all fields are final -- allows compile-time constant objects
  6. 6. The constructor uses required named parameters with this.id, this.name, this.email for concise assignment
  7. 7. Define a getter called initials that computes the user's initials from their name
  8. 8. Split the name by spaces into a list of parts
  9. 9. If there are at least 2 parts, take the first character of each and uppercase them
  10. 10. Otherwise fall back to just the first character of the name, uppercased
  11. 11. Override toString from Object to return a readable string for debugging
  12. 12. In main, create a UserEntity instance using the named constructor parameters
  13. 13. Pass id, name, and email as required named arguments
  14. 14. Print user.initials which computes and returns AS
  15. 15. Print the user object which automatically calls our toString override

Spot the bug

class Counter {
  int count = 0;
  void increment() {
    count++;
  }
  void reset() {
    int count = 0;
  }
}
Need a hint?
Look carefully at the reset method. Is it modifying the class property or doing something else?
Show answer
The reset method declares a new local variable called count instead of modifying the class property. It should be this.count = 0; or just count = 0; without the int keyword. The int keyword creates a brand new local variable that shadows the class property.

Explain like I'm 5

Imagine you have a recipe card for making a sandwich. The recipe says you need bread, filling, and sauce -- those are the properties. It also says how to assemble it -- those are the methods. Every time you follow the recipe, you make an actual sandwich -- that is an object. The recipe card is the class, and each sandwich you make is an object. You can make a turkey sandwich and a ham sandwich from different recipes, just like you make different objects from different classes.

Fun fact

In Dart, even the number 42 is an object -- it is an instance of the int class. You can call methods on it directly: 42.isEven returns true. Dart compiles these to efficient primitives, so you get the elegance of objects with the speed of raw numbers.

Hands-on challenge

Create a Product class with properties: id (String), name (String), price (double), and quantity (int). Add a getter called totalValue that returns price * quantity. Add a method called applyDiscount(double percent) that reduces the price. Override toString to show all properties. Create two Product objects and print their total values.

More resources

Open interactive version (quiz + challenge) ← Back to course: Flutter & Dart