# Encapsulation in Dart

# Encapsulation

> Encapsulation is the principle that limits access to of an object's state; and the bundling of methods and operations that do work on a set of data.

In other languages such as C++ and Java, it is common to control access to a field by making it private and having public getters and setters for that field. [In Dart, fields and getters/setter are indistinguishable](https://dart-lang.github.io/linter/lints/unnecessary_getters_setters.html).

## Minimal Encapsulation

The following example has _minimal encapsulation_. 
You can directly access its fields freely.
```dart
class Employee {
  String name;
}

void main() {
  var myEmployee = Employee();
  myEmployee.name = "Bobby";
} 
```

## Private Fields

If you want to restrict access to a certain field outside of a class, you can make it private by prefixing the field name with an underscore.

```dart
class Employee {
  String name;
  int _salary; // Private - This field cannot be accessed outside of this class
}
```

## Read-only fields

If you want read-only (get-only) fields, simply add the `final` keyword.

```dart
class Employee {
  final String name;
}
```

## Setters and Getters 

If we want to have more control over the field, we can use the _"private field, public getter/setter"_ pattern.

For example:

- let's say we want to store the `name` in lowercase
- and, we want to display it with only the first letter capitalized.

We can do something like this:

```dart
String titleCase(String string) => "${string[0].toUpperCase()}${string.substring(1)}";

class Employee {
  String _name;
  String get name => titleCase(_name);
  set name(String newValue) { _name = newValue.toLowerCase(); }
}

void main() {
  var myEmployee = Employee();
  myEmployee.name = "BOBBY";
  print(myEmployee.name); // Bobby
}
```




