Dart is an object-oriented language that treats every value as an object. An object stands for an instance of a class, and a class is a template or definition of an object. It could also be described with the following analogy: we all have some idea of a person – with two arms, two legs, a head and a torso. This pattern of a thouhgt can be called a class. A real person (actually an instance of this class) is an object of this class.
The class is identified using the class keyword:
class Person{ }
The Person class is defined here. After the name of the class you should insert curly brackets, between which the body of the class with its fields and methods is located.
Any object typically has two main characteristics: state – consists of data that the object stores, and behavior – actions that the object can complete.
In order to store the state of an object in a class, you should apply the fields or variables of the class. Methods are used to set the behavior of an object in a class. For instance, a Person class that identifies a person might have the following definition:
class Person{ String name = "undefined"; // name int age = 0; // age void display(){ print("Name: $name Age: $age"); } }
The Person class has two important fields: person’s name and person’s age. Additionally, the display method is also defined, which returns nothing and just forwards this data to the console.
It is worth noting that since the variables name and age go as the String and int types, which do not take null values, we need to provide these variables with initial values. Or alternatively we could use nullable types, then providing initial values would not be required:
class Person{ String? name; // name int? age; // age void display(){ print("Name: $name Age: $age"); } }
Now we can use this class. For that, define the following program:
void main (){ Person tom; } class Person{ String name = "undefined"; // name int age = 0; // age void display(){ print("Name: $name Age: $age"); } }
A class represents a new type, so we can determine variables that represent a given type. Thus, here in the main function, the tom variable is defined, which represents the Person class. Yet the same variable does not point to any object and by default will have the value null. At last, it cannot be used yet, so first you will have to create an object of the Person class.
Constructors Option
Besides the usual methods, classes can identify special methods, which are called constructors. Constructors are activated when creating a new object of this class. Constructors mainly used to complete object initialization.
In case no constructor is there in a class, a constructor without parameters is automatically called for that class.
The above created Person class has no constructors. Thus, a default constructor is automatically designed for it, which we can use to finalize a Person object. To illustrate, we will create one object:
void main (){ Person tom = Person(); tom.display(); // change name and age tom.name = "Tom"; tom.age = 35; tom.display(); } class Person{ String name = "undefined"; int age = 0; void display(){ print("Name: $name Age: $age"); } }
In order to create a Person object, you should use the expression Person(). Older versions of Dart could also be included the new: Person tom = new Person (); operator to call the constructor. But in recent versions of Dart, the new operator can be simply ignored.
The default constructor does not operate with just any parameters. Because of that, after running this expression, a section will be assigned in memory where all the data of the Person object will be located. And the tom variable will get a reference to the created object.
If the constructor does not initialize the values of the object variables, then they go by default values, that is, the null value, that is the actual absence of a value.
When creating the object, you can access the variables and methods of the Person object with the tom variable. To do this, just use the dot (.) operator to specify the name of the field or method through the dot: tom.name. For instance, you can set or get the values of the fields: tom.name = “Tom”.
After the execution, you should see the following on the console:
Name: indefinite Age: 0 Name: Tom Age: 35
Null and Classes Features
Similar to other built-in types, classes by default define a type that does not permit a null value. If you need an object of the class to store a null value, you can use the nullable class that adds the operator to the type definition:
void main (){ Person? sam; print(sam); // null - sam accepts the value null Person tom; // print(tom); // ! Error, tom can't accept null }
In the case of the print(tom) call, as in the case of other types of variables that cannot allow the null value, you are expected to assign the variable an initial value before refering to it.
Additionally, when using nullable classes, it is possible for you to get into the following situation. As stated above, to access the fields and methods of the object, the dot (.) operator is inserted, after which the name of the field/method is set. Neverthless, if variables are not assigned a value, then they default to null, which may need to be taken into consideration. To illustrate, we refer to the fields of an object through a variable that is not initialized:
void main (){ Person? sam; sam.age = 23;// Error, sam = null } class Person{ String name = "undefined"; int age = 0; void display(){ print("Name: $name Age: $age"); }
After executing a line of code sam. age = 23, the program activates an exception and ends its execution since we didn’t create an object of the Person class using the constructor. On that account, the variable sam has the value null, that is, there is no object. With that, we cannot access the fields of a non-existent object yet is it possible to avoid this problem by using a different operator -?. to access the fields:
void main (){ Person sam; sam?.age = 19; sam?.display(); } class Person{ String name = "undefined"; int age = 0; void display(){ print("Name: $name Age: $age"); } }
The operator ?. goes through the value of the variable, and if the variable is not null, then access to its fields and methods occurs. In case it is null, the reference to the variable is omitted.