Skip to main content

Menu

System onlineAI Tutorials / 2026

AI Tutorials
Knowledge search

Recent · Popular · Tutorials

  • dart3 tutorials
  • java1 tutorial
  • Javascript3 tutorials
  • Node.js Introduction2 tutorials
  • dartdart · General · In depth
  • JavascriptJavascript · Advanced · In depth
  • JavascriptJavascript · Advanced · Mid
  • JavascriptJavascript · Advanced · Short

Find a tutorial

Tell the assistant what you want to learn. It suggests published chapters.

For example: “I want to learn Rust ownership from the start.” The conversation is kept only in this tab.

0 / 2,000 characters

Enter to send, Shift+Enter for a new line. Do not include personal information.

Chapter 10

Constructors, Fields, and Methods in Depth

This chapter assumes you have already met classes and objects in Dart — the previous chapter introduced a class as a blueprint and an object as a thing built from that blueprint. Now we go deeper into the three parts every class is made of: **fields** (the data an object holds), **constructors** (th
Level: GeneralLength: In depth4 min read

Read at another depth

Constructors, Fields, and Methods in Depth

This chapter assumes you have already met classes and objects in Dart — the previous chapter introduced a class as a blueprint and an object as a thing built from that blueprint. Now we go deeper into the three parts every class is made of: fields (the data an object holds), constructors (the special code that builds a new object), and methods (the actions an object can perform).

Fields: Where an Object Keeps Its Data

A field is a variable that belongs to a class. Every object created from the class gets its own copy.

Code example in dart
class Book {
  String title = 'Untitled';
  int pages = 0;
}

Here every Book starts with the title 'Untitled' and zero pages. You can also mark a field final, which means it can be set once and never changed:

Code example in dart
class Book {
  final String title; // must be set during construction
  Book(this.title);
}

A field that starts with an underscore, like _secret, is private: it can only be used inside the same file. Dart has no private keyword — the underscore is the convention the whole language and its tools follow.

Constructors: How Objects Are Born

A constructor is a special method that runs when you create a new object with the new-style syntax Book('Dune'). In Dart you can write it in several ways.

1. The shorthand constructor

The most common form uses this.fieldName in the parameter list to assign a parameter straight to a field:

Code example in dart
class Book {
  final String title;
  final int pages;
  Book(this.title, this.pages);
}

this.title means "the title field of the object being built." This one line replaces what other languages need five lines for.

2. Named constructors

A class can have several constructors with different names, each useful for a different situation:

Code example in dart
class Book {
  final String title;
  final int pages;

  Book(this.title, this.pages);

  Book.unknown() : title = 'Unknown', pages = 0;
  Book.sample() : title = 'Sample Text', pages = 12;
}

void main() {
  final a = Book('Dune', 412);
  final b = Book.unknown();
  print(b.title); // Unknown
}

Book.unknown() and Book.sample() are called named constructors. The part after the colon (: title = 'Unknown', ...) is an initializer list — code that runs before the constructor body and can only set fields, not read them yet. This is the only place you can initialize final fields with logic rather than parameters.

3. Redirecting constructors

One constructor can hand off the work to another:

Code example in dart
class Book {
  final String title;
  final int pages;
  Book(this.title, this.pages);
  Book.paperback(String title) : this(title, 300);
}

Methods: What an Object Can Do

A method is a function attached to a class. Inside a method, this refers to the object the method was called on — though in Dart you rarely need to write this explicitly.

Code example in dart
class Book {
  final String title;
  final int pages;
  Book(this.title, this.pages);

  String describe() => '$title runs $pages pages.';
  bool isShort() => pages < 200;
}

void main() {
  final b = Book('Hobbit', 310);
  print(b.describe()); // Hobbit runs 310 pages.
  print(b.isShort());  // false
}

The arrow syntax => expression is shorthand for a method whose whole body is one return expression.

Getters and setters

A getter looks like a field from the outside but is computed on demand:

Code example in dart
class Book {
  final String title;
  final int pages;
  Book(this.title, this.pages);

  double get pagesPerDay => pages / 30; // computed, no stored field
}

Callers write b.pagesPerDay with no parentheses, just like a field. A setter (rare in idiomatic Dart) lets assignment trigger code:

Code example in dart
class Temperature {
  double _celsius = 0;
  set fahrenheit(double f) => _celsius = (f - 32) / 1.8;
  double get fahrenheit => _celsius * 1.8 + 32;
}

Overriding toString

Every Dart object inherits a toString() method. Overriding it makes printing useful:

Code example in dart
class Book {
  final String title;
  Book(this.title);

  @override
  String toString() => 'Book($title)';
}

void main() {
  print(Book('Emma')); // Book(Emma) instead of Instance of 'Book'
}

The @override annotation is optional but valuable: it makes the compiler check that a method with that name actually exists in the parent class, catching typos.

Putting It Together

caption: The life of a Dart object, from construction to cleanup. alt: A flow chart with seven steps: a constructor is called, the initializer list runs, field initializers and the constructor body finish, the object becomes ready, its methods and getters are used, the object becomes unreachable, and the garbage collector reclaims its memory.

Two things to note in that diagram. First, the initializer list really does run before anything else — that is why final fields must be set there or in the shorthand parameters. Second, Dart manages memory for you: once no variable points to an object anymore, the garbage collector (the runtime's automatic memory cleaner) frees it. You never write destructor code.

A Warning About Instance Methods and State

Common Errors at This Level

  1. "The final variable must be initialized." You declared a final field but no constructor sets it. Fix: add it to the constructor's parameters or initializer list.
  2. Calling an instance method without an object. describe() alone fails; you need b.describe().
  3. Using this in the initializer list. The object does not fully exist yet, so you cannot call its methods there — only set fields.
  4. Forgetting @override and misspelling a parent method name. Without the annotation, the compiler silently treats your typo as a brand-new method.

Exercise

You write Book(this.title) but forgot to declare a title field in the class. What happens?

Show answer

The compiler reports an error: the shorthand this.title requires an actual field named title to assign to. Add final String title; (or String title;) to the class.

Exercise

Which two places can initialize a final field of a class?

Show answer

In the constructor's parameter list via shorthand (Book(this.title)) or in the initializer list (Book.unknown() : title = 'Unknown';). A final field cannot be assigned anywhere else.

Exercise

What is the difference between a getter and a regular method in Dart, from the caller's point of view?

Show answer

A getter is used without parentheses, like a field (b.pagesPerDay), while a method is called with parentheses (b.describe()). Internally both can run code.

Spotted a mistake, or code that does not work?

Report an issue

Chapter: Constructors, Fields, and Methods in Depth

0 / 2,000 characters

Plain text, for example: the second code sample does not compile. Do not include personal information.

You can't do that