What is Encapsulation?
Encapsulation is one of the four fundamental OOP concepts (along with inheritance, polymorphism, and abstraction). It refers to bundling data (variables) and methods that operate on that data into a single unit (a class) and restricting direct access to some of the object's internal details. This protects the integrity of the data and reduces complexity by hiding implementation details.
Encapsulation in Dart
In Dart, encapsulation is achieved through library‑level privacy. There are no private, protected, or public keywords. Instead, any identifier (variable, method, class) that starts with an underscore _ is considered library private – it is visible only within the same library (usually the same file). This simple mechanism allows you to hide internal details.
Private Fields (Using _)
To make a field private, prefix its name with an underscore. This field can only be accessed within the same file. Attempting to access it from another file results in a compile‑time error.
Getters and Setters
Getters and setters provide controlled access to private fields. They look like methods but are accessed like properties. You can add validation or logic when getting or setting a value.
Read‑Only and Write‑Only Properties
You can create read‑only properties by providing only a getter (no setter), and write‑only properties by providing only a setter (though less common).
Encapsulation in Different Files
Privacy in Dart is based on libraries. If you split your code across files, private members are only accessible within the same file. To share a private member within a package, you can use a part directive, but it's generally better to keep related classes together or provide public getters/setters.
Why Use Encapsulation?
- Data protection: Prevent accidental or unauthorized modification of data.
- Validation: Ensure that data meets certain criteria before being set.
- Flexibility: You can change internal implementation without affecting external code.
- Reduced complexity: Users of your class only need to know the public interface, not the internal details.
- Maintainability: Encapsulated code is easier to debug and modify.
Common Mistakes
- Forgetting that privacy is library‑based: A private member is accessible anywhere in the same file, which might be surprising if you have multiple classes in one file.
- Not providing getters/setters when needed: Making fields private without any access method makes them completely unusable outside the class.
- Using getters/setters for simple fields without validation: If no logic is needed, a public field might be simpler (but then you lose the ability to add logic later without breaking API).
- Creating unnecessary getters/setters: Over‑encapsulation can make code verbose.
Best Practices
- Make fields private by default and provide public getters/setters only when needed.
- Use getters for computed properties (like
areaof a rectangle).
- Use getters for computed properties (like
- Validate data in setters to maintain object integrity.
- -Keep classes focused – each class should have a clear responsibility.
- Use meaningful names for private fields (still follow camelCase, just with leading underscore).
Complete Example
Key Takeaways
- Encapsulation hides internal data and exposes a controlled interface.
- In Dart, privacy is library‑based: use
_to make members private to the file.
- In Dart, privacy is library‑based: use
- Getters and setters provide controlled access to private fields and can include validation.
- Use read‑only properties (only getter) for data that should not be changed externally.
- Encapsulation improves code maintainability, flexibility, and security.