d3ridi
d3ridi

Reputation: 191

Dart Encapsulation - private data

I know i can create a private property by prefixing its name with an underscore (_).

but if I put the class and the main function in the same file I can access to private properties

class User {
  late String email;
  late String _password;

  User({required String email, required String password})
      : email = email,
        _password = password;
}

void main() {
  User u = User(email: '[email protected]', password: 'mypassword');
  print(u._password); // I can access to this private property
}

if I move the User class to a separate file everything works like expected, and i can't access private properties

import 'user.dart';
void main() {
  User u = User(email: '[email protected]', password: 'mypassword');
  print(u._password); // I can't access to this private property
}

I didn't understand the reason.

Upvotes: 1

Views: 184

Answers (2)

Alex
Alex

Reputation: 2364

Unlike Java, Dart doesn’t have the keywords public, protected, and private. If an identifier starts with an underscore (_), it's private to its library.

https://dart.dev/guides/language/language-tour#important-concepts.

So basically the underscore does not make "variable private" the way we are used to (from languages like Java or C#) but it makes private to the library (which, roughly saying, is the same as a Java package).

That's why if you put the directive part of 'main.dart'; in the user.dart and the directive part 'user.dart'; in the main.dart file you will be able to access the private field, even the class being in a different file. The part of and part directives makes two files the same library.


If you are curious why Dart uses underscores instead of access modifier keywords like public or private, see SDK issue #33383 https://github.com/dart-lang/sdk/issues/33383.

In a nutshell, from what I have understood: since the Dart language supports dynamic member access, it's far more performant use library level visibility than class-based visibility, as @eernstg said:

I think it's important to note that this is actually not about syntax. You could choose lots of different syntactic forms for the same thing, but it's the underlying structure that matters.

Upvotes: 3

Delwinn
Delwinn

Reputation: 1019

If you want to access a variable from a class, use this

class User {
  late String email;
  late String _password;

  User({required String email, required String password})
      : email = email,
        _password = password;

  //this is called a get function, which you can call from class instance.
  String get getUserPassword => _password;
}
import 'user.dart';
void main() {
  User u = User(email: '[email protected]', password: 'mypassword');
  print(u.getUserPassword); // changes here
}

Happy coding!!

Upvotes: 0

Related Questions