OOPS IN DART - Docx 1
OOPS IN DART - Docx 1
OOP IN DART
OOP In Dart
Object-oriented programming (OOP) is a programming method that uses
objects and their interactions to design and program applications. It is one
of the most popular programming paradigms and is used in many
programming languages, such as Dart, Java, C++, Python, etc.
Advantages
1. Class
2. Object
3. Encapsulation
4. Inheritance
5. Polymorphism
6. Abstraction
Note: The main purpose of OOP is to break complex problems into smaller objects.
You will learn all these OOPs features later in this dart tutorial.
Key Points
CLASS IN DART
Class In Dart
You can declare a class in dart using the class keyword followed by class
name and braces {}. It’s a good habit to write class name in PascalCase. For
example, Employee, Student, QuizBrain, etc.
Syntax
class ClassName {
// properties or fields
// methods or functions
}
class Animal {
String? name;
int? numberOfLegs;
int? lifeSpan;
void display() {
print("Animal name: $name.");
print("Number of Legs: $numberOfLegs.");
print("Life Span: $lifeSpan.");
}
}
Note: This program will not print anything because we have not created any object
of the class. You will learn about the object later. The ? is used for null safety. You
will also learn about null safety later.
class Person {
String? name;
String? phone;
bool? isMarried;
int? age;
void displayInfo() {
print("Person name: $name.");
print("Phone number: $phone.");
print("Married: $isMarried.");
print("Age: $age.");
}
}
class Area {
double? length;
double? breadth;
double calculateArea() {
return length! * breadth!;
}
}
class Student {
String? name;
int? age;
int? grade;
void displayInfo() {
print("Student name: $name.");
print("Student age: $age.");
print("Student grade: $grade.");
}
}
Key Points
Create a class Book with three properties: name, author, and prize. Also,
create a method called display, which prints out the values of the three
properties.
Note: In the next section, you will learn how to create an object from a
class.
OBJECT IN DART
Object In Dart
For example, a bicycle object might have attributes like color, size, and
current speed. It might have methods like changeGear, pedalFaster, and
brake.
Info
Note: To create an object, you must create a class first. It’s a good practice
to declare the object name in lower case.
Instantiation
Once you have created a class, it’s time to declare the object. You can
declare an object by the following syntax:
Syntax
class Bicycle {
String? color;
int? size;
int? currentSpeed;
void display() {
print("Color: $color");
print("Size: $size");
print("Current Speed: $currentSpeed");
}
}
void main(){
// Here bicycle is object of class Bicycle.
Bicycle bicycle = Bicycle();
bicycle.color = "Red";
bicycle.size = 26;
bicycle.currentSpeed = 0;
bicycle.changeGear(5);
bicycle.display();
}
Note: Once you create an object, you can access the properties and
methods of the object using the dot(.) operator.
class Animal {
String? name;
int? numberOfLegs;
int? lifeSpan;
void display() {
print("Animal name: $name.");
print("Number of Legs: $numberOfLegs.");
print("Life Span: $lifeSpan.");
}
}
void main(){
// Here animal is object of class Animal.
Animal animal = Animal();
animal.name = "Lion";
animal.numberOfLegs = 4;
animal.lifeSpan = 10;
animal.display();
}
In this example below there is class Car with three properties: name, color,
and numberOfSeats. The class also has a method called start, which prints
out the message “Car Started”. We also have an object of the
class Car called car.
class Car {
String? name;
String? color;
int? numberOfSeats;
void start() {
print("$name Car Started.");
}
}
void main(){
// Here car is object of class Car.
Car car = Car();
car.name = "BMW";
car.color = "Red";
car.numberOfSeats = 4;
car.start();
Key Points
Challenge
What is Object
class Animal {
String? name;
int? numberOfLegs;
int? lifeSpan;
void display() {
print("Animal name: $name.");
print("Number of Legs: $numberOfLegs.");
print("Life Span: $lifeSpan.");
}
}
void main(){
// Here animal is object of class Animal.
Animal animal = Animal();
animal.name = "Lion";
animal.numberOfLegs = 4;
animal.lifeSpan = 10;
animal.display();
}
class Rectangle{
//properties of rectangle
double? length;
double? breadth;
//functions of rectangle
double area(){
return length! * breadth!;
}
}
void main(){
//object of rectangle created
Rectangle rectangle = Rectangle();
class SimpleInterest{
//properties of simple interest
double? principal;
double? rate;
double? time;
Challenge
CONSTRUCTOR IN DART
Constructor In Dart
Without Constructor
If you don’t define a constructor for class, then you need to set the values
of the properties manually. For example, the following code creates
a Person class object and sets the values for the name and age properties.
Things To Remember
Syntax
class ClassName {
// Constructor declaration: Same as class name
ClassName() {
// body of the constructor
}
}
Note: When you create a object of a class, the constructor is called
automatically. It is used to initialize the values when an object is created.
class Student {
String? name;
int? age;
int? rollNumber;
// Constructor
Student(String name, int age, int rollNumber) {
print(
"Constructor called"); // this is for checking the constructor
is called or not.
this.name = name;
this.age = age;
this.rollNumber = rollNumber;
}
}
void main() {
// Here student is object of class Student.
Student student = Student("John", 20, 1);
print("Name: ${student.name}");
print("Age: ${student.age}");
print("Roll Number: ${student.rollNumber}");
}
Note: The this keyword is used to refer to the current instance of the class.
It is used to access the current class properties. In the example above,
parameter names and class properties of constructor Student are the
same. Hence to avoid confusion, we use the this keyword.
class Teacher {
String? name;
int? age;
String? subject;
double? salary;
// Constructor
Teacher(String name, int age, String subject, double salary) {
this.name = name;
this.age = age;
this.subject = subject;
this.salary = salary;
}
// Method
void display() {
print("Name: ${this.name}");
print("Age: ${this.age}");
print("Subject: ${this.subject}");
print("Salary: ${this.salary}\n"); // \n is used for new line
}
}
void main() {
// Creating teacher1 object of class Teacher
Teacher teacher1 = Teacher("John", 30, "Maths", 50000.0);
teacher1.display();
Note: You can create many objects of a class. Each object will have its own
copy of the properties.
// Constructor
Car(String name, double prize) {
this.name = name;
this.prize = prize;
}
// Method
void display() {
print("Name: ${this.name}");
print("Prize: ${this.prize}");
}
}
void main() {
// Here car is object of class Car.
Car car = Car("BMW", 500000.0);
car.display();
}
class Staff {
String? name;
int? phone1;
int? phone2;
String? subject;
// Constructor
Staff(String name, int phone1, String subject) {
this.name = name;
this.phone1 = phone1;
this.subject = subject;
}
// Method
void display() {
print("Name: ${this.name}");
print("Phone1: ${this.phone1}");
print("Phone2: ${this.phone2}");
print("Subject: ${this.subject}");
}
}
void main() {
// Here staff is object of class Staff.
Staff staff = Staff("John", 1234567890, "Maths");
staff.display();
}
In the avobe section, you have written the constructor in long form. You can
also write the constructor in short form. You can directly assign the values
to the properties. For example, the following code is the short form of the
constructor in one line.
class Person{
String? name;
int? age;
String? subject;
double? salary;
// display method
void display(){
print("Name: ${this.name}");
print("Age: ${this.age}");
print("Subject: ${this.subject}");
print("Salary: ${this.salary}");
}
}
void main(){
Person person = Person("John", 30, "Maths", 50000.0);
person.display();
}
class Employee {
String? name;
int? age;
String? subject;
double? salary;
// Constructor
Employee(this.name, this.age, [this.subject = "N/A", this.salary=0]);
// Method
void display() {
print("Name: ${this.name}");
print("Age: ${this.age}");
print("Subject: ${this.subject}");
print("Salary: ${this.salary}");
}
}
void main(){
Employee employee = Employee("John", 30);
employee.display();
}
class Chair {
String? name;
String? color;
// Constructor
Chair({this.name, this.color});
// Method
void display() {
print("Name: ${this.name}");
print("Color: ${this.color}");
}
}
void main(){
Chair chair = Chair(name: "Chair1", color: "Red");
chair.display();
}
class Table {
String? name;
String? color;
// Constructor
Table({this.name = "Table1", this.color = "White"});
// Method
void display() {
print("Name: ${this.name}");
print("Color: ${this.color}");
}
}
void main(){
Table table = Table();
table.display();
}
Key Points
Default Constructor
In this example below, there is a class Laptop with two properties: brand,
and prize. Lets create constructor with no parameter and print something
from the constructor. We also have an object of the
class Laptop called laptop.
class Laptop {
String? brand;
int? prize;
// Constructor
Laptop() {
print("This is a default constructor");
}
}
void main() {
// Here laptop is object of class Laptop.
Laptop laptop = Laptop();
}
Note: The default constructor is called automatically when you create an object of
the class. It is used to initialize the instance variables of the class.
String? name;
int? age;
String? schoolname;
String? grade;
// Default Constructor
Student() {
print(
void main() {
student.name = "John";
student.age = 10;
student.grade = "A";
print("Name: ${student.name}");
print("Age: ${student.age}");
print("Grade: ${student.grade}");
PARAMETERIZED CONSTRUCTOR IN
DART
Parameterized Constructor
Syntax
class ClassName {
// Instance Variables
int? number;
String? name;
// Parameterized Constructor
ClassName(this.number, this.name);
}
In this example below, there is a class Student with three properties: name,
age, and rollNumber. The class has one constructor. The constructor is used
to initialize the values of the three properties. We also have an object of
the class Student called student.
class Student {
String? name;
int? age;
int? rollNumber;
// Constructor
Student(this.name, this.age, this.rollNumber);
}
void main(){
// Here student is object of class Student.
Student student = Student("John", 20, 1);
print("Name: ${student.name}");
print("Age: ${student.age}");
print("Roll Number: ${student.rollNumber}");
}
Show Output
Name: John
Age: 20
Roll Number: 1
In this example below, there is a class Student with three properties: name,
age, and rollNumber. The class has one constructor. The constructor is used
to initialize the values of the three properties. We also have an object of
the class Student called student.
class Student {
String? name;
int? age;
int? rollNumber;
// Constructor
Student({String? name, int? age, int? rollNumber}) {
this.name = name;
this.age = age;
this.rollNumber = rollNumber;
}
}
void main(){
// Here student is object of class Student.
Student student = Student(name: "John", age: 20, rollNumber: 1);
print("Name: ${student.name}");
print("Age: ${student.age}");
print("Roll Number: ${student.rollNumber}");
}
out put:
Name: John
Age: 20
Roll Number: 1
Name: John
In this example below, there is class Student with two properties: name,
and age. The class has parameterized constructor with default values. The
constructor is used to initialize the values of the two properties. We also
have an object of the class Student called student.
class Student {
String? name;
int? age;
// Constructor
Student({String? name = "John", int? age = 0}) {
this.name = name;
this.age = age;
}
}
void main(){
// Here student is object of class Student.
Student student = Student();
print("Name: ${student.name}");
print("Age: ${student.age}");
}
Show Output
Name: John
Age: 0
In most programming languages like java, c++, c#, etc., we can create
multiple constructors with the same name. But in Dart, this is not possible.
Well, there is a way. We can create multiple constructors with the same
name using named constructors.
Note: Named constructors improves code readability. It is useful when you
want to create multiple constructors with the same name.
In this example below, there is a class Student with three properties: name,
age, and rollNumber. The class has two constructors. The first constructor
is a default constructor. The second constructor is a named constructor.
The named constructor is used to initialize the values of the three
properties. We also have an object of the class Student called student.
class Student {
String? name;
int? age;
int? rollNumber;
// Default Constructor
Student() {
print("This is a default constructor");
}
// Named Constructor
Student.namedConstructor(String name, int age, int rollNumber) {
this.name = name;
this.age = age;
this.rollNumber = rollNumber;
}
}
void main() {
// Here student is object of class Student.
Student student = Student.namedConstructor("John", 20, 1);
print("Name: ${student.name}");
print("Age: ${student.age}");
print("Roll Number: ${student.rollNumber}");
}
Show Output
This is a default constructor
Name: John
Age: 20
Roll Number: 1
class Mobile {
String? name;
String? color;
int? prize;
Mobile(this.name, this.color, this.prize);
// here Mobile() is a named constructor
Mobile.namedConstructor(this.name, this.color, [this.prize = 0]);
void displayMobileDetails() {
print("Mobile name: $name.");
print("Mobile color: $color.");
print("Mobile prize: $prize");
}
}
void main() {
var mobile1 = Mobile("Samsung", "Black", 20000);
mobile1.displayMobileDetails();
var mobile2 = Mobile.namedConstructor("Apple", "White");
mobile2.displayMobileDetails();
}
Show Output
Mobile name: Samsung.
Mobile color: Black.
Mobile prize: 20000
Mobile name: Apple.
In this example below, there is a class Animal with two properties name
and age. The class has three constructors. The first constructor is a default
constructor. The second and third constructors are named constructors.
The second constructor is used to initialize the values of name and age,
and the third constructor is used to initialize the value of name only. We
also have an object of the class Animal called animal.
class Animal {
String? name;
int? age;
// Default Constructor
Animal() {
print("This is a default constructor");
}
// Named Constructor
Animal.namedConstructor(String name, int age) {
this.name = name;
this.age = age;
}
// Named Constructor
Animal.namedConstructor2(String name) {
this.name = name;
}
}
void main(){
// Here animal is object of class Animal.
Animal animal = Animal.namedConstructor("Dog", 5);
print("Name: ${animal.name}");
print("Age: ${animal.age}");
Animal animal2 = Animal.namedConstructor2("Cat");
print("Name: ${animal2.name}");
}
Show Output
Name: Dog
Age: 5
Name: Cat
In this example below, there is a class Person with two properties name
and age. The class has three constructors. The first is a parameterized
constructor which takes two parameters name and age. The second and
third constructors are named constructors. Second constructor fromJson is
used to create an object of the class Person from a JSON. The third
fromJsonString is used to create an object of the class Person from a JSON
string. We also have an object of the class Person called person.
import 'dart:convert';
class Person {
String? name;
int? age;
Person(this.name, this.age);
Person.fromJson(Map<String, dynamic> json) {
name = json['name'];
age = json['age'];
}
Person.fromJsonString(String jsonString) {
Map<String, dynamic> json = jsonDecode(jsonString);
name = json['name'];
age = json['age'];
}
}
void main() {
// Here person is object of class Person.
String jsonString1 = '{"name": "Arjith", "age": 25}';
String jsonString2 = '{"name": "John", "age": 30}';
Person p1 = Person.fromJsonString(jsonString1);
print("Person 1 name: ${p1.name}");
print("Person 1 age: ${p1.age}");
Person p2 = Person.fromJsonString(jsonString2);
print("Person 2 name: ${p2.name}");
print("Person 2 age: ${p2.age}");
}
Show Output
Person 1 name: Arjith
Person 1 age: 25
Person 2 name: John
Person 2 age: 30
Challenge
Try to create a class Car with three properties name, color, and prize and
one method display which prints out the values of the three properties.
Create a constructor, which takes all 3 parameters. Create a named
constructor which takes two parameters name and color. Create an object
of the class from both the constructors and call the method display.
In this example below, there is a class Point with two final properties: x and
y. The class also has a constant constructor that initializes the two
properties. The class also has a method called display, which prints out the
values of the two properties.
class Point {
final int x;
final int y;
const Point(this.x, this.y);
}
void main() {
// p1 and p2 has the same hash code.
Point p1 = const Point(1, 2);
print("The p1 hash code is: ${p1.hashCode}");
Point p2 = const Point(1, 2);
print("The p2 hash code is: ${p2.hashCode}");
// without using const
// this has different hash code.
Point p3 = Point(2, 2);
print("The p3 hash code is: ${p3.hashCode}");
Point p4 = Point(2, 2);
print("The p4 hash code is: ${p4.hashCode}");
}
output
The p1 hash code is: 918939239
The p2 hash code is: 918939239
The p3 hash code is: 745146896
The p4 hash code is: 225789186
Note: Here p1 and p2 has the same hash code. This is because p1 and p2
are constant objects. The hash code of a constant object is the same. This
is because the hash code of a constant object is computed at compile
time. The hash code of a non-constant object is computed at run time. This
is why p3 and p4 have different hash code.
In this example below, there is a class Student with three properties: name,
age, and rollNumber. The class has one constant constructor. The
constructor is used to initialize the values of the three properties. We also
have an object of the class called student.
class Student {
final String? name;
final int? age;
final int? rollNumber;
// Constant Constructor
const Student({this.name, this.age, this.rollNumber});
}
void main() {
// Here student is the object of Student.
const Student student = Student(name: "John", age: 20, rollNumber: 1);
print("Name: ${student.name}");
print("Age: ${student.age}");
print("Roll Number: ${student.rollNumber}");
}
Show Output
Name: John
Age: 20
Roll Number: 1
In this example below, there is a class Car with three properties: name,
model, and prize. The class has one constructor. The constructor is used to
initialize the values of the three properties. We also have an object of the
class Car called car.
class Car {
final String? name;
final String? model;
final int? prize;
// Constant Constructor
const Car({this.name, this.model, this.prize});
}
void main() {
// Here car is object of class Car.
const Car car = Car(name: "BMW", model: "X5", prize: 50000);
print("Name: ${car.name}");
print("Model: ${car.model}");
print("Prize: ${car.prize}");
}
Show Output
Name: BMW
Model: X5
Prize: 50000
Challenge
Create a class Customer with three properties: name, age, and phone. The
class should have one constant constructor. The constructor should
initialize the values of the three properties. Create an object of the class
Customer and print the values of the three properties.
ENCAPSULATION IN DART
Introduction
Encapsulation In Dart
In Dart, Encapsulation means hiding data within a library, preventing it from
outside factors. It helps you control your program and prevent it from
becoming too complicated.
Note: Dart doesn’t support keywords like public, private, and protected. Dart
uses _ (underscore) to make a property or method private. The
encapsulation happens at library level, not at class level.
Getter and setter methods are used to access and update the value of
private property. Getter methods are used to access the value of private
property. Setter methods are used to update the value of private property.
In this example, we will create a class named Employee. The class will have
two private properties _id and _name. We will also create two public
methods getId() and getName() to access the private properties. We will
also create two public methods setId() and setName() to update the private
properties.
class Employee {
// Private properties
int? _id;
String? _name;
// Getter method to access private property _id
int getId() {
return _id!;
}
// Getter method to access private property _name
String getName() {
return _name!;
}
// Setter method to update private property _id
void setId(int id) {
this._id = id;
}
// Setter method to update private property _name
void setName(String name) {
this._name = name;
}
}
void main() {
// Create an object of Employee class
Employee emp = new Employee();
// setting values to the object using setter
emp.setId(1);
emp.setName("John");
// Retrieve the values of the object using getter
print("Id: ${emp.getId()}");
print("Name: ${emp.getName()}");
}
Show Output
Id: 1
Name: John
Private Properties
Private property is a property that can only be accessed from same library.
Dart does not have any keywords like private to define a private property.
You can define it by prefixing an underscore (_) to its name.
In this example, we will create a class named Employee. The class has one
private property _name. We will also create a public method getName() to
access the private property.
class Employee {
// Private property
var _name;
// Getter method to access private property _name
String getName() {
return _name;
}
// Setter method to update private property _name
void setName(String name) {
this._name = name;
}
}
void main() {
var employee = Employee();
employee.s
etName("Jack");
print(employee.getName());
}
output
Jack
In the main method, if you write the following code, it will compile and run
without any error. Let’s see why it is happening.
class Employee {
// Private property
var _name;
// Getter method to access private property _name
String getName() {
return _name;
}
// Setter method to update private property _name
void setName(String name) {
this._name = name;
}
}
void main() {
var employee = Employee();
employee._name = "John"; // It is working, but why?
print(employee.getName());
}
Show Output
John
Reason
The reason is that using underscore (_) before a variable or method name
makes it library private not class private. It means that the variable or
method is only visible to the library in which it is declared. It is not visible
to any other library. In simple words, library is one file. If you write the main
method in a separate file, this will not work.
Solution
To see private properties in action, you must create a separate file for the
class and import it into the main file.
Read-only Properties
You can control the properties’s access and implement the encapsulation in
the dart by using the read-only properties. You can do that by adding the
final keyword before the properties declaration. Hence, you can only access
its value, but you cannot change it.
Note: Properties declared with the final keyword must be initialized at the
time of declaration. You can also initialize them in the constructor.
class Student {
final _schoolname = "ABC School";
String getSchoolName() {
return _schoolname;
}
}
void main() {
var student = Student();
print(student.getSchoolName());
// This is not possible
//student._schoolname = "XYZ School";
}
Show Output
ABC School
Note: You can also define getter and setter using get and set keywords. For
more see this example below.
How To Create Getter and Setter Methods?
You can create getter and setter methods by using the get and set
keywords. In this example below, we have created a class named Vehicle.
The class has two private properties _model and _year. We have also
created two getter and setter methods for each property. The getter and
setter methods are named model and year. The getter and setter methods
are used to access and update the value of the private properties.
class Vehicle {
String _model;
int _year;
// Getter method
String get model => _model;
// Setter method
set model(String model) => _model = model;
// Getter method
int get year => _year;
// Setter method
set year(int year) => _year = year;
}
void main() {
var vehicle = Vehicle();
vehicle.model = "Toyota";
vehicle.year = 2019;
print(vehicle.model);
print(vehicle.year);
}
Show Output
Toyota
2019
Note: In dart, any identifier like (class, class properties, top-level function,
or variable) that starts with an underscore _ it is private to its library.
● Data Hiding: Encapsulation hides the data from the outside world. It
prevents the data from being accessed by the code outside the class.
This is known as data hiding.
● Testability: Encapsulation allows you to test the class in isolation. It
will enable you to test the class without testing the code outside the
class.
● Flexibility: Encapsulation allows you to change the implementation of
the class without affecting the code outside the class.
● Security: Encapsulation allows you to restrict access to the class
members. It will enable you to limit access to the class members
from the code outside the library.
GETTER IN DART
Getter In Dart
Syntax
return_type get property_name {
// Getter body
}
Note: Instead of writing { } after the property name, you can also write =>
(fat arrow) after the property name.
In this example below, there is a class named Person. The class has two
properties: firstName and lastName. There is a getter fullName which is
responsible for getting the full name of a person.
class Person {
// Properties
String? firstName;
String? lastName;
// Constructor
Person(this.firstName, this.lastName);
// Getter
String get fullName => "$firstName $lastName";
}
void main() {
Person p = Person("John", "Doe");
print(p.fullName);
}
Show Output
John Doe
Example 2: Getter In Dart
In this example below, there is a class named NoteBook. The class has two
private properties _name and _prize. There are two getters name and prize
to access the value of the properties.
class NoteBook {
// Private properties
String? _name;
double? _prize;
// Constructor
NoteBook(this._name, this._prize);
// Getter method to access private property _name
String get name => this._name!;
// Getter method to access private property _prize
double get prize => this._prize!;
}
void main() {
// Create an object of NoteBook class
NoteBook nb = new NoteBook("Dell", 500);
// Display the values of the object
print(nb.name);
print(nb.prize);
}
Show Output
Name: Dell
Price: 500.0
Note: In the above example, a getter name and prize are used to access the
value of the properties _name and _prize.
In this example below, there is a class named NoteBook. The class has two
private properties _name and _prize. There are two getters name and prize
to access the value of the properties. If you provide a blank name, then it
will return No Name.
class NoteBook {
// Private properties
String _name;
double _prize;
// Constructor
NoteBook(this._name, this._prize);
// Getter to access private property _name
String get name {
if (_name == "") {
return "No Name";
}
return this._name;
}
// Getter to access private property _prize
double get prize {
return this._prize;
}
}
void main() {
// Create an object of NoteBook class
NoteBook nb = new NoteBook("Apple", 1000);
print("First Notebook name: ${nb.name}");
print("First Notebook prize: ${nb.prize}");
NoteBook nb2 = new NoteBook("", 500);
print("Second Notebook name: ${nb2.name}");
print("Second Notebook prize: ${nb2.prize}");
}
Show Output
First Notebook name: Apple
First Notebook prize: 1000.0
Second Notebook name: No Name
Second Notebook prize: 500.0
In this example below, there is a class named Doctor. The class has three
private properties _name, _age and _gender. There are three getters: name,
age, and gender to access the value of the properties. It has a map getter to
get a Map of the object.
class Doctor {
// Private properties
String _name;
int _age;
String _gender;
// Constructor
Doctor(this._name, this._age, this._gender);
// Getters
String get name => _name;
int get age => _age;
String get gender => _gender;
// Map Getter
Map<String, dynamic> get map {
return {"name": _name, "age": _age, "gender": _gender};
}
}
void main() {
// Create an object of Doctor class
Doctor d = Doctor("John", 41, "Male");
print(d.map);
}
Show Output
{name: John, age: 41, gender: Male}
SETTER IN DART
Setter In Dart
Syntax
set property_name (value) {
// Setter body
}
Info
Note: Instead of writing { } after the property name, you can also write =>
(fat arrow) after the property name.
In this example below, there is a class named NoteBook. The class has two
private properties _name and _prize. There are two setters name and prize
to update the value of the properties. There is also a method display to
display the value of the properties.
class NoteBook {
// Private Properties
String? _name;
double? _prize;
// Setter to update private property _name
set name(String name) => this._name = name;
// Setter to update private property _prize
set prize(double prize) => this._prize = prize;
// Method to display the values of the properties
void display() {
print("Name: ${_name}");
print("Price: ${_prize}");
}
}
void main() {
// Create an object of NoteBook class
NoteBook nb = new NoteBook();
// setting values to the object using setter
nb.name = "Dell";
nb.prize = 500.00;
// Display the values of the object
nb.display();
}
Show Output
Name: Dell
Price: 500.0
Note: In the above example, a setter name and prize are used to update the
value of the properties _name and _prize.
In this example, there is a class named NoteBook. The class has two private
properties _name and _prize. If the value of _prize is less than 0, we will
throw an exception. There are also two setters name and prize to update
the value of the properties. The class also has a method display() to display
the values of the properties.
class NoteBook {
// Private properties
String? _name;
double? _prize;
// Setter to update the value of name property
set name(String name) => _name = name;
// Setter to update the value of prize property
set prize(double prize) {
if (prize < 0) {
throw Exception("Price cannot be less than 0");
}
this._prize = prize;
}
// Method to display the values of the properties
void display() {
print("Name: $_name");
print("Price: $_prize");
}
}
void main() {
// Create an object of NoteBook class
NoteBook nb = new NoteBook();
// setting values to the object using setter
nb.name = "Dell";
nb.prize = 250;
// Display the values of the object
nb.display();
}
Output
Name: Dell
Price: 500.0
Note: It is generally best to not allow the user to set the value of a field
directly. Instead, you should provide a setter method that can validate the
value before setting it. This is very important when working on large and
complex programs.
In this example, there is a class named Student. The class has two private
properties _name and _classnumber. We will also create two setters name
and classnumber to update the value of the properties. The classnumber
setter will only accept a value between 1 and 12. The class also has a
method display() to display the values of the properties.
class Student {
// Private properties
String? _name;
int? _classnumber;
// Setter to update the value of name property
set name(String name) => this._name = name;
// Setter to update the value of classnumber property
set classnumber(int classnumber) {
if (classnumber <= 0 || classnumber > 12) {
throw ('Classnumber must be between 1 and 12');
}
this._classnumber = classnumber;
}
// Method to display the values of the properties
void display() {
print("Name: $_name");
print("Class Number: $_classnumber");
}
}
void main() {
// Create an object of Student class
Student s = new Student();
// setting values to the object using setter
s.name = "John Doe";
s.classnumber = 12;
// Display the values of the object
s.display();
// This will generate error
//s.setClassNumber(13);
}
Show Output
Name: John
Class Number: 10
In this section, you will learn about Getter and Setter in dart with the help
of examples.
Getter and Setter provide explicit read and write access to an object
properties. In dart, get and set are the keywords used to create getter and
setter. Getter read the value of property and act as accessor. Setter update
the value of property and act as mutator.
Note: You can use same name for getter and setter. But, you can’t use same
name for getter, setter and property name.
In this example below, there is a class named Student with three private
properties _firstName, _lastName and _age. There are two getters fullName
and age to get the value of the properties. There are also three setters
firstName, lastName and age to update the value of the properties. If age is
less than 0, it will throw an error.
class Student {
// Private Properties
String? _firstName;
String? _lastName;
int? _age;
// Getter to get full name
String get fullName => this._firstName! + " " + this._lastName!;
// Getter to read private property _age
int get age => this._age!;
// Setter to update private property _firstName
set firstName(String firstName) => this._firstName = firstName;
// Setter to update private property _lastName
set lastName(String lastName) => this._lastName = lastName;
// Setter to update private property _age
set age(int age) {
if (age < 0) {
throw new Exception("Age can't be less than 0");
}
this._age = age;
}
}
void main() {
// Create an object of Student class
Student st = new Student();
// setting values to the object using setter
st.firstName = "John";
st.lastName = "Doe";
st.age = 20;
// Display the values of the object
print("Full Name: ${st.fullName}");
print("Age: ${st.age}");
}
Show Output
Full Name: John Doe
Age: 20
In this example below, there is a class named BankAccount with one private
property _balance. There is one getter balance to read the value of the
property. There are methods deposit and withdraw to update the value of
the _balance.
class BankAccount {
// Private Property
double _balance = 0.0;
// Getter to read private property _balance
double get balance => this._balance;
// Method to deposit money
void deposit(double amount) {
this._balance += amount;
}
// Method to withdraw money
void withdraw(double amount) {
if (this._balance >= amount) {
this._balance -= amount;
} else {
throw new Exception("Insufficient Balance");
}
}
}
void main() {
// Create an object of BankAccount class
BankAccount account = new BankAccount();
// Deposit money
account.deposit(1000);
// Display the balance
print("Balance after deposit: ${account.balance}");
// Withdraw money
account.withdraw(500);
// Display the balance
print("Balance after withdraw: ${account.balance}");
}
Output
● Use getter and setter when you want to restrict the access to the
properties.
● Use getter and setter when you want to perform some action before
reading or writing the properties.
● Use getter and setter when you want to validate the data before
reading or writing the properties.
● Don’t use getter and setter when you want to make the properties
read-only or write-only.
INHERITANCE IN DART
Introduction
In this section, you will learn inheritance in Dart programming and how to
define a class that reuses the properties and methods of another class.
Inheritance In Dart
Inheritance is a sharing of behaviour between two classes. It allows you to
define a class that extends the functionality of another class. The extend
keyword is used for inheriting from parent class.
Dart supports single inheritance, which means that a class can only inherit
from a single class. Dart does not support multiple inheritance which
means that a class cannot inherit from multiple classes.
Syntax
class ParentClass {
// Parent class code
}
class ChildClass extends ParentClass {
// Child class code
}
In this syntax, ParentClass is the super class and ChildClass is the sub
class. The ChildClass inherits the properties and methods of the
ParentClass.
Terminology
Parent Class: The class whose properties and methods are inherited by
another class is called parent class. It is also known as base class or super
class.
Child Class: The class that inherits the properties and methods of another
class is called child class. It is also known as derived class or sub class.
In this example, we will create a class Person and then create a class
Student that inherits the properties and methods of the Person class.
class Person {
// Properties
String? name;
int? age;
// Method
void display() {
print("Name: $name");
print("Age: $age");
}
}
// Here In student class, we are extending the
// properties and methods of the Person class
class Student extends Person {
// Fields
String? schoolName;
String? schoolAddress;
// Method
void displaySchoolInfo() {
print("School Name: $schoolName");
print("School Address: $schoolAddress");
}
}
void main() {
// Creating an object of the Student class
var student = Student();
student.name = "John";
student.age = 20;
student.schoolName = "ABC School";
student.schoolAddress = "New York";
student.display();
student.displaySchoolInfo();
}
output
Name: John
Age: 20
School Name: ABC School
School Address: New York
In this example, here is parent class Car and child class Toyota. The Toyota
class inherits the properties and methods of the Car class.
class Car{
String color;
int year;
void start(){
print("Car started");
}
}
class Toyota extends Car{
String model;
int prize;
void showDetails(){
print("Model: $model");
print("Prize: $prize");
}
}
void main(){
var toyota = Toyota();
toyota.color = "Red";
toyota.year = 2020;
toyota.model = "Camry";
toyota.prize = 20000;
toyota.start();
toyota.showDetails();
}
Show Output
Car started
Model: Camry
Prize: 20000
In this example below, there is super class named Car with two properties
name and prize. There is sub class named Tesla which inherits the
properties of the super class. The sub class has a method display to display
the values of the properties.
class Car {
// Properties
String? name;
double? prize;
}
class Tesla extends Car {
// Method to display the values of the properties
void display() {
print("Name: ${name}");
print("Prize: ${prize}");
}
}
void main() {
// Create an object of Tesla class
Tesla t = new Tesla();
// setting values to the object
t.name = "Tesla Model 3";
t.prize = 50000.00;
// Display the values of the object
t.display();
}
Show Output
Name: Tesla Model 3
Prize: 50000.0
In this example below, there is super class named Car with two properties
name and prize. There is sub class named Tesla which inherits the
properties of the super class. The sub class has a method display to display
the values of the properties. There is another sub class named Model3
which inherits the properties of the sub class Tesla. The sub class has a
property color and a method display to display the values of the properties.
class Car {
// Properties
String? name;
double? prize;
}
class Tesla extends Car {
// Method to display the values of the properties
void display() {
print("Name: ${name}");
‘print("Prize: ${prize}");
}
}
class Model3 extends Tesla {
// Properties
String? color;
// Method to display the values of the properties
void display() {
super.display();
print("Color: ${color}");
}
}
void main() {
// Create an object of Model3 class
Model3 m = new Model3();
// setting values to the object
m.name = "Tesla Model 3";
m.prize = 50000.00;
m.color = "Red";
// Display the values of the object
m.display();
}
Show Output
Name: Tesla Model 3
Prize: 50000.0
Color: Red
Note: Here super keyword is used to call the method of the parent class.
class Person {
// Properties
String? name;
int? age;
}
class Doctor extends Person {
// Properties
List<String>? listofdegrees;
String? hospitalname;
// Method to display the values of the properties
void display() {
print("Name: ${name}");
print("Age: ${age}");
print("List of Degrees: ${listofdegrees}");
print("Hospital Name: ${hospitalname}");
}
}
class Specialist extends Doctor {
// Properties
String? specialization;
// Method to display the values of the properties
void display() {
super.display();
print("Specialization: ${specialization}");
}
}
void main() {
// Create an object of Specialist class
Specialist s = new Specialist();
// setting values to the object
s.name = "John";
s.age = 30;
s.listofdegrees = ["MBBS", "MD"];
s.hospitalname = "ABC Hospital";
s.specialization = "Cardiologist";
// Display the values of the object
s.display();
}
Output
Name: John
Age: 30
List of Degrees: [MBBS, MD]
Hospital Name: ABC Hospital
Specialization: Cardiologist
In this example below, there is class named Shape with two properties
diameter1 and diameter2. There is sub class named Rectangle with method
area to calculate the area of the rectangle. There is another subclass
named Triangle with method area to calculate the area of the triangle.
class Shape {
// Properties
double? diameter1;
double? diameter2;
}
class Rectangle extends Shape {
// Method to calculate the area of the rectangle
double area() {
return diameter1! * diameter2!;
}
}
class Triangle extends Shape {
// Method to calculate the area of the triangle
double area() {
return 0.5 * diameter1! * diameter2!;
}
}
void main() {
// Create an object of Rectangle class
Rectangle r = new Rectangle();
// setting values to the object
r.diameter1 = 10.0;
r.diameter2 = 20.0;
// Display the area of the rectangle
print("Area of the rectangle: ${r.area()}");
Key Points
If you copy the code from one class to another class, then you will have to
maintain the code in both the classes. If you make any changes in one
class, then you will have to make the same changes in the other class. This
can lead to errors and bugs in the code.
No, there is a lot more to learn about inheritance. You need to learn about
Constructor Inheritance, Method Overriding, Abstract Class, Interface and
Mixin etc. You will learn about these concepts in the next chapters.
INHERITANCE OF CONSTRUCTOR IN
DART
Introduction
class Laptop {
// Constructor
Laptop() {
print("Laptop constructor");
}
}
class MacBook extends Laptop {
// Constructor
MacBook() {
print("MacBook constructor");
}
}
void main() {
var macbook = MacBook();
}
Show Output
Laptop constructor
MacBook constructor
Note: The constructor of the parent class is called first and then the
constructor of the child class is called.
class Laptop {
// Constructor
Laptop(String name, String color) {
print("Laptop constructor");
print("Name: $name");
print("Color: $color");
}
}
class MacBook extends Laptop {
// Constructor
MacBook(String name, String color) : super(name, color) {
print("MacBook constructor");
}
}
void main() {
var macbook = MacBook("MacBook Pro", "Silver");
}
output
Laptop constructor
Name: MacBook Pro
Color: Silver
MacBook constructor
In this example below, there is class named Person with properties name
and age. There is another class named Student which extends the Person
class. The Student class has additional property rollNumber. Lets see how
to create a constructor for the Student class.
class Person {
String name;
int age;
// Constructor
Person(this.name, this.age);
}
class Student extends Person {
int rollNumber;
// Constructor
Student(String name, int age, this.rollNumber) : super(name, age);
}
void main() {
var student = Student("John", 20, 1);
print("Student name: ${student.name}");
print("Student age: ${student.age}");
print("Student roll number: ${student.rollNumber}");
}
Output
Student name: John
Student age: 20
Student roll number: 1
In this example below, there is class named Laptop with a constructor with
named parameters. There is another class named MacBook which extends
the Laptop class. The MacBook class has its own constructor with named
parameters.
class Laptop {
// Constructor
Laptop({String name, String color}) {
print("Laptop constructor");
print("Name: $name");
print("Color: $color");
}
}
class MacBook extends Laptop {
// Constructor
MacBook({String name, String color}) : super(name: name, color: color)
{
print("MacBook constructor");
}
}
void main() {
var macbook = MacBook(name: "MacBook Pro", color: "Silver");
}
Output
Laptop constructor
Name: MacBook Pro
Color: Silver
MacBook constructor
In this example below, there is class named Laptop with one default
constructor and one named constructor. There is another class named
MacBook which extends the Laptop class. The MacBook class has its own
constructor with named parameters. You can call the named constructor of
the parent class using the super keyword.
class Laptop {
// Default Constructor
Laptop() {
print("Laptop constructor");
}
// Named Constructor
Laptop.named() {
print("Laptop named constructor");
}
}
class MacBook extends Laptop {
// Constructor
MacBook() : super.named() {
print("MacBook constructor");
}
}
void main() {
var macbook = MacBook();
}
Show Output
Laptop named constructor
MacBook constructor
SUPER IN DART
Introduction
In this section, you will learn about Super in Dart programming language
with the help of examples. Before learning about Super in Dart, you should
have a basic understanding of the constructor and inheritance in Dart.
Super is used to refer to the parent class. It is used to call the parent
class’s properties and methods.
In this example below, the show() method of the MacBook class calls the
show() method of the parent class using the super keyword.
class Laptop {
// Method
void show() {
print("Laptop show method");
}
}
class MacBook extends Laptop {
void show() {
super.show(); // Calling the show method of the parent class
print("MacBook show method");
}
}
void main() {
// Creating an object of the MacBook class
MacBook macbook = MacBook();
macbook.show();
}
Show Output
Laptop show method
MacBook show method
In this example below, the display() method of the Tesla class calls the
noOfSeats property of the parent class using the super keyword.
class Car {
int noOfSeats = 4;
}
class Tesla extends Car {
int noOfSeats = 6;
void display() {
print("No of seats in Tesla: $noOfSeats");
print("No of seats in Car: ${super.noOfSeats}");
}
}
void main() {
var tesla = Tesla();
tesla.display();
}
Show Output
No of seats in Tesla: 6
No of seats in Car: 4
In this example below, the Manager class constructor calls the Employee
class constructor using the super keyword.
class Employee {
// Constructor
Employee(String name, double salary) {
print("Employee constructor");
print("Name: $name");
print("Salary: $salary");
}
}
class Manager extends Employee {
// Constructor
Manager(String name, double salary) : super(name, salary) {
print("Manager constructor");
}
}
void main() {
Manager manager = Manager("John", 25000.0);
}
Show Output
Employee constructor
Name: John
Salary: 25000.0
Manager constructor
In this example below, the Manager class named constructor calls the
Employee class named constructor using the super keyword.
class Employee {
// Named constructor
Employee.manager() {
print("Employee named constructor");
}
}
class Manager extends Employee {
// Named constructor
Manager.manager() : super.manager() {
print("Manager named constructor");
}
}
void main() {
Manager manager = Manager.manager();
}
Show Output
Employee named constructor
Manager named constructor
In this example below, the MacBookPro class method display calls the
display method of the parent class MacBook using the super keyword. The
MacBook class method display calls the display method of the parent class
Laptop using the super keyword.
class Laptop {
// Method
void display() {
print("Laptop display");
}
}
class MacBook extends Laptop {
// Method
void display() {
print("MacBook display");
super.display();
}
}
class MacBookPro extends MacBook {
// Method
void display() {
print("MacBookPro display");
super.display();
}
}
void main() {
var macbookpro = MacBookPro();
macbookpro.display();
}
Show Output
MacBookPro display
MacBook display
Laptop display
POLYMORPHISM IN DART
Introduction
Polymorphism In Dart
Poly means many and morph means forms. Polymorphism is the ability of
an object to take on many forms. As humans, we have the ability to take on
many forms. We can be a student, a teacher, a parent, a friend, and so on.
Similarly, in object-oriented programming, polymorphism is the ability of an
object to take on many forms.
Syntax
class ParentClass{
void functionName(){
}
}
class ChildClass extends ParentClass{
@override
void functionName(){
}
}
In this example below, there is a class named Animal with a method named
eat(). The eat() method is overridden in the child class named Dog.
class Animal {
void eat() {
print("Animal is eating");
}
}
class Dog extends Animal {
@override
void eat() {
print("Dog is eating");
}
}
void main() {
Animal animal = Animal();
animal.eat();
Dog dog = Dog();
dog.eat();
}
Animal is eating
Dog is eating
In this example below, there is a class named Vehicle with a method named
run(). The run() method is overridden in the child class named Bus.
class Vehicle {
void run() {
print("Vehicle is running");
}
}
class Bus extends Vehicle {
@override
void run() {
print("Bus is running");
}
}
void main() {
Vehicle vehicle = Vehicle();
vehicle.run();
Bus bus = Bus();
bus.run();
}
Vehicle is running
Bus is running
Note: If you don’t write @override, the program still runs. But, it is a good
practice to write @override.
In this example below, there is a class named Car with a method named
power(). The power() method is overridden in two child classes named
Honda and Tesla.
class Car{
void power(){
print("It runs on petrol.");
}
}
class Honda extends Car{
}
class Tesla extends Car{
@override
void power(){
print("It runs on electricity.");
}
}
void main(){
Honda honda=Honda();
Tesla tesla=Tesla();
honda.power();
tesla.power();
}
Show Output
It runs on petrol.
It runs on electricity.
In this section, you will learn about dart abstract class. Before learning
about abstract class, you should have a basic understanding of class,
object, constructor, and inheritance. Previously you learned how to define a
class. These classes are concrete classes. You can create an object of
concrete classes, but you cannot create an object of abstract classes.
Abstract Class
Syntax
abstract class ClassName {
//Body of abstract class
method1();
method2();
}
Abstract Method
Abstract Method
Syntax
abstract class ClassName {
//Body of abstract class
method1();
method2();
}
Subclasses of an abstract class must implement all the abstract methods of the abstract class. It is
used to achieve abstraction in the Dart programming language.
In this example below, there is an abstract class Vehicle with two abstract methods start() and stop().
The subclasses Car and Bike implement the abstract methods and override them to print the
message.
In this example below, there is an abstract class Shape with one abstract
method area() and two subclasses Rectangle and Triangle. The subclasses
implement the area() method and override it to calculate the area of the
rectangle and triangle, respectively.
// Implementation of area()
@override
void area() {
print('The area of the rectangle is ${dim1 * dim2}');
}
}
// Implementation of area()
@override
void area() {
print('The area of the triangle is ${0.5 * dim1 * dim2}');
}
}
void main() {
Rectangle rectangle = Rectangle(10, 20);
rectangle.area();
You can’t create an object of an abstract class. However, you can define a
constructor in an abstract class. The constructor of an abstract class is
called when an object of a subclass is created.
Output
The rate of interest of SBI is 8.4
The rate of interest of ICICI is 7.3
Bank Name: ICICI