OOP in Dart 2
OOP in Dart 2
Advantages
Features Of OOP
1. Class
2. Object
3. Encapsulation
4. Inheritance
5. Polymorphism
6. Abstraction
Info
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
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.");
}
}
Info
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!;
}
}
Example 4: Declaring A Student Class In Dart
class Student {
String? name;
int? age;
int? grade;
void displayInfo() {
print("Student name: $name.");
print("Student age: $age.");
print("Student grade: $grade.");
}
}
Key Points
Challenge
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.
Info
Note: In the next section, you will learn how to create an object from a class.
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 changeGear(int newValue) {
currentSpeed = newValue;
}
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();
}
Show Output
Run Online
Info
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();
}
Show Output
Run Online
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
The main method is the program’s entry point, so it is always needed
to see the result.
The new keyword can be used to create a new object, but it is
unnecessary.
Challenge
A class is a blueprint for creating objects. A class defines the properties and
methods that an object will have. If you want to learn more about class in
Dart, you can read class in dart.
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();
}
Show Output
Run Online
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();
Note: Here ! is used to tell the compiler that the variable is not null. If you
don’t use !, then you will get an error. You will learn more about it in null
safety later.
class SimpleInterest{
//properties of simple interest
double? principal;
double? rate;
double? time;
Challenge
Constructor In Dart
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.
Syntax
class ClassName {
// Constructor declaration: Same as class name
ClassName() {
// body of the constructor
}
}
Info
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}");
}
Show Output
Run Online
Info
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();
Info
Note: You can create many objects of a class. Each object will have its own
copy of the properties.
class Car {
String? name;
double? prize;
// 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();
}
Show Output
Run Online
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();
}
Show Output
Run Online
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();
}
Show Output
Run Online
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();
}
Show Output
Run Online
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();
}
Show Output
Run Online
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();
}
Show Output
Run Online
Key Points
Challenge
Create a class Patient with three properties name, age, and disease. The
class has one constructor. The constructor is used to initialize the values of
the three properties. Also, create an object of the
class Patient called patient. Print the values of the three properties using
the object.
DEFAULT CONSTRUCTOR IN DART
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();
}
Show Output
Run Online
Info
class Student {
String? name;
int? age;
String? schoolname;
String? grade;
// Default Constructor
Student() {
print(
"Constructor called"); // this is for checking the
constructor is called or not.
schoolname = "ABC School";
}
}
void main() {
// Here student is object of class Student.
Student student = Student();
student.name = "John";
student.age = 10;
student.grade = "A";
print("Name: ${student.name}");
print("Age: ${student.age}");
print("School Name: ${student.schoolname}");
print("Grade: ${student.grade}");
}
Show Output
Run Online
Challenge
Try to create a class Person with two properties: name, and planet. Create
a default constructor to initialize the values of the planet to earth. Create an
object of the class Person, set the name to “Your Name” and print the name
and planet.
class ClassName {
// Instance Variables
int? number;
String? name;
// Parameterized Constructor
ClassName(this.number, this.name);
}
Example 1: Parameterized Constructor In Dart
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
Run Online
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}");
}
Show Output
Run Online
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
Run Online
Info
Note: In parameterized constructor, at the time of object creation, you must
pass the parameters through the constructor which initialize the variables
value, avoiding the null values.
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 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.
Info
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
Run Online
class Mobile {
String? name;
String? color;
int? prize;
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
Run Online
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
Run Online
import 'dart:convert';
class Person {
String? name;
int? age;
Person(this.name, this.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": "Bishworaj", "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
Run Online
Info
class Point {
final int x;
final int 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}");
Info
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.
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 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
Run Online
Example 3: Constant Constructor With Named Parameters In Dart
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
Run Online
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
Info
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.
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;
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");
Private Properties
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;
void main() {
var employee = Employee();
employee.setName("Jack");
print(employee.getName());
}
Show Output
Run Online
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;
void main() {
var employee = Employee();
employee._name = "John"; // It is working, but why?
print(employee.getName());
}
Show Output
Run Online
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.
Info
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
Run Online
Info
Note: You can also define getter and setter using get and set keywords.
For more see this example below.
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
Run Online
Info
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.
Getter In Dart
Syntax
return_type get property_name {
// Getter 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 Person. The class has two
properties firstName and lastName. There is getter fullName which is
responsible to get full name of 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
Run Online
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!;
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
Run Online
Info
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);
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
Run Online
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 map getter to get 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
Run Online
Setter In Dart
Syntax
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;
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
Run Online
Info
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;
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;
Info
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;
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.
Info
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;
class BankAccount {
// Private Property
double _balance = 0.0;
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}");
}
Show Output
Run Online
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
Info
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
}
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.
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();
}
Show Output
Run Online
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");
}
}
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
Run Online
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;
}
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
Run Online
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;
}
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
Run Online
Info
Note: Here super keyword is used to call the method of the parent class.
class Person {
// Properties
String? name;
int? age;
}
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();
}
Show Output
Run Online
class Shape {
// Properties
double? diameter1;
double? 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
Dart does not support multiple inheritance because it can lead to ambiguity.
For example, if class Apple inherits class Fruit and class Vegetable, then
there may be two methods with the same name eat. If the method is called,
then which method should be called? This is the reason why Dart does not
support multiple inheritance.
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.
class Laptop {
// Constructor
Laptop() {
print("Laptop constructor");
}
}
class MacBook extends Laptop {
// Constructor
MacBook() {
print("MacBook constructor");
}
}
void main() {
var macbook = MacBook();
}
Show Output
Run Online
Info
Note: The constructor of the parent class is called first and then the
constructor of the child class is called.
In this example below, there is class named Laptop with a constructor with
parameters. There is another class named MacBook which extends
the Laptop class. The MacBook class has its own constructor with
parameters.
class Laptop {
// Constructor
Laptop(String name, String color) {
print("Laptop constructor");
print("Name: $name");
print("Color: $color");
}
}
void main() {
var macbook = MacBook("MacBook Pro", "Silver");
}
Show Output
Run Online
Example 3: Inheritance Of Constructor
class Person {
String name;
int age;
// Constructor
Person(this.name, this.age);
}
// 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}");
}
Show Output
Run Online
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");
}
}
void main() {
var macbook = MacBook(name: "MacBook Pro", color: "Silver");
}
Show Output
Run Online
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");
}
}
void main() {
var macbook = MacBook();
}
Show Output
Run Online
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");
}
}
void main() {
// Creating an object of the MacBook class
MacBook macbook = MacBook();
macbook.show();
}
Show Output
Run Online
Example 2: Accessing Super Properties In Dart
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;
}
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
Run Online
class Employee {
// Constructor
Employee(String name, double salary) {
print("Employee constructor");
print("Name: $name");
print("Salary: $salary");
}
}
void main() {
Manager manager = Manager("John", 25000.0);
}
Show Output
Run Online
class Employee {
// Named constructor
Employee.manager() {
print("Employee named constructor");
}
}
void main() {
Manager manager = Manager.manager();
}
Show Output
Run Online
class Laptop {
// Method
void display() {
print("Laptop display");
}
}
void main() {
var macbookpro = MacBookPro();
macbookpro.display();
}
Show Output
Run Online
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.
Info
Note: In the real world, polymorphism is updating or modifying the feature,
function, or implementation that already exists in the parent class.
Syntax
class ParentClass{
void functionName(){
}
}
class ChildClass extends ParentClass{
@override
void functionName(){
}
}
Example 1: Polymorphism By Method Overriding In Dart
class Animal {
void eat() {
print("Animal is eating");
}
}
void main() {
Animal animal = Animal();
animal.eat();
class Vehicle {
void run() {
print("Vehicle is running");
}
}
void main() {
Vehicle vehicle = Vehicle();
vehicle.run();
Info
Note: If you don’t write @override, the program still runs. But, it is a good
practice to write @override.
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
Run Online
class Employee{
void salary(){
print("Employee salary is \$1000.");
}
}
void main(){
Manager manager=Manager();
Developer developer=Developer();
manager.salary();
developer.salary();
}
Show Output
Run Online
STATIC IN DART
Introduction
In this section, you will learn about dart static to share the same variable or
method across all instances of a class.
Static In Dart
To declare a static variable in Dart, you must use the static keyword before
the variable name.
class ClassName {
static dataType variableName;
}
How To Initialize A Static Variable In Dart
class ClassName {
static dataType variableName = value;
// Accessing the static variable inside same class
void display() {
print(variableName);
}
}
void main() {
// Accessing static variable outside the class
dataType value =ClassName.variableName;
}
Example 1: Static Variable In Dart
In this example below, there is a class named Employee. The class has a
static variable count to count the number of employees.
class Employee {
// Static variable
static int count = 0;
// Constructor
Employee() {
count++;
}
// Method to display the value of count
void totalEmployee() {
print("Total Employee: $count");
}
}
void main() {
// Creating objects of Employee class
Employee e1 = new Employee();
e1.totalEmployee();
Employee e2 = new Employee();
e2.totalEmployee();
Employee e3 = new Employee();
e3.totalEmployee();
}
Show Output
Run Online
Info
Note: While creating the objects of the class, the static variable count is
incremented by 1. The totalEmployee() method displays the value of the
static variable count.
In this example below, there is a class named Student. The class has a
static variable schoolName to store the name of the school. If every student
belongs to the same school, then it is better to use a static variable.
class Student {
int id;
String name;
static String schoolName = "ABC School";
Student(this.id, this.name);
void display() {
print("Id: ${this.id}");
print("Name: ${this.name}");
print("School Name: ${Student.schoolName}");
}
}
void main() {
Student s1 = new Student(1, "John");
s1.display();
Student s2 = new Student(2, "Smith");
s2.display();
}
Show Output
Run Online
Syntax
class ClassName{
static returnType methodName(){
//statements
}
}
Example 3: Static Method In Dart
class SimpleInterest {
static double calculateInterest(double principal, double rate,
double time) {
return (principal * rate * time) / 100;
}
}
void main() {
print(
"The simple interest is $
{SimpleInterest.calculateInterest(1000, 2, 2)}");
}
Show Output
Run Online
import 'dart:math';
class PasswordGenerator {
static String generateRandomPassword() {
List<String> allalphabets =
'abcdefghijklmnopqrstuvwxyz'.split('');
List<int> numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
List<String> specialCharacters = ["@", "#", "%", "&", "*"];
List<String> password = [];
for (int i = 0; i < 5; i++) {
password.add(allalphabets[Random().nextInt(allalphabets.length)]);
password.add(numbers[Random().nextInt(numbers.length)].toString());
password
.add(specialCharacters[Random().nextInt(specialCharacters
.length)]);
}
return password.join();
}
}
void main() {
print(PasswordGenerator.generateRandomPassword());
}
Show Output
Run Online
Info
Note: You don’t need to create an instance of a class to call a static method.
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
Abstract classes are classes that cannot be initialized. It is used to define the
behavior of a class that can be inherited by other classes. An abstract class
is declared using the keyword abstract.
Syntax
Syntax
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.
// Implementation of stop()
@override
void stop() {
print('Car stopped');
}
}
// Implementation of stop()
@override
void stop() {
print('Bike stopped');
}
}
void main() {
Car car = Car();
car.start();
car.stop();
Info
Note: The abstract class is used to define the behavior of a class that can be
inherited by other classes. You can define an abstract method inside an
abstract class.
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.
// Constructor
Bank(this.name, this.rate);
// Abstract method
void interest();
// Implementation of interest()
@override
void interest() {
print('The rate of interest of SBI is $rate');
}
}
// Implementation of interest()
@override
void interest() {
print('The rate of interest of ICICI is $rate');
}
}
void main() {
SBI sbi = SBI('SBI', 8.4);
ICICI icici = ICICI('ICICI', 7.3);
sbi.interest();
icici.interest();
icici.display();
}
Show Output
Run Online
INTERFACE IN DART
Introduction
In this section, you will learn the dart interface and how to implement an
interface with the help of examples. In Dart, every class is implicit
interface. Before learning about the interface in dart, you should have a
basic understanding of the class and objects, inheritance and abstract
class in Dart.
Interface In Dart
class InterfaceName {
// code
}
In dart there is no keyword interface but you can use class or abstract
class to declare an interface. All classes implicitly define an interface.
Mostly abstract class is used to declare an interface.
You must use the implements keyword to implement an interface. The class
that implements an interface must implement all the methods and properties
of the interface.
// implementation of canRun()
@override
canRun() {
print('Student can run');
}
}
Example 1: Interface In Dart
void main() {
var macBook = MacBook();
macBook.turnOn();
macBook.turnOff();
}
Show Output
Run Online
Info
Note: Most of the time, abstract class is used instead of concrete class to
declare an interface.
@override
void stop() {
print('Car stopped');
}
}
void main() {
var car = Car();
car.start();
car.stop();
}
Show Output
Run Online
Multiple inheritance means a class can inherit from more than one class.
In dart, you can’t inherit from more than one class. But you can implement
multiple interfaces in a class.
In this example below, two abstract classes are named Area and Perimeter.
The Area class has an abstract method area() and the Perimeter class has
an abstract method perimeter(). The Shape class implements both
the Area and Perimeter classes. The Shape class has to implement
the area() and perimeter() methods.
// constructor
Rectangle(this.length, this.breadth);
// implementation of area()
@override
void area() {
print('The area of the rectangle is ${length * breadth}');
}
// implementation of perimeter()
@override
void perimeter() {
print('The perimeter of the rectangle is ${2 * (length +
breadth)}');
}
}
void main() {
Rectangle rectangle = Rectangle(10, 20);
rectangle.area();
rectangle.perimeter();
}
Show Output
Run Online
// implementation of run()
@override
void run() {
print('Student is running');
}
// implementation of walk()
@override
void walk() {
print('Student is walking');
}
}
void main() {
var student = Student();
student.name = 'John';
print(student.name);
student.run();
student.walk();
}
Show Output
Run Online
extends implements
It is optional to override the methods. Concrete class must override the meth
Constructors of the superclass is called before the sub- Constructors of the superclass is not c
class constructor. class constructor.
The super keyword is used to access the members of the Interface members can’t be accessed
superclass. keyword.
Sub-class need not to override the fields of the superclass. Subclass must override the fields of th
MIXIN IN DART
Introduction
In this section, you will learn about dart mixins to reuse the code in multiple
classes. Before learning about mixins you should have a basic understanding
of class, object, constructor, and inheritance.
Mixin In Dart
Mixins are a way of reusing the code in multiple classes. Mixins are declared
using the keyword mixin followed by the mixin name. Three keywords are
used while working with mixins: mixin, with, and on. It is possible to use
multiple mixins in a class.
Info
Note: The with keyword is used to apply the mixin to the class. It promotes
DRY(Don’t Repeat Yourself) principle.
Syntax
mixin Mixin1{
// code
}
mixin Mixin2{
// code
}
mixin ElectricVariant {
void electricVariant() {
print('This is an electric variant');
}
}
mixin PetrolVariant {
void petrolVariant() {
print('This is a petrol variant');
}
}
// with is used to apply the mixin to the class
class Car with ElectricVariant, PetrolVariant {
// here we have access of electricVariant() and petrolVariant()
methods
}
void main() {
var car = Car();
car.electricVariant();
car.petrolVariant();
}
Show Output
Run Online
In this example below, there are two mixins named CanFly and CanWalk.
The CanFly mixin has a method fly() and the CanWalk mixin has a
method walk(). The Bird class uses both the CanFly and CanWalk mixins.
The Human class uses the CanWalk mixin.
mixin CanFly {
void fly() {
print('I can fly');
}
}
mixin CanWalk {
void walk() {
print('I can walk');
}
}
void main() {
var bird = Bird();
bird.fly();
bird.walk();
On Keyword
Sometimes, you want to use a mixin only with a specific class. In this case,
you can use the on keyword.
Syntax Of On Keyword
// constructor
Animal(this.name, this.speed);
// abstract method
void run();
}
void main() {
var dog = Dog('My Dog', 25);
dog.run();
}
// Not Possible
// class Bird with Animal { }
Show Output
Run Online