Dart Access Modifiers


Access Modifiers in Dart

In Dart, access modifiers are used to control the visibility and accessibility of class members (fields and methods). Access modifiers determine how and where the members of a class can be accessed from other parts of the code.

Dart has the following access modifiers:

  1. Public Members: By default, all members of a class are public. This means they can be accessed from anywhere in the program.
  2. Private Members: Dart uses a convention for private members, where any member that starts with an underscore (_) is considered private to the library. Private members cannot be accessed outside of the library where they are defined.

Unlike other languages like Java or C++, Dart doesn't have explicit keywords like public, private, or protected. Instead, it uses the underscore (_) prefix to mark a member as private.


Public Members

By default, members of a class are public in Dart, meaning they can be accessed from anywhere in the program.

class Person { String name; int age; // Constructor Person(this.name, this.age); // Public method void displayInfo() { print('Name: $name, Age: $age'); } } void main() { var person = Person('Alice', 25); // Accessing public members print(person.name); // Output: Alice person.displayInfo(); // Output: Name: Alice, Age: 25 }

Explanation:

  • name and age are public fields.
  • The displayInfo method is also public, and it can be accessed from outside the class.

Private Members

To make a member private to the class or library, you use the underscore (_) prefix. Private members can only be accessed within the same library, not from outside.

class Person { String name; int _age; // Private member // Constructor Person(this.name, this._age); // Public method to access private field void displayInfo() { print('Name: $name, Age: $_age'); } // Public method to modify the private field void setAge(int age) { _age = age; } // Public method to access the private field int getAge() { return _age; } } void main() { var person = Person('John', 30); // Accessing public members print(person.name); // Output: John person.displayInfo(); // Output: Name: John, Age: 30 // Attempting to access the private member _age directly results in an error // print(person._age); // Error: The getter '_age' isn't defined for the class 'Person'. // Accessing and modifying the private field via public methods person.setAge(35); print('Updated Age: ${person.getAge()}'); // Output: Updated Age: 35 }

Explanation:

  • _age is a private field. It is only accessible inside the Person class or library, so you cannot access it directly outside the class (e.g., person._age would result in an error).
  • To interact with private members, we provide getter and setter methods (getAge and setAge) to allow controlled access to private fields.

Private Members and Libraries

In Dart, privacy is scoped to the library, not the class. This means that if two classes are in the same library (e.g., the same Dart file), they can access each other's private members. However, if they are in different libraries (Dart files), they cannot access each other's private members.

Example of Private Members in Different Libraries:

Let's create two Dart files to demonstrate this.

file1.dart:

class Person { String name; int _age; // Private field // Constructor Person(this.name, this._age); // Public method to access private field void displayInfo() { print('Name: $name, Age: $_age'); } void setAge(int age) { _age = age; } int getAge() { return _age; } }

file2.dart:

import 'file1.dart'; // Import the first file void main() { var person = Person('Alice', 28); // Accessing public method and field person.displayInfo(); // Output: Name: Alice, Age: 28 // Trying to access the private member _age directly would cause an error // print(person._age); // Error: The getter '_age' isn't defined for the class 'Person'. // Accessing private member via getter method person.setAge(30); print('Updated Age: ${person.getAge()}'); // Output: Updated Age: 30 }

Explanation:

  • In file1.dart, Person has a private member _age.
  • In file2.dart, which imports file1.dart, we cannot access _age directly. Instead, we use the public methods (getAge and setAge) to interact with the private field.

Summary of Access Modifiers in Dart:

  1. Public Members:

    • Members without an underscore (_) are public.
    • Public members can be accessed from anywhere.
  2. Private Members:

    • Members with an underscore (_) are private.
    • Private members are only accessible within the same library (same Dart file, unless explicitly exported).
  3. Library Scope:

    • In Dart, privacy is scoped to the library, not the class. Two classes in the same Dart file can access each other’s private members.

Output for Example:

Name: John, Age: 30 Name: John, Age: 30 Updated Age: 35

In this example:

  • We define both public and private members (name is public, and _age is private).
  • We use public methods (setAge, getAge) to modify and access the private field _age.

This shows how Dart uses the underscore to implement privacy and how we can control access to the internal details of a class.