Watch the video (8 min)
On this page22 sections
  1. Prerequisites
  2. Connection With Previous Lectures
  3. Learning Objectives
  4. 1. What Is a Static Member?
  5. 2. A Static Field
  6. 3. One Copy, Shared by All
  7. 4. Static Methods
  8. 5. A Static Method Has No this
  9. 6. Call Static Members Through the Class
  10. 7. Class Constants with static const
  11. 8. Static Members You Already Use
  12. 9. Static Method or Top-Level Function?
  13. 10. A Real-World Example
  14. Code Examples
  15. Common Beginner Mistakes
  16. Best Practices
  17. Mini Challenge
  18. Practice Questions
  19. Practice Answers
  20. Quick Revision
  21. Key Takeaways
  22. What's Next?

Lecture 58 — Static Members

Category9 — Object-Oriented Programming
Lecture058 of 140
Estimated video length8 min
TargetDart 3.12.2
LevelBeginner

Every field so far belonged to one object, so no object could answer "how many of us are there?". A static member belongs to the class itself — one copy, shared by all.

Contents

Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways

Every error message in this lecture is real. Each one was produced by running the code shown on Dart 3.12.2, so you will recognize it when you meet it yourself.


Prerequisites

Students should already understand, from Lectures 052–057:

  • classes, objects, fields, and methods
  • constructors, including Student(this.name) and a constructor body
  • this, getters, and setters
  • const, from Lecture 006, and int.parse, from Lecture 010
  • top-level functions and variables, from Lectures 030 and 037

Connection With Previous Lectures

Since Lecture 053, every field has belonged to one object. Ali's Student object has its own name, and Sara's has hers:

dart
class Student {
  String name;
  Student(this.name);
}

Now the school asks: how many students have been created? No single object can know that. Ali's object knows only about Ali. And where should a rule like "the maximum mark is 100" live? It is true for every student, so storing a copy inside each object would be wasteful. We need a member that belongs to the class itself.


Learning Objectives

By the end of this lecture you will be able to:

  • Explain the difference between an instance member and a static member
  • Declare a static field shared by every object of a class
  • Write and call static methods
  • Explain why a static method has no this
  • Define class constants with static const
  • Access static members through the class name
  • Recognize static members you already use, such as int.parse
  • Choose between a static method and a top-level function

1. What Is a Static Member?

A normal field or method is an instance member: every object (instance) gets its own. A static member is marked with the keyword static and belongs to the class, not to any object.

Analogy — in a classroom, every student has their own notebook (instance fields). There is one whiteboard at the front that the whole class shares (a static field). Writing on the whiteboard changes it for everyone.


2. A Static Field

Put static in front of a field. You reach it through the class name, Student.count:

dart
class Student {
  static int count = 0;
  String name;

  Student(this.name) {
    count++;
  }
}

void main() {
  print(Student.count);
  Student('Ali');
  Student('Sara');
  Student('Zayan');
  print(Student.count);
}
output
0
3

Each time the constructor runs, it adds one to the same count. Student.count exists even before any object is created — it printed 0 first.


3. One Copy, Shared by All

Compare an instance field with a static field side by side:

dart
class Student {
  static String school = 'City School';
  String name;
  Student(this.name);
}

void main() {
  var ali = Student('Ali');
  var sara = Student('Sara');

  ali.name = 'Ali Khan';
  Student.school = 'Green School';

  print('${ali.name} — ${Student.school}');
  print('${sara.name} — ${Student.school}');
}
output
Ali Khan — Green School
Sara — Green School

Changing ali.name changed only Ali's object. Changing Student.school changed it for everyone, because there is only one school.


4. Static Methods

A method can be static too. You call it on the class, with no object needed:

dart
class Calculator {
  static int square(int n) {
    return n * n;
  }

  static double average(int a, int b) => (a + b) / 2;
}

void main() {
  print(Calculator.square(4));
  print(Calculator.average(80, 91));
}
output
16
85.5

A static method suits work that needs only its parameters — no object's data.


5. A Static Method Has No this

A static method is not called on an object, so there is no "this object" whose fields it could read. Try to use an instance field:

dart
class Student {
  String name;
  Student(this.name);

  static void describe() {
    print('Student: $name');
  }
}

void main() {
  Student.describe();
}
output
Error: Undefined name 'name'.
    print('Student: $name');
                     ^^^^

Which student's name? There is no answer, so Dart refuses. Your editor (which runs dart analyze) says it even more plainly: "Instance members can't be accessed from a static method." Writing this.name is rejected too:

output
Error: Expected identifier, but got 'this'.
    print(this.name);
          ^^^^

The other direction is fine: an instance method can use static members, because they are always there. Inside the class, you can even drop the class name:

dart
class Student {
  static int count = 0;
  String name;

  Student(this.name) {
    count++;
  }

  void introduce() {
    print('I am $name, one of $count students.');
  }
}

void main() {
  var ali = Student('Ali');
  Student('Sara');
  ali.introduce();
}
output
I am Ali, one of 2 students.

6. Call Static Members Through the Class

Outside the class, a static member is reached through the class name only — not through an object:

dart
class Student {
  static int count = 0;
  String name;
  Student(this.name) {
    count++;
  }
}

void main() {
  var ali = Student('Ali');
  print(ali.count);
}
output
Error: The getter 'count' isn't defined for the type 'Student'.
Try correcting the name to the name of an existing getter, or defining a getter or field named 'count'.
  print(ali.count);
            ^^^^^

Your editor's version is clearer: "The static getter 'count' can't be accessed through an instance. Try using the class 'Student' to access the getter." The same happens with a static method: calc.square(4) gives "The method 'square' isn't defined for the type 'Calculator'." The rule works the other way too — an instance field cannot be read through the class: Student.name gives "Member not found: 'name'."


7. Class Constants with static const

A value that is fixed and the same for every object is a class constant. Write static const:

dart
class Exam {
  static const maxMarks = 100;
  static const passMark = 40;
}

void main() {
  print('Pass mark: ${Exam.passMark} out of ${Exam.maxMarks}');
}
output
Pass mark: 40 out of 100

Inside a class, const alone is not allowed — it must be static const:

output
Error: Only static fields can be declared as const.
Try using 'final' instead of 'const', or adding the keyword 'static'.
  const maxMarks = 100;
  ^^^^^

And like any const, it cannot be changed: Exam.maxMarks = 50; gives "Setter not found: 'maxMarks'."


8. Static Members You Already Use

You have been calling static members since Lecture 010. int.parse is a static method of the int class, and double has static constants:

dart
void main() {
  print(int.parse('42'));
  print(double.parse('99.5'));
  print(double.infinity);
  print(double.infinity > 1000000000);
}
output
42
99.5
Infinity
true

Same pattern: class name, dot, member. You never create an int object to call parse.


9. Static Method or Top-Level Function?

A top-level function, from Lecture 030, also needs no object. So when should a function be static?

  • Use a top-level function for a general helper that is not about one class: double toFahrenheit(double c).
  • Use a static member when it clearly belongs to the class: Student.count, Exam.passMark, int.parse. The class name tells the reader where it comes from.

Dart's style guide warns against a class that holds only static members — use top-level functions and constants for that instead.


10. A Real-World Example

dart
class BankAccount {
  static const minDeposit = 100;
  static int accountsOpened = 0;

  String owner;
  int balance = 0;

  BankAccount(this.owner) {
    accountsOpened++;
  }

  static bool isValidDeposit(int amount) => amount >= minDeposit;

  void deposit(int amount) {
    if (isValidDeposit(amount)) {
      balance += amount;
      print('$owner deposited $amount. Balance: $balance');
    } else {
      print('$owner: deposits must be at least $minDeposit.');
    }
  }
}

void main() {
  var ali = BankAccount('Ali');
  var sara = BankAccount('Sara');

  ali.deposit(500);
  sara.deposit(50);
  sara.deposit(1200);

  print('Accounts opened: ${BankAccount.accountsOpened}');
  print(BankAccount.isValidDeposit(99));
}
output
Ali deposited 500. Balance: 500
Sara: deposits must be at least 100.
Sara deposited 1200. Balance: 1200
Accounts opened: 2
false

owner and balance are instance fields — each account has its own. accountsOpened is shared, minDeposit is a class constant, and isValidDeposit is a static method that deposit and main can both use.


Code Examples

Example 1 — A Static Counter

dart
class Book {
  static int count = 0;
  Book() {
    count++;
  }
}

void main() {
  Book();
  Book();
  print(Book.count);
}
output
2

Example 2 — A Shared Field

dart
class Car {
  static String brand = 'Dartmobile';
  String color;
  Car(this.color);
}

void main() {
  var a = Car('red');
  var b = Car('blue');
  print('${a.color} ${Car.brand}');
  print('${b.color} ${Car.brand}');
}
output
red Dartmobile
blue Dartmobile

Example 3 — A Static Method

dart
class MathHelper {
  static int cube(int n) => n * n * n;
}

void main() {
  print(MathHelper.cube(3));
}
output
27

Example 4 — Class Constants

dart
class Week {
  static const days = 7;
  static const hoursPerDay = 24;
}

void main() {
  print(Week.days * Week.hoursPerDay);
}
output
168

Example 5 — An Instance Method Using a Static Field

dart
class Player {
  static int highScore = 0;
  String name;
  Player(this.name);

  void score(int points) {
    if (points > highScore) {
      highScore = points;
    }
  }
}

void main() {
  Player('Ali').score(30);
  Player('Sara').score(45);
  print(Player.highScore);
}
output
45

Example 6 — Built-In Static Members

dart
void main() {
  var total = int.parse('15') + int.parse('25');
  print(total);
  print(double.infinity);
}
output
40
Infinity

Example 7 — Student Marks

dart
class Student {
  static const maxMarks = 100;
  String name;
  int marks;
  Student(this.name, this.marks);

  double percentage() => marks / maxMarks * 100;
}

void main() {
  var ali = Student('Ali', 85);
  print('${ali.name}: ${ali.percentage()}%');
}
output
Ali: 85.0%

How it works — maxMarks is the same for every student, so it is one static const instead of a field in each object.

Example 8 — Shopping Total

dart
class Cart {
  static const taxRate = 0.1;
  static double withTax(int amount) => amount + amount * taxRate;
}

void main() {
  print('Total: ${Cart.withTax(2000)}');
}
output
Total: 2200.0

Example 9 — Bank Balance

dart
class Account {
  static int totalDeposits = 0;
  int balance = 0;

  void deposit(int amount) {
    balance += amount;
    totalDeposits += amount;
  }
}

void main() {
  var ali = Account();
  var sara = Account();
  ali.deposit(300);
  sara.deposit(700);
  print('Ali: ${ali.balance}, Sara: ${sara.balance}');
  print('Bank total: ${Account.totalDeposits}');
}
output
Ali: 300, Sara: 700
Bank total: 1000

How it works — each balance belongs to one account; totalDeposits is shared, so it collects deposits from both.

Example 10 — Temperature Conversion

dart
class Temperature {
  static const freezingC = 0.0;
  static double toFahrenheit(double c) => c * 9 / 5 + 32;
}

void main() {
  print(Temperature.toFahrenheit(Temperature.freezingC));
  print(Temperature.toFahrenheit(25));
}
output
32.0
77.0

Common Beginner Mistakes

1. Reading an instance field in a static method

dart
class Student {
  String name;
  Student(this.name);

  // static void describe() => print(name); // ✗
}
output
Error: Undefined name 'name'.

A static method has no object. Make it an instance method, or pass the value as a parameter.

2. Calling a static member through an object

dart
void main() {
  // var ali = Student('Ali');
  // print(ali.count); // ✗
}
output
Error: The getter 'count' isn't defined for the type 'Student'.

Write Student.count.

3. Reading an instance field through the class

dart
void main() {
  // print(Student.name); // ✗
}
output
Error: Member not found: 'name'.

name belongs to an object: ali.name.

4. const without static in a class

dart
class Exam {
  // const maxMarks = 100; // ✗
}
output
Error: Only static fields can be declared as const.

Write static const maxMarks = 100;.

5. Making per-object data static

dart
class Student {
  static String name = ''; // ✗ every student would share one name
}

No error appears — but setting Sara's name would overwrite Ali's. Only data that is truly shared belongs in a static field.


Best Practices

  • Make a member static only when it belongs to the class as a whole.
  • Use static const for fixed values that apply to every object.
  • Always access static members as ClassName.member outside the class.
  • Prefer a top-level function for a helper that is not about one class.
  • Avoid classes that contain nothing but static members.

Mini Challenge

Write a Ticket class for a cinema. It has a static const price = 500, a static field sold counting tickets, and an instance field movie. Create three tickets and print:

output
Tickets sold: 3
Revenue: 1500

Try it yourself before opening the solution.

Show solution
dart
class Ticket {
  static const price = 500;
  static int sold = 0;
  String movie;

  Ticket(this.movie) {
    sold++;
  }
}

void main() {
  Ticket('Space Trip');
  Ticket('Space Trip');
  Ticket('Ocean Life');
  print('Tickets sold: ${Ticket.sold}');
  print('Revenue: ${Ticket.sold * Ticket.price}');
}
output
Tickets sold: 3
Revenue: 1500

How it works — the constructor adds one to the shared sold for every ticket, and revenue multiplies it by the class constant price.


Practice Questions

Work through these in order — they run from beginner to application to challenge.

Beginner

  1. Write a class Dog with a static field count that goes up in the constructor. Create two dogs and print Dogs: 2.
  2. Write a class Circle with static const pi = 3.14. Print Circle.pi.
  3. Write a class Greeter with a static method hello(String name) that prints Hello, <name>!. Call it for Zayan.

Application

  1. Write a class Converter with a static method kmToMeters(int km). Print the result for 5.

  2. This program does not compile. Fix the print line:

    dart
    class Counter {
      static int value = 10;
    }
    
    void main() {
      var c = Counter();
      print(c.value);
    }
  3. Write a class Shop with static const discount = 0.2 and a static method finalPrice(int price). Print the final price for 1500.

  4. Write a class Student with an instance field name, a static field count, and an instance method info() that prints <name> (total: <count>). Create Ali and Sara, then call info() on Ali.

Challenge

  1. Write a class Thermometer with a static field highest, starting at -1000.0, and an instance method record(double t) that updates highest when t is larger. Record 21.5, 30.0, and 27.5 on different thermometers, then print highest.

  2. Write a class Wallet with an instance field balance and a static field total. A method add(int amount) updates both. Give Ali 200 and Sara 350, then print each balance and the total.

  3. Explain in one sentence why this method does not compile, and fix it by adding a parameter, so that Student.describe('Sara') prints Student: Sara:

    dart
    class Student {
      String name;
      Student(this.name);
    
      static void describe() {
        print('Student: $name');
      }
    }

Practice Answers

Question 1 — Solution

dart
class Dog {
  static int count = 0;
  Dog() {
    count++;
  }
}

void main() {
  Dog();
  Dog();
  print('Dogs: ${Dog.count}');
}
output
Dogs: 2

Question 2 — Solution

dart
class Circle {
  static const pi = 3.14;
}

void main() {
  print(Circle.pi);
}
output
3.14

Question 3 — Solution

dart
class Greeter {
  static void hello(String name) {
    print('Hello, $name!');
  }
}

void main() {
  Greeter.hello('Zayan');
}
output
Hello, Zayan!

Question 4 — Solution

dart
class Converter {
  static int kmToMeters(int km) => km * 1000;
}

void main() {
  print(Converter.kmToMeters(5));
}
output
5000

Question 5 — Solution

value is static, so read it through the class. The object is no longer needed:

dart
class Counter {
  static int value = 10;
}

void main() {
  print(Counter.value);
}
output
10

Question 6 — Solution

dart
class Shop {
  static const discount = 0.2;
  static double finalPrice(int price) => price - price * discount;
}

void main() {
  print(Shop.finalPrice(1500));
}
output
1200.0

Question 7 — Solution

dart
class Student {
  static int count = 0;
  String name;

  Student(this.name) {
    count++;
  }

  void info() {
    print('$name (total: $count)');
  }
}

void main() {
  var ali = Student('Ali');
  Student('Sara');
  ali.info();
}
output
Ali (total: 2)

count is read when info() runs, after both students exist, so it shows 2.

Question 8 — Solution

dart
class Thermometer {
  static double highest = -1000.0;

  void record(double t) {
    if (t > highest) {
      highest = t;
    }
  }
}

void main() {
  Thermometer().record(21.5);
  Thermometer().record(30.0);
  Thermometer().record(27.5);
  print(Thermometer.highest);
}
output
30.0

Question 9 — Solution

dart
class Wallet {
  static int total = 0;
  int balance = 0;

  void add(int amount) {
    balance += amount;
    total += amount;
  }
}

void main() {
  var ali = Wallet();
  var sara = Wallet();
  ali.add(200);
  sara.add(350);
  print('Ali: ${ali.balance}');
  print('Sara: ${sara.balance}');
  print('Total: ${Wallet.total}');
}
output
Ali: 200
Sara: 350
Total: 550

Question 10 — Solution

A static method has no object, so it cannot know which student's name to print. Pass the name in instead:

dart
class Student {
  String name;
  Student(this.name);

  static void describe(String name) {
    print('Student: $name');
  }
}

void main() {
  Student.describe('Sara');
}
output
Student: Sara

Quick Revision

  1. What is the difference between an instance field and a static field?
  2. How many copies of a static field exist when you create five objects?
  3. Why can't a static method use this?
  4. Can an instance method read a static field?
  5. How do you call a static method from main()?
  6. Why is const maxMarks = 100; inside a class an error?
  7. Name two static members of Dart's built-in number classes.

Key Takeaways

  • An instance member belongs to each object; a static member belongs to the class.
  • A static field has exactly one copy, shared by every object — perfect for counters.
  • A static method needs no object and has no this, so it cannot read instance fields.
  • Instance methods can use static members freely.
  • Outside the class, use ClassName.member — static members are not reached through objects.
  • static const defines class constants; const alone is not allowed on a field.
  • int.parse and double.infinity are static members you already know.
  • Prefer top-level functions for general helpers; use static for what belongs to the class.

What's Next?

Lecture 59 — Inheritance. Category 9 is complete: you can build classes with fields, methods, constructors, private members, and now static members. But what if a Teacher and a Student share a name, an age, and an introduce() method? Writing it twice is wasteful. Category 10 opens with inheritance — building a new class on top of an existing one.


Video lecture

Subscribe
Placeholder video — the real recording isn't linked yet.