print object properties in Dart [duplicate] - dart

This question already has answers here:
Default stringify for objects, equivalent to Java's toString?
(3 answers)
Closed 2 years ago.
I have a simple Dart file:
class Person {
String name;
int age;
}
void main() {
var person1 = Person();
person1.name = 'Rajesh';
person1.age = 20;
print("person name $person1.name ");
print(person1.name);
}
I just want to print print("person name $person1.name ");, and i want output as person name Rajesh. But i am getting output as person name Instance of 'Person'.name.
Need some help, i am new to Dart.
`

You have to use this:
print("person name ${person1.name} ");
alternatively you can override toString in class:
#override
String toString() {
return '''
person name $name
''';
}
then:
print(person1);

You probably meant:
print("person name: ${person1.name} ");
Remember that you can specify a toString() method in the class:
class Person {
String name;
int age;
String toString() => "${name} is ${age} years old";
}
and use it as follows:
class Person {
String name;
int age;
String toString() => "${this.name} is ${this.age} years old";
}
void main() {
Person person = new Person();
person.name = "John";
person.age = 25;
print(person); // John is 25 years old
}

Here, the error is in the interpolation string.
In general, when you use more than one object, you should use the full form of the string interpolation ${} rather than just $.
For your code, do this instead:
print('person name : ${person1.name}');
I hope that will be useful to you.

Related

Dart object as a value

I remember that Dart objects have a method which does an object return a value by default without pointing to an property. Example:
class A {
final String name;
A(this.name);
...
}
main() {
var obj = A('chesu');
print(obj + ' locuaz');
}
Output: chesu locuaz
But I don't remember that method or decorator and it is not toString().
Use interpolation to compose strings and values. It will automatically call toString method of value.
class A {
A(this.name);
final String name;
#override
toString() => name;
}
main() {
var obj = A('chesu');
print('$obj locuaz');
}
I finally found what I was looking for, it's called callable classes.

Why there is a colon symbol (:) with the class constructor in Dart?

I am new in Dart(OOP Languange) which it is a bit similar in Java
But this code get me confusion
What is the purpose of colon(:) before the super keyword within SchoolID class that has been inherit with Person class?
Here is the code:
class Person {
String name;
int age;
int height;
Person({this.name, this.age, this.height});
}
class SchoolID extends Person {
int id;
int year;
String name;
SchoolID({this.id, this.year, this.name}) : super(name: name);
}
Another Example ,,, focus on colon the fishmap
AllFish.fromJson(Map<String, dynamic> json)
: fishMap = json.map(
(String k, dynamic v) => MapEntry(
k,
Fish.fromJson(v),
),
);
It's considered as an initializer list which runs before the constructor body, here you're calling the super that means the constructor of your Person class.
It's an initializer. This means the initializer is executed before the constructor body

Is it possible to add setter for inner(nested) fields in dart?

In dart we can execute some code when value of field is changed using something like
class Name{
String fname;
String lname;
}
class Person extends ChangeNotifier{
Name _name = Name();
set name(Name n){
notifyListeners();
_name = n;
}
get name=>_name;
}
//inside main()
Person p = Person();
p.name = Name();
I want to be able to perform similar action while setting inner fields. Such as while doing
p.name.fname ="FooBar";
But I want to be able to do it from Person class.
Because I am extending ChangeNotifier in Person class. And I want to call
notifyListeners()
that is not accessible in Name class. This is best I've come up with
Name newName = Name(p.name); //copy constructor
newName.fname = "Foo Bar";
p.name = newName;
Is there a better way?
What you can do depends on how you can constrain the API.
If Name objects are routinely being created by third-party code and passed around, and are expected to retain their identity when stored in a Person object, then here isn't much you can do. So I wouldn't design the Person object that way.
Instead I'd say that the Name object of a Person object is linked to that, and setting the name of a Person is the same as setting both name parts.
Example:
class Person {
_PersonName _name;
Person(...) : ... {
_name = _PersonName(this);
}
...
void set name(Name name) {
_name.fname = name.fname;
_name.lname = name.lname;
notifyListeners();
}
Name get name => _name;
}
class _PersonName extends Name {
final Person _owner;
_PersonName(this._owner);
void set fname(String fname) {
super.fname = fname;
_owner.notifyListeners();
}
void set lname(String lname) {
super.lname = lname;
_owner.notifyListeners();
}
}
That has the disadvantage that the extracted _PersonName is forever linked to the Person object, even if you try to write a different Name object.
Another option is to create a new _PersonName on every store a new name object, and detach the old object from the Person at that point:
class Person {
_PersonName _name = _PersonName;
Person(...) : ... {
_name = _PersonName(this, null, null);
}
void set name(Name name) {
_name.owner = null;
_name = _PersonName(this, name.fname, name.lname);
notifyListeners();
}
Name get name => _name;
}
class _PersonName extends Name {
Person _owner;
_PersonName(this._owner, String fname, String lname) {
super.fname = fname;
super.lname = lname;
}
void set fname(String fname) {
super.fname = fname;
owner?.notifyListeners();
}
void set lname(String lname) {
super.lname = lname;
owner?.notifyListeners();
}
}
This approach behaves mostly like the plain storing of name objects, except that if you do:
var p = Person();
var n = Name();
p.name = n;
print(identical(n, p.name)); // false?
you don't preserve the identity of the Name object stored into the Person object.
There is no way to do so, and also change the behavior of setting strings directly on the name using person.name.fname = ..., so something has to be sacrificed.

Dart Multiple Constructors

Is it really not possible to create multiple constructors for a class in dart?
in my Player Class, If I have this constructor
Player(String name, int color) {
this._color = color;
this._name = name;
}
Then I try to add this constructor:
Player(Player another) {
this._color = another.getColor();
this._name = another.getName();
}
I get the following error:
The default constructor is already defined.
I'm not looking for a workaround by creating one Constructor with a bunch of non required arguments.
Is there a nice way to solve this?
You can only have one unnamed constructor, but you can have any number of additional named constructors
class Player {
Player(String name, int color) {
this._color = color;
this._name = name;
}
Player.fromPlayer(Player another) {
this._color = another.getColor();
this._name = another.getName();
}
}
new Player.fromPlayer(playerOne);
This constructor
Player(String name, int color) {
this._color = color;
this._name = name;
}
can be simplified to
Player(this._name, this._color);
Named constructors can also be private by starting the name with _
class Player {
Player._(this._name, this._color);
Player._foo();
}
Constructors with final fields initializer list are necessary:
class Player {
final String name;
final String color;
Player(this.name, this.color);
Player.fromPlayer(Player another) :
color = another.color,
name = another.name;
}
If your class uses final parameters the accepted answer will not work. This does:
class Player {
final String name;
final String color;
Player(this.name, this.color);
Player.fromPlayer(Player another) :
color = another.color,
name = another.name;
}
If you already used a constructor with params in the project and now you figured out that you need some no params default constructor you can add an empty constructor.
class User{
String name;
User({this.name}); //This you already had before
User.empty(); //Add this later
}
Try the below code on DartPad
class MyClass {
//These two are private attributes
int _age;
String _name;
//This is a public attribute
String defaultName = "My Default Name!";
//Default constructor
MyClass() {
_age = 0;
_name = "Anonymous";
}
MyClass.copyContructor(MyClass fromMyClass) {
this._age = fromMyClass._age;
this._name = fromMyClass._name;
}
MyClass.overloadedContructor(String name, int age) {
this._age = age;
this._name = name;
}
MyClass.overloadedContructorNamedArguemnts({String name, int age}) {
this._age = age;
this._name = name;
}
//Overriding the toString() method
String toString() {
String retVal = "Name:: " + _name + " | " + "Age:: " + _age.toString();
return retVal;
}
}
//The execution starts from here..
void main() {
MyClass myClass1 = new MyClass();
//Cannot access oprivate attributes
//print(myClass1.name);
//print(myClass1.age);
//Can access the public attribute
print("Default Name:: " + myClass1.defaultName);
print(myClass1.toString());
MyClass myClass2 = new MyClass.copyContructor(myClass1);
print(myClass2.toString());
MyClass myClass3 = new MyClass.overloadedContructor("Amit", 42);
print(myClass3.toString());
MyClass myClass4 =
new MyClass.overloadedContructorNamedArguemnts(age: 42, name: "Amit");
print(myClass4.toString());
}
Dart doesn't support parameter overloading (having multiple functions of the same name but with different parameters). This applies to constructors as well - that's the reason why in SDK there're so many classes with named constructors.
In Dart you can use Default Constructor, Named Constructor, Factory Method and Static Method to instantiate classes:
class A {
// Default constructor
A() : msg = '1';
// Named constructor with positional param
A.message(this.msg);
// Factory method with named param
factory A.underscore({String msg = ''}) {
return A.message('_'+msg);
}
// Factory method with arrow func body
static A bang(msg) => A.message('!'+msg);
final String msg;
}
void main() {
print(A().msg);
print(A.message('2').msg);
print(A.underscore(msg: '3').msg);
print(A.bang('4').msg);
}
Output:
1
2
_3
!4
You can use factory constructors
factory Player.fromPlayer(Player another) => Player(another.name, another.color);
i had found solution to solve this problem depend on checked the type of data you are passed it to function
Try this Solution
As Günter Zöchbauer already specified in his answer:
You can only have one unnamed constructor, but you can have any number of additional named constructors in Flutter.
By using named constructor you can create multiple constructors in the same class.
Each constructor will have a unique name. So that you can identify each of them.
Syntax for named constructor :
class_name.constructor_name (arguments) {
// If there is a block of code, use this syntax
// Statements
}
or
class_name.constructor_name (arguments);
// If there is no block of code, use this syntax
For more insights Click Here
To know about various types of constructors in Flutter Click Here
Class User{
User();
User.fromName(this.name);
String? name;
}
If you want to do some more elaborated property calculation (I'm a Swift guy), you can do like this:
class FooProvider {
int selectedFoo;
FooProvider(List<String> usageObjects)
: selectedFoo = firstOne(usageObjects);
static int firstOne(List<String> usageObjects) {
return 2;
}
}

in Dart, given a Type name, how do you get the Type (class) itself? [duplicate]

This question already has answers here:
Create an instance of an object from a String in Dart?
(3 answers)
Closed 8 years ago.
if have a Type, using Mirrors can get the Type name. inversely, given a Type's name, how do you get the Type?
for example, from a Dart-centric version of Angular:
index.html
<form ng-controller='word?reset=true' >
...
</form>
mylib.dart
class Controller {
Controller( Brando brando, Element elem, Map args ) { ... }
}
class Word extends Controller { ... }
class LangList extends Controller { ... }
// Brando, the godfather
class Brando {
...
void compile( Element el ) {
...
// add controller
if( el.attributes.contains( 'ng-controller' ) {
var name = el.attributes.getTypeName(); <== "Word"
var args = el.attributes.getTypeArgs(); <== { 'reset': 'true' }
var type = <get type from camelized Type name> <=== how??
this.controllers.add( reflectClass(type).newInstance(
const Symbol(''), [this,el,args]).reflectee ); <=== instance from type
}
...
}
}
know how to get name of Type, how to get Type from class and Object, and know how to instantiate a Type. missing final piece - how do you derive the Type from its name?
Note: The mirror API is `unstable', so this answer may change over time.
*Note: This may (will) bloat your generated javascript see: https://api.dartlang.org/docs/channels/stable/latest/dart_mirrors/MirrorSystem.html#getSymbol*
import 'dart:mirrors';
class Bar {
}
ClassMirror findClassMirror(String name) {
for (var lib in currentMirrorSystem().libraries.values) {
var mirror = lib.declarations[MirrorSystem.getSymbol(name)];
if (mirror != null) return mirror;
}
throw new ArgumentError("Class $name does not exist");
}
void main() {
ClassMirror mirror = findClassMirror("Bar");
print("mirror: $mirror");
}
output:
mirror: ClassMirror on 'Bar'

Resources