Category: 5. Object-Oriented

https://cdn3d.iconscout.com/3d/premium/thumb/spiral-object-10293243-8431858.png?f=webp

  • Interfaces

    An interface defines the syntax that any entity must adhere to. Dart does not have any separate syntax to define interfaces. An Interface defines the same as the class where any set of methods can be accessed by an object. The Class declaration can interface itself.

    The keyword implement is needed to be writing, followed by class name to be able to use the interface. Implementing class must provide a complete definition of all the functions of the implemented interface. We can say that a class must define every function with the body in the interface that we want to achieve.

    Declaring an Interface

    Dart doesn’t provide syntax for declaring interface directly. Implicitly, a class declaration itself an interface containing the entire instance member of the class and of any interfaces it implements.

    Implementing an Interface

    To work with interface methods, the interface must be implemented by another class using the implements keyword. A class which is implemented the interface must provide a full implementation of all the methods that belongs to the interface. Following is the syntax of the implementing interface.

    Syntax:

    class ClassName implements InterfaceName  

    In the following example, we are declaring a class Employee. Implicit, the Engineer class implements the interface declaration for the Employee class. Let’s understand the above example by the following code snippet.

    Example –

    class Employee  
    
    {  
    
       void display() {  
    
             print("I am working as an engineer");  
    
                                }  
    
    }  
    
    // Defining interface by implanting another class  
    
    class Engineer implements Employee   
    
    {  
    
              void display() {  
    
                     print("I am an engineer in this company");                   
    
    }  
    
    }  
    
    void main()   
    
    {  
    
    Engineer eng = new Engineer();  
    
    eng.display();  
    
    } 

      Output:

      I am working as engineer
      

      Explanation

      In the above example, we defined a class Engineer as an interface implementing the Engineer class. Then, we defined the same method display() in both classes. This method override in class Engineer, so we created the object of the Engineer class in a main() function invoked the display() function. It printed the output to the screen.

      Implementing Multiple Inheritance

      We have discussed previously that the multiple inheritance is not supported by the Dart, but we can apply the multiple interfaces. We can say that, using multiple interfaces, we can achieve multiple inheritance in Dart. The syntax is given below.

      Syntax:

      class ClassName implements interface1, interface2,…interface n  

      Let’s understand the following example.

      Example –

      class Student  
      
      {  
      
         String name;  
      
         int age;  
      
           
      
         void displayName() {  
      
               print("I am ${name}");  
      
                                  }  
      
         void displayAge() {  
      
                  print("My age is ${age}");  
      
                                     }  
      
      }  
      
        
      
      class Faculty  
      
      {  
      
         String dep_name;  
      
         int salary;  
      
           
      
         void displayDepartment() {  
      
               print("I am a professor of ${dep_name}");  
      
                                  }  
      
         void displaySalary() {  
      
                  print("My salary is ${salary}");  
      
                                     }  
      
      }  
      
      // Defining interface by implenting another class  
      
      class College implements Student,Faculty  
      
      {    
      
         // Overriding the Student class members  
      
         String name;  
      
         int age;  
      
           
      
         void displayName() {  
      
               print("I am ${name}");  
      
                                  }  
      
         void displayAge() {  
      
                  print("My age is ${age}");  
      
                                     }  
      
        
      
      //Overriding each data member of Faculty class  
      
         String dep_name;  
      
         int salary;  
      
           
      
         void displayDepartment() {  
      
               print("I am a proffesor of ${dep_name}");  
      
                                  }  
      
         void displaySalary() {  
      
                  print("My salary is ${salary}");  
      
        
      
      }  
      
      }  
      
      void main()   
      
      {  
      
      College cg = new College();  
      
      cg.name = "Handscomb";  
      
      cg.age = 25;  
      
      cg.dep_name = "Data Structure";  
      
      cg.salary = 50000;  
      
        
      
      cg.displayName();  
      
      cg.displayAge();  
      
      cg.displayDepartment();  
      
      cg.displaySalary();  
      
      }

        Output:

        I am Handscomb
        My age is 25
        I am a professor of Data Structure
        My salary is 50000
        

        Explanation:

        In the above example, we implemented multiple interfaces in class College. Each data member of Student and Faculty class is overriding in class College. We created the object of College class and invoked the overriding functions. It printed the result.

        Rules for Implementing Interfaces

        1. A class that implements the interface must override every method and instance variable of an interface.
        2. Dart doesn’t provide syntax to declare the interface directly. The class declaration can consider as the interface itself.
        3. An interface class must provide the full implementation of all the methods belong to the interfaces.
        4. We can implement one or more interfaces simultaneously.
        5. Using the interface, we can achieve multiple inheritance.
      1. Abstract Classes

        Abstract classes are the classes in Dart that has one or more abstract method. Abstraction is a part of the data encapsulation where the actual internal working of the function hides from the users. They interact only with external functionality. We can declare the abstract class by using the abstract keyword. There is a possibility that an abstract class may or may not have abstract methods.

        Abstract methods are those methods, which are declared without implementation. The concrete methods or normal methods are declared with implementation. An abstract class can contain both types of methods, but a normal class is not allowed to have abstract methods.

        We cannot create the instance of an abstract class that means it can’t be instantiated. It can only be extended by the subclass, and the subclass must be provided the implantation to the abstract methods which are present in the present class. Then it is necessary to declare abstract subclass.

        Rules for Abstract classes:

        The rules of the abstract are given below.

        1. An abstract class can have an abstract method (method without implementation), or not.
        2. If there is at least one abstract method, then the class must be declared abstract.
        3. The object of the abstract class cannot be created, but it can be extended.
        4. An abstract keyword is used to declare the abstract class.
        5. An abstract class can also include normal or concrete (method with the body) methods.
        6. All abstract methods of parent class must be implemented in the subclass.

        Declaring Abstract Class

        An abstract keyword followed by a class name is used to declare the abstract class. An abstract class mostly used to offer a base for the subclass to extends and implement the abstract method.

        Syntax:

        abstract class ClassName {  
        
         // Body of abstract class  
        
        } 

          Usage of Abstract class

          Let’s suppose we have a class Person that has method displayInfo(), and we have to sub classes of it Boy and Girl. Each of the person information varies from the other person, so there is no benefit to implementing the displayInfo() in the parent class. Because every subclass must override the parent class method by provides its own implementation. Thus, we can force the subclass to provide implementation to that method, so that is the benefit to make method abstract. We don’t require the give implementation in the parent class.

          Dart Abstract Classes

          Let’s understand the above scenario through the following code.

          Example –

          abstract class Person {  
          
          //declaring abstract method  
          
            
          
          void displayInfo();  //abstract method   
          
            
          
          }  
          
          class Boy extends Person   
          
          {  
          
          // Overriding method  
          
          void displayInfo() {  
          
              print("My name is Johnathon");  
          
            
          
                 }  
          
            
          
          }  
          
            
          
          class Girl extends Person   
          
          {  
          
          // Overriding method  
          
          void displayInfo() {  
          
              print("My name is Grecia");  
          
            
          
                 }  
          
            
          
          }  
          
            
          
          void main() {  
          
          Boy b = new Boy();  // Creating Object of Boy class  
          
          Girl g = new Girl();  // Creating Object of Girl class  
          
            
          
          b.displayInfo();  
          
          g.displayInfo();  
          
          }  

            Output

            My name is Johnathon
            My name is Grecia
            

            Explanation:

            As we can see that in the above code, we implemented the abstract method in two subclasses according to its requirement and then we called the displayInfo() method using the object of the both class’s object.

          1. Getters and Setters

            Getters and setters are the special class method that is used to read and write access to an object’s properties. The getter method is used to reads the value of the variable or retrieve the value and setter method is used to set or initialize respective class fields. By default, all classes are associated with getter and setter method. However, we can override the default methods by defining getter and setter method explicitly.

            Defining a getter

            We can define the getters method by using the get keyword with no parameter a valid return type.

            Syntax:

            return_type get field_name{  
            
            } 

              Defining a setter

              We can declare the setter method using the set keyword with one parameter and without return type.

              Syntax:

              set field_name {  
              
              } 

                Example:

                class Student {  
                
                          String stdName;  
                
                          String branch;  
                
                          int stdAge;  
                
                 // getter method   
                
                         String get std_name   
                
                             {  
                
                             return stdName;  
                
                             }  
                
                         void set std_name(String name)  
                
                                 {  
                
                              this.stdName = name;  
                
                  
                
                               }  
                
                          void set std_age(int age) {  
                
                               if(age> = 20){  
                
                                   print("Student age should be greater than 20")  
                
                                     }else{   
                
                                         this.stdAge = age;  
                
                                              }  
                
                                      }  
                
                  
                
                                                                         }  
                
                           int get std_age{  
                
                                 return stdAge;  
                
                  
                
                }  
                
                        void set std_branch(String branch_name) {  
                
                                 this.branch = branch_name;  
                
                  
                
                }  
                
                     int get std_branch{  
                
                            return branch;  
                
                }  
                
                  
                
                }  
                
                void main(){  
                
                Student std = new Student();  
                
                std.std_name = 'John';  
                
                std.std_age = 24;  
                
                std.std_branch = 'Computer Science';  
                
                  
                
                print("Student name is: ${std_name}");  
                
                print("Student age is: ${std_age}");  
                
                print("Student branch is: ${std_branch}");  
                
                }  

                  Output

                  Student name is: John
                  Student age is: 24
                  Student Branch is: Computer Science
                  

                  We can also place the getter and setter method just after the. Now, let’s understand the following example:

                  Example – 2

                  class Car {  
                  
                    String makedate;  
                  
                    String modelname;  
                  
                    int manufactureYear;  
                  
                    int carAge;  
                  
                    String color;  
                  
                  // Getter method  
                  
                    int get age {  
                  
                      return carAge;  
                  
                    }  
                  
                  // Setter Method  
                  
                    void set age(int currentYear) {  
                  
                      carAge = currentYear - manufactureYear;  
                  
                    }  
                  
                  // defining parameterized constructor  
                  
                    Car({this.makedate,this.modelname,this.manufactureYear,this.color,});  
                  
                  }  
                  
                  //Age here is both a getter and a setter. Let's see how we can use it.  
                  
                  void main() {  
                  
                   Car c =   
                  
                   Car(makedate:"Renault 20/03/2010",modelname:"Duster",manufactureYear:2010,color:"White");  
                  
                    print("The car company is: ${c.makedate}");   
                  
                    print("The modelname is: ${c.modelname}");   
                  
                    print("The color is:${c.color}");  
                  
                    c.age = 2020;  
                  
                    print(c.age);  
                  
                  } 

                    Output

                    The car company is: Honda 20/03/2010
                    The modelname is: City
                    The color is: White
                    10
                    

                    Explanation:

                    In the above code, we defined the getter and setter methods before the constructor.

                  1. Method Overriding

                    What is Polymorphism?

                    The polymorphism is a combination of the two Greek words poly, which means many and morph means morphing into different forms or shapes. Together, polymorphism means the same entity can be used in various forms. In the programming aspect, the same method can be used in different classes. This technique makes programming more intuitive and more accessible.

                    For example – We have Shape class to define the shape of the object. The shape can be the circle, rectangle, square, straight line, etc. So here the goal is common, but the approach is different.

                    The method overriding is a technique to achieve polymorphism. Sometimes, we want a subclass object to give different results for the same method when subclass object invokes it. This can be done by defining the same method again in subclass. The method has the same name, same arguments, and the same return type. When that method is called, the subclass’s method is executed instead of the method defined in the superclass.

                    Method Overriding

                    When we declare the same method in the subclass, which is previously defined in the superclass is known as the method overriding. The subclass can define the same method by providing its own implementation, which is already exists in the superclass. The method in the superclass is called method overridden, and method in the subclass is called method overriding. Let’s understand the method overriding in the following example.

                    Method Overriding Example

                    We define two classes; first, is a subclass called Human, and the second is a superclass Boy. The Boy subclass inherits the Human superclass. The same method void showInfo() in both classes is defined with the different implementation. The subclass has its own definition of the void showInfo(). Let’s have a look at the following code snippet.

                    Example –

                    class Human{  
                    
                       //Overridden method  
                    
                        void run()  
                    
                       {  
                    
                          print("Human is running");  
                    
                       }  
                    
                    }  
                    
                    class Man extends Human{  
                    
                       //Overriding method  
                    
                        void run(){  
                    
                          print("Boy is running");  
                    
                       }  
                    
                    }  
                    
                    void main(){  
                    
                          Man m = new Man();  
                    
                          //This will call the child class version of run()  
                    
                          m.run();  
                    
                    }  

                      Output:

                      Boy is running
                      

                      Explanation:

                      In the above example, we defined a method with the same name in both, subclass and superclass. The purpose of method overriding is to give the own implementation of subclass method. When we created the object of the Boy subclass, it executed the subclass method and printed the Man is running instead of Human is running.

                      If we create the object of a parent class, then it will be always invoked the parent class method.

                      Let’s take another example where we create two Classes called College and Student with common method void student_details(). Let’s have a look at the following code snippet.

                      Example – 2

                      class College{  
                      
                       // Declaring variables  
                      
                                 String name;  
                      
                                 int rollno;  
                      
                        
                      
                      // Overriden Method  
                      
                      void stu_details(name,rollno){  
                      
                               this.name = name;  
                      
                               this.rollno = rollno;  
                      
                                 
                      
                        
                      
                      }  
                      
                        
                      
                      void display(){  
                      
                               print("The student name:${name}");  
                      
                               print("The student rollno: ${rollno}");  
                      
                               print("The result is passed");  
                      
                        
                      
                            }  
                      
                        
                      
                       }  
                      
                        
                      
                      class Student extends College{  
                      
                      // Overriding Method  
                      
                      void stu_details(name,rollno){  
                      
                               this.name = name;  
                      
                               this.rollno = rollno;  
                      
                        
                      
                      }  
                      
                        
                      
                      void show(){  
                      
                               print("The student name:${name}");  
                      
                               print("The student rollno: ${rollno}");  
                      
                        
                      
                               print("The result is failed");  
                      
                        
                      
                      }  
                      
                      }  
                      
                        
                      
                      void main(){  
                      
                      //Creating object of subclass  
                      
                      Student  st = new Student();  
                      
                      st.stu_details("Joseph",101);  
                      
                      st.show();  
                      
                        
                      
                      // Creating object of superclass  
                      
                      College cg = new College();  
                      
                      cg.stu_details("Jason",102);  
                      
                      cg.display();  
                      
                      }  

                        Output:

                        The student name: Joseph
                        The student rollno: 101
                        The result is failed
                        The student name:Peter
                        The student rollno: 102
                        The result is passed
                        

                        Explanation:

                        In the above example, we create two classes – College as a parent class and Student as a child class. The method stu_details defined in both classes with the same parameters and same return types.

                        Now, the College superclass is inherited by the Student subclass and the stu_details() method is overridden in the subclass.

                        We created the object of Student and to invoked the stu_details() with suitable arguments. It executed the subclass method, and then it printed the result.

                        Same as we created the object of College superclass object invoked its methods and printed the different results.

                        Method Overriding using super Keyword

                        We can invoke the parent class method without creating its object. It can be done by using the super keyword in the subclass. The parent class data member can be accessed in the subclass by using the super keyword. Let’s understand the following example.

                        Example –

                        class Human{  
                        
                           //Overridden method  
                        
                            void run()  
                        
                           {  
                        
                              print("Human is running");  
                        
                           }  
                        
                        }  
                        
                        class Man extends Human{  
                        
                           //Overriding method  
                        
                            void run(){   
                        
                               // Accessing Parent class run() method in child class  
                        
                               super.run();  
                        
                              print("Boy is running");  
                        
                           }  
                        
                        }  
                        
                        void main(){  
                        
                              Man m = new Man();  
                        
                              //This will call the child class version of eat()  
                        
                              m.run();  
                        
                        } 

                          Output:

                          Human is running
                          Boy is running
                          

                          Explanation:

                          In the above program, we accessed the Human class method in child class using the super keyword. Now, we don’t need to instantiate the parent class. We only created the object of subclass, which invoked the run() method of child class and parent class.

                          Note – When we created the child class object and invoked the method, it executes the parent class (if accessed by super keyword) method first, then the child class method.

                          Advantage of method overriding

                          The main benefit of the method overriding is that the subclass can provide its own implementation to the same method as per requirement without making any changes in the superclass method. This technique is much when we want to subclass method to behave differently also with the same name.

                          Rules of Method overriding in Dart

                          The few rules of method overriding are given below. These points must be kept in mind while declaring the same method in subclass.

                          1. The overriding method (the child class method) must be declared with the same configuration as the overridden method (the superclass method). The return type, list of arguments and its sequence must be the same as the parent class method.
                          2. The overriding method must be defined in the subclass, not in the same class.
                          3. The static and final method cannot be inherited in the subclass as they are accessible in their own class
                          4. The constructor of the superclass cannot be inherited in a subclass.
                          5. A method that cannot be inherited, then it cannot be overridden.
                        1. Methods

                          A Dart method is the collection of statements that consists of some characteristics to class object. It provides the facility to perform some operation and it can be invoked by using its name when we need in the program. Methods divide the large task into small chunks and perform the specific operation of that program. This process increases the code reusability and enhances the modular approach of program. The methods can be defined with parameters that are passed as information to complete the specific task, after that it can return value to where it called or return nothing. Methods that define in the class either instance method or class methods.

                          Instance Methods

                          A method that can be accessed by using the instance of class is called instance methods. The instance methods can be no arguments or with arguments. The instance method can access by instance variable this keyword.

                          Creating Instance Methods

                          An instance method is defined by a name and valid return type. It may have list of parameters. The syntax is given below.

                          Syntax:

                          return_type method_name(<list of arguments>)   
                          
                          {  
                          
                          //statement(s)  
                          
                          } 

                            Calling instance Method

                            Instance methods can be accessed by using the class object, thus we required to create object to use it. The syntax is given below.

                            Syntax:

                            ClassName objName = new ClassName()  
                            
                            objName.methodName() 

                              Class Methods

                              The class method is declared with the static keyword. It can be accessed by using the class name instead of the class object. These methods are common to all instances of that individual class. The static methods only can access the static variables.

                              Creating Class Methods

                              A static method is declared by using static keyword followed by method name with return type. The syntax is given below.

                              Syntax:

                              static return_type method_name(){  
                              
                                //statement(s)  
                              
                              } 

                                Calling Class Method

                                The class method can be called directly by using the class name instead of class object. The syntax is given below.

                                Syntax:

                                ClassName.classMethod()  
                              1. Super Constructor

                                The child class can inherit all properties (methods, variables) and behavior of parent expect parent class constructor.& The superclass constructor can be invoke in sub class by using the super() constructor. We can access both non-parameterized and parameterized constructor of superclass. Accessing the constructor of superclass is slightly different in the Dart. The syntax is given below.

                                Syntax:

                                SubClassConstructor():super() {  
                                
                                } 

                                  Implicit super

                                  As we know that the constructor is automatically called when we instantiate a class. When we create the object of sub class, it invokes the constructor of sub class which implicitly invokes the parent class’s default(non-parameterized) constructor. We can use super() constructor in our subclass to invoke superclass constructor. Let’s understand the following example.

                                  Example –

                                  // Parent class  
                                  
                                  class Superclass {  
                                  
                                            Superclass(){  
                                  
                                                 print("This is a superclass constructor");  
                                  
                                    
                                  
                                                  }  
                                  
                                  }  
                                  
                                  class Subclass extends Superclass  
                                  
                                  {  
                                  
                                            Subclass(){  
                                  
                                                  print("This is a subclass constructor");  
                                  
                                             }  
                                  
                                             display(){  
                                  
                                                 print("Welcome to javatpoint");  
                                  
                                  }  
                                  
                                  }  
                                  
                                  void main(){  
                                  
                                            print("Dart Implicit Superclass constructor call");  
                                  
                                            // We create a object of sub class which will invoke subclass constructor.  
                                  
                                            // as well as parent class constructor.   
                                  
                                            Subclass s = new Subclass();  
                                  
                                            // Calling sub class method  
                                  
                                            s.display();  
                                  
                                  }  

                                    Output:

                                    Dart Implicit Superclass constructor example
                                    This is a superclass constructor
                                    This is a subclass constructor
                                    Welcome to javatpoint
                                    

                                    Explicit super

                                    If the superclass constructor consists of parameters then we require to call super() constructor with argument in to invoke superclass constructor in subclass explicitly. Let’s understand the following example.

                                    Example –

                                    // Parent class  
                                    
                                    class Superclass {  
                                    
                                              Superclass(String msg){  
                                    
                                                   print("This is a superclass constructor");  
                                    
                                                    print(msg);  
                                    
                                      
                                    
                                                    }  
                                    
                                    }  
                                    
                                    class Subclass extends Superclass  
                                    
                                    {  
                                    
                                              Subclass():super("We are calling superclass constructor explicitly "){  
                                    
                                                    print("This is a subclass constructor");  
                                    
                                                     
                                    
                                               }  
                                    
                                               display(){  
                                    
                                                   print("Welcome to javatpoint");  
                                    
                                    }  
                                    
                                    }  
                                    
                                    void main(){  
                                    
                                              print("Dart Implicit Superclass constructor example");  
                                    
                                              // We create an object of sub class which will invoke subclass constructor.  
                                    
                                              // as well as parent class constructor.   
                                    
                                              Subclass s = new Subclass();  
                                    
                                              // Calling sub class method  
                                    
                                              s.display();  
                                    
                                    }  

                                      Output:

                                      Dart explicit Superclass constructor example
                                      This is a parameterized superclass constructor
                                      We are calling superclass constructor explicitly
                                      This is a subclass constructor
                                      Welcome to javatpoint
                                      
                                    1. Dart Inheritance

                                      Dart inheritance is defined as the process of deriving the properties and characteristics of another class. It provides the ability to create a new class from an existing class. It is the most essential concept of the oops(Object-Oriented programming approach). We can reuse the all the behavior and characteristics of the previous class in the new class.

                                      • Parent Class – A class which is inherited by the other class is called superclass or parent class. It is also known as a base class.
                                      • Child Class – A class which inherits properties from other class is called the child class. It is also known as the derived class or subclass.

                                      Suppose we have a fleet of cars, and we create three classes as Duster, Maruti, and Jaguar. The methods modelName(), milage(), and man_year() will be same for all of the three classes. By using the inheritance, we don’t need to write these functions in each of the three classes.

                                      Dart Inheritance

                                      As you can see in the above figure, if we create class Car and write the common function in each of the classes. Then, it will increase duplication and data redundancy in the program. The inheritance is used to avoid this type of situation.

                                      We can avoid data redundancy by defining the class Car with these functions in it and inheriting in the other classes from the Car class. It enhances the re-usability of code. We just need to write function one time instead of multiple times. Let’s have a look at the following image.

                                      Dart Inheritance

                                      The syntax is given below.

                                      Syntax –

                                      class child_class extends parent_class {  
                                      
                                          //body of child class  
                                      
                                      } 

                                        The child class inherits functions and variables, or properties of parent class using the extends keyword. It cannot inherit the parent class constructor; we will discuss this concept later.

                                        Types of Inheritance

                                        The inheritance can be mainly four types. These are given below.

                                        • Single Inheritance
                                        • Multiple Inheritance
                                        • Multilevel Inheritance
                                        • Hierarchical Inheritance

                                        Single Level Inheritance

                                        In the single inheritance, a class is inherited by a single class or subclass is inherited by one parent class. In the following example, we create Person which inherits Human class.

                                        Dart Inheritance

                                        Let’s understand the following example.

                                        Example –

                                        class Bird{    
                                        
                                              void fly()  
                                        
                                                 {  
                                        
                                                    print("The bird can fly");  
                                        
                                                  }  
                                        
                                           }    
                                        
                                              // Inherits the super class  
                                        
                                        class Parrot extends Bird{    
                                        
                                                 //child class function  
                                        
                                                 void speak(){  
                                        
                                                     print("The parrot can speak");  
                                        
                                                         }            
                                        
                                        }  
                                        
                                        void main() {  
                                        
                                              // Creating object of the child class  
                                        
                                              Parrot p=new Parrot();    
                                        
                                              p.speak();    
                                        
                                              p.fly();    
                                        
                                        }   

                                          Output

                                          The parrot can speak
                                          The bird can fly
                                          

                                          Explanation:

                                          In the above code, we create parent class Bird and declared the fly() function in it. Then, we created the child class called Parrot, which inherited the parent class’s property using the extends keyword. The child class has its own function speak().

                                          Now the child class has two functions fly() and speak(). So we created the object of child class and access both functions. It printed the result to the console.

                                          Multilevel Inheritance

                                          In the multiple inheritance, a subclass is inherited by another subclass or creates the chaining of inheritance. Let’s understand the following example.

                                          Dart Inheritance

                                          Example –

                                          class Bird{    
                                          
                                                void fly()  
                                          
                                                   {  
                                          
                                                      print("The bird can fly");  
                                          
                                                    }  
                                          
                                             }    
                                          
                                                // Inherits the super class  
                                          
                                          class Parrot extends Bird{    
                                          
                                                   void speak(){  
                                          
                                                       print("The parrot can speak");  
                                          
                                                           }  
                                          
                                                       
                                          
                                          }  
                                          
                                             
                                          
                                          // Inherits the Parror base class  
                                          
                                          class Eagle extends Parrot {  
                                          
                                                    void vision(){  
                                          
                                                       print("The eagle has a sharp vision");  
                                          
                                                           }  
                                          
                                          }  
                                          
                                          void main() {  
                                          
                                                // Creating object of the child class  
                                          
                                                Eagle e=new Eagle();    
                                          
                                                e.speak();    
                                          
                                                e.fly();    
                                          
                                                e.vision();  
                                          
                                          }    

                                            Output

                                            The parrot can speak
                                            The bird can fly
                                            The eagle has a sharp vision
                                            

                                            Explanation:

                                            In the above example, we created another new class Eagle and inherited the Parrot class. Now the parrot is the parent class of Eagle, and class Eagle acquired all functions of both parent classes. We created the object of the child class and accessed all properties. It printed the output to the screen.

                                            Note – Dart doesn’t support multiple inheritance because it creates complexity in the program.

                                            Hierarchical Inheritance

                                            In the hierarchical inherence, two or more classes inherit a single class. In the following example, the two-child classes Peter and James inherit the Person class.

                                            Dart Inheritance

                                            Example –

                                            // Parent Class  
                                            
                                            class Person {  
                                            
                                              void dispName(String name) {  
                                            
                                                print(name);  
                                            
                                              }  
                                            
                                              
                                            
                                              void dispAge(int age) {  
                                            
                                                print(age);  
                                            
                                              }  
                                            
                                            }  
                                            
                                              
                                            
                                            class Peter extends Person {  
                                            
                                               
                                            
                                              void dispBranch(String nationality) {  
                                            
                                                print(nationality);  
                                            
                                              }  
                                            
                                            }  
                                            
                                            //Derived class created from another derived class.  
                                            
                                            class James extends Person {  
                                            
                                                      void result(String result){  
                                            
                                                          print(result);  
                                            
                                            }  
                                            
                                            }  
                                            
                                            void main() {  
                                            
                                                  // Creating Object of James class  
                                            
                                                  James j = new James();  
                                            
                                                  j.dispName("James");  
                                            
                                                  j.dispAge(24);  
                                            
                                                  j.result("Passed");  
                                            
                                              
                                            
                                                // Creating Object of Peter class  
                                            
                                                  Peter p = new Peter();  
                                            
                                                  p.dispName("Peter");  
                                            
                                                  p.dispAge(21);  
                                            
                                                  p.dispBranch("Computer Science");  
                                            
                                              
                                            
                                            } 

                                              Output

                                              James
                                              24
                                              Passed
                                              Peter
                                              21
                                              Computer Science
                                              
                                            1. Dart super Keyword

                                              The super keyword is used to denote the instant parent class object of the current child class. It is used to invoke superclass methods, superclass constructor in its child class. The super keyword’s main objective is to remove the confusion between parent class and subclass with the same method name. It is also used to refer to the superclass properties and methods.

                                              Usage of static Keyword

                                              • When parent class and child class have members with the same name, then super keyword can be accessed data members of parent class in child class.
                                              • It is used to access the parent class constructor in the child class.
                                              • Using the super keyword, we can access the superclass method that is overridden by the subclass.

                                              Using a super keyword with variables

                                              This situation arises when the child class has the same name variables as superclass variables. So there is a chance of ambiguity for Dart compiler. Then super keyword can access the superclass variables in its child class. The syntax is given below.

                                              Syntax:

                                              Super.varName  

                                              We can more understand by the following example.

                                              Example –

                                              // Super class Car   
                                              
                                              class Car  
                                              
                                              {   
                                              
                                                  int speed = 180;   
                                              
                                              }   
                                              
                                                  
                                              
                                              // sub class Bike extending Car   
                                              
                                              class Bike extends Car   
                                              
                                              {   
                                              
                                                  int speed = 110;   
                                              
                                                  
                                              
                                                  void display()   
                                              
                                                  {   
                                              
                                                      //print varible of the base class (Bike)  
                                              
                                                      print("The speed of car: ${super.speed}");  
                                              
                                                  }   
                                              
                                              }   
                                              
                                              void main() {  
                                              
                                              // Creating object of sub class  
                                              
                                              Bike b = new Bike();  
                                              
                                              b.display();  
                                              
                                              }   

                                                Output

                                                The speed of car: 180
                                                

                                                Explanation:

                                                In the above code, we defined the superclass as Car, which has a speed variable, and then it inherited by the subclass Bike.

                                                The sub class also has variable speed, so we used the super keyword to access the parent class variable. We created the object of child class b and called a display method that printed the value of superclass variable.

                                                If we use the print(speed) instead of print(super.speed), it will print the value the subclass variable.

                                                You can copy the above code, paste it into your dartpad or notepad, and print the value without using the super keyword. You can see the difference between both results.

                                                Using the super keyword with parent class method

                                                As discussed earlier, the super keyword is used to access the parent class method in child class. If the child class and parent class consist of the same name, then we can use the super keyword to use the parent class method in child class. The syntax is given below.

                                                Syntax:

                                                super.methodName;  

                                                Let’s understand the following example

                                                Example –

                                                // Base class Super   
                                                
                                                class Super   
                                                
                                                {   
                                                
                                                    void display()   
                                                
                                                    {   
                                                
                                                        print("This is the super class method");   
                                                
                                                    }   
                                                
                                                }   
                                                
                                                  
                                                
                                                // Child class inherits Super  
                                                
                                                class Child extends Super   
                                                
                                                {   
                                                
                                                    void display()   
                                                
                                                    {   
                                                
                                                        print("This is the child class");   
                                                
                                                    }   
                                                
                                                  
                                                
                                                    // Note that message() is only in Student class   
                                                
                                                    void message()   
                                                
                                                    {   
                                                
                                                        // will invoke or call current class display() method   
                                                
                                                        display();   
                                                
                                                  
                                                
                                                        // will invoke or call parent class displa() method   
                                                
                                                        super.display();   
                                                
                                                    }   
                                                
                                                }   
                                                
                                                  
                                                
                                                void main() {  
                                                
                                                 // Creating object of sub class  
                                                
                                                Child c = new Child();   
                                                
                                                // calling display() of Student   
                                                
                                                c.message();   
                                                
                                                    }   

                                                  Output

                                                  This is the child class method
                                                  This is the super class method
                                                  

                                                  Explanation –

                                                  In the above code, we created the function with the same name in both parent class and child class. The display() method is present in both parent class and child class that means It is a situation of method overriding.

                                                  So we created a message() method in the child class, inside it, we called parent class method using the super keyword, and then created the object of the child class. Using the object, we called the message() method that printed both display() methods statements to the screen.

                                                  Note – The super can be used only if the subclass method overrides the superclass method. If it doesn’t then we don’t require using super keyword.

                                                  Using super keyword with constructor

                                                  We can also use the super keyword to access the parent class constructor. The super keyword can call both parameterized and non-parameterized constructors depending on the situation. The syntax is given below.

                                                  Syntax:

                                                  :super();  

                                                  Let’s understand the following example.

                                                  Example –

                                                  // Base class called Parent  
                                                  
                                                  class Parent  
                                                  
                                                  {   
                                                  
                                                      Parent()   
                                                  
                                                      {   
                                                  
                                                          print("This is the super class constructor");   
                                                  
                                                      }   
                                                  
                                                  }   
                                                  
                                                    
                                                  
                                                  // Child class Super  
                                                  
                                                  class Child extends Parent   
                                                  
                                                  {              
                                                  
                                                      Child():super()   // Calling super class constructor  
                                                  
                                                      {                   
                                                  
                                                          print("This is the sub class constructor");   
                                                  
                                                      }   
                                                  
                                                  }  
                                                  
                                                    
                                                  
                                                  void main() {  
                                                  
                                                   // Creating object of sub class  
                                                  
                                                  Child c = new Child();   
                                                  
                                                  }  

                                                    Output

                                                    This is the super class constructor
                                                    This is the sub class constructor
                                                    

                                                    Explanation

                                                    The syntax of Dart language is too close to C# language. We called the parent class constructor using the super keyword, which is separated by : (colon). The delegate a superclass constructor, we should put the superclass as an initializer.

                                                  1. Dart static Keyword

                                                    The static keyword is used to declare the class variable and method. It generally manages the memory for the global data variable. The static variables and methods are the member of the class instead of an individual instance. The static variable or methods are the same for every instance of the class, so if we declare the data member as static then we can access it without creating an object. The class object is not required to access the static method or variable we can access it by putting the class name before the static variable or method. Using the class name, we can call the class method from the other classes.

                                                    Dart Static Variable

                                                    A variable which is declared using the static keyword inside the class is called Dart static keyword. These are the member of the class instead of a specific instance. The static variables are treated the same for all instances of the class; it means a single copy of the static variable is shared among all instances of classes. It allocates memory once and at the class loading and uses throughout the program.

                                                    Point to Remember –

                                                    • The static variable is also identified as a class variable.
                                                    • Single copy of the static variable is shared among the instance of a class.
                                                    • It can be accessed using the class name. We don’t need to create an object of that class they belong to.
                                                    • The static variables can be accessed directly in the static methods.

                                                    Declaring Static Variable

                                                    Dart provides the static keyword to declare the static variable. It is declared by using the static keyword followed by the variable name. The syntax is given below.

                                                    Syntax:

                                                    static [data_type] [variable_name];  

                                                    Accessing Static Variable

                                                    We can access the static variable by using the class name itself instead of creating an object of it. The syntax is given below.

                                                    Syntax:

                                                    ClassName.staticVariableName;  

                                                    Dart Static Method

                                                    The concept of the static method is also similar to static variable. The static methods are the member of the class instead of the class instance. The static methods can use only static variables and can invoke the static method of the class. We don’t need to create an instance of class the access it. The static method is useful when we want to use it in other classes.

                                                    Points to Remember

                                                    • The static methods are the member class instead of its object.
                                                    • Static methods are also identifies as class methods.
                                                    • We can access static methods using the class name.
                                                    • A particular copy of the static method is distributed among all the instances of a class.

                                                    Declaring Static Methods

                                                    We can declare the static method by using the static keyword followed by the method name with the return type. The syntax is given below.

                                                    Syntax:

                                                    static return_type method_name() {  
                                                    
                                                     //statement(s)  
                                                    
                                                    }  

                                                      Calling Static Method

                                                      The static methods can be called by using the class name, which they belong to instead of creating an object.

                                                      Syntax:

                                                      className.staticMethod();  

                                                      Let’s understand the following example.

                                                      Example –

                                                      class Student {  
                                                      
                                                         static String stdBranch;  // Declaring static variable  
                                                      
                                                         String stdName;  
                                                      
                                                         int roll_num;  
                                                      
                                                           
                                                      
                                                         showStdInfo() {  
                                                      
                                                           print("Student's name is: ${empName}");  
                                                      
                                                           print("Student's salary is: ${roll_num}");  
                                                      
                                                           print("Student's branch name is: ${stdBranch}");  
                                                      
                                                        
                                                      
                                                            }  
                                                      
                                                      }  
                                                      
                                                        
                                                      
                                                      void main() {  
                                                      
                                                         
                                                      
                                                        Student std1 = new Student();  // Creating instances of student class   
                                                      
                                                        Student std2 = new Student();  
                                                      
                                                        // Assigning value of static variable using class name   
                                                      
                                                        Student.stdBranch = "Computer Science";  
                                                      
                                                          
                                                      
                                                        std1.stdName = "Ben Cutting";  
                                                      
                                                        std1.roll_num = 90013  
                                                      
                                                        std1.showStdInfo();  
                                                      
                                                        
                                                      
                                                        std2.stdName = "Peter Handscomb";  
                                                      
                                                        std2.roll_num = 90014  
                                                      
                                                        std2.showStdInfo();  
                                                      
                                                      }  

                                                        Output

                                                        Student's name is: Ben Cutting
                                                        Student's salary is: 90013
                                                        Student's branch name is: Computer Science
                                                        Student's name is: Peter Handscomb
                                                        Student's salary is: 90014
                                                        Student's branch name is: Computer Science
                                                        

                                                        Explanation:

                                                        In the above code, we declared the class called Student, which has three fields including static variable stdBranch and one method showStdInfo(). We created two instances of class Student and assigned values to the class variables.

                                                        The static variable stdBranch accessed by using the class name and assigned value. Then, we called the showStdInfo() function by objects std1 and stu2. It printed details of the student as an output.

                                                      1. Dart this Keyword

                                                        The this keyword is used to refer the current class object. It indicates the current instance of the class, methods, or constructor. It can be also used to call the current class methods or constructors. It eliminates the uncertainty between class attributes and the parameter names are the same. If we declare the class attributes same as the parameter name, that situation will create ambiguity in the program, then the this keyword can remove the ambiguity by prefixing the class attributes. It can be passed as an argument in the class method or constructors.

                                                        Let’s understand the following example of how this keyword works.

                                                        Example – Without using this keyword

                                                        class Mobile {  
                                                        
                                                            String modelname;  
                                                        
                                                            int man_year;  
                                                        
                                                              
                                                        
                                                             // Creating constructor  
                                                        
                                                            Mobile(modelname, man_year){  
                                                        
                                                                     modelname = modelname;  
                                                        
                                                                     man_year = 2020;  
                                                        
                                                                     print("Mobile's model name is: ${modelname}, and the manufacture year is: ${man_year}");  
                                                        
                                                          
                                                        
                                                                          }  
                                                        
                                                                                                                      }  
                                                        
                                                        void main(){  
                                                        
                                                        Mobile mob = new Mobile("iPhone 11 ",2020);  
                                                        
                                                               } 

                                                          Output

                                                          Mobile's model name is: iPhone 11 , and the manufacture year is: 2020
                                                          

                                                          Explanation:

                                                          In the above program, we created a class called Mobile, which has two attributes modelname and man_year. Then, we created a constructor and passed parameters the same as the class attributes name.

                                                          In the constructor body, the class variables (attributes) on the left side are assigned by the constructor parameters with the same name. When we create the instance of a class, the constructor automatically called the constructor and printed the result.

                                                          The Dart compiler might get confused if there are a number of the same name parameters. The result is the compiler will create ambiguity. That’s why we use the this keyword to refer the current class object.

                                                          Example – 2: Using this keyword

                                                          class Mobile {  
                                                          
                                                              String modelname;  
                                                          
                                                              int man_year;  
                                                          
                                                                
                                                          
                                                               // Creating constructor  
                                                          
                                                              Mobile(modelname, man_year){  
                                                          
                                                                       this.modelname = modelname;  
                                                          
                                                                       this.man_year = 2020;  
                                                          
                                                                       print("Mobile's model name is: ${modelname}, and the manufacture year is: ${man_year}");  
                                                          
                                                            
                                                          
                                                                            }  
                                                          
                                                                                                                        }  
                                                          
                                                          void main(){  
                                                          
                                                          Mobile mob = new Mobile("IPhone 11",2020);  
                                                          
                                                                 }

                                                          Output

                                                          Mobile's model name is: IPhone 11, and the manufacture year is: 2020
                                                          

                                                          Explanation:

                                                          The above example is the same as the previous program, but the only difference of this keyword.

                                                          this.modelname = modelname;  
                                                          
                                                          this.man_year = 2020;  

                                                            We have used the this keyword to the different instance or class variable from the local variable.

                                                            Points to Remember

                                                            • The this keyword is used to point the current class object.
                                                            • It can be used to refer to the present class variables.
                                                            • We can instantiate or invoke the current class constructor using this keyword.
                                                            • We can pass this keyword as a parameter in the constructor call.
                                                            • We can pass this keyword as a parameter in the method call.
                                                            • It removes the ambiguity or naming conflict in the constructor or method of our instance/object.
                                                            • It can be used to return the current class instance.

                                                            Local Variable

                                                            Local variables are defined in the methods, constructors, or blocks. It is created when we create a method or constructor, and it has scope only inside them. We cannot use a local variable outside the method, constructor, or block.

                                                            Class Variable

                                                            Class variable is also known as the static member variable, which is used to declare using the static keyword. It is declared in the class, but outside a constructor, method or a block. All instances share one copy of the class variable or we can say that class variables are common to all instances of that class.

                                                            Instance Variable

                                                            Instance variable is also known as the non-static, variable which is used to declare without the static keyword. The instance variables are specific by an object. These variables can be accessed using the instance of that class.

                                                            Difference Between Class Variable and Instance Variable

                                                            The following are the difference between the class variable and instance variable

                                                            Sr.Class VariableInstance Variable
                                                            1.The class variable is declared using the static keyword in a class, but not in method and constructor.The instance variable is declared in a class without using the static keyword.
                                                            2.The class variable can be accessed using the class name.
                                                            Syntax:
                                                            ClassName.variableName
                                                            The instance variable can be accessed using the instance of that class.
                                                            Syntax:
                                                            ObjectRefernce.variableName
                                                            3The class variables are common to all instances of that class. All instances of the class share one copy of the static variable.The instance variables are not common to all instance of class. Each object of particular will preserve its own copy of the instance variables.
                                                            4These are created when the program is started and destroys when the program is terminated.The instance variables are created when an object of the particular class created using the new() keyword and destroys when the object is destroyed.