inheritance

  • Extends a class using the extends keyword
  • Subclasses inherit properties and methods visible to their parent class, not constructors
  • Subclasses can override methods, getters, and setters of their parent class
  • Single inheritance, polymorphism

We define an Animal class, Animal, with a name, age, a carnivorous property, default true, and a run() method.

class Animal{
  String name;
  int age;

  bool get eatMeat => true;

  void run(){
     print("run...");
  }
}
Copy the code

Define a Sheep class that incorporates the Animal class, override the carnivore property to false, override the run() method, and it has its own special method shout().

Class Sheep extends Animal{@override bool get eatMeat => false; @override void run() {print("Sheep run... ); } void shout(){ print("mie mie mie..." ); }}Copy the code

Create the Sheep class and call its run() method. Since the shout() method is unique to the Sheep class, we need to convert the Sheep variable of Animal type first, either using as conversion, or using the following determination:

void main() { Animal sheep = new Sheep(); // use the Animal class to receive sheep. Run (); If (sheep is sheep){// if(sheep is sheep){// if(sheep is sheep){// if(sheep is sheep){// if(sheep is sheep){// if(sheep is sheep); }}Copy the code

The printed result is:

Sheep run...
mie mie mie...
Copy the code

Constructor in inheritance

  • By default, the constructor of a subclass calls the nameless, no-argument constructor of its parent class
  • If the parent class has no nameless, no-argument constructor, you need to show that the parent class constructor was called
  • Used after constructor arguments: Displays the constructor that called the parent class

Define a Person class with a nameless constructor and a named constructor withAge()

class Person {
  String name;
  int age;

  Person(this.name);

  Person.withAge(this.age);
}

Copy the code

Define a Student class that inherits the Person class and override its two constructors:

class Student extends Person {
  Student(String name) : super(name);

  Student.withAge(int age) : super.withAge(age);
}
Copy the code

Construct the student instance with two different constructors:

void main() {
   var student1 = new Student("chaychan");
   var student2 = new Student.withAge(26);
   print(student1.name);
   print(student2.age);
}
Copy the code

Construct method execution order

  • The constructor of the parent class is called at the point where the subclass constructor body begins execution
  • If there is an initializer, the initializer is executed before the parent constructor
class Student extends Person {
  final String gender;

  Student(String name) : gender = "Male", super(name);
}
Copy the code

An abstract class

  • Abstract classes are expressed as abstract and cannot be instantiated directly
  • Abstract methods do not need to be modified with abstract, there is no implementation
  • Abstract classes can have no abstract methods
  • Classes that have abstract methods must be declared abstract
abstract class Animal {
   void run();
}

class Dog extends Animal {
  @override
  void run() {
     print("run...");
  }
}
Copy the code

interface

  • Classes and interfaces are unified, and a class is an interface
  • Each class implicitly defines an interface containing all instance members
class Animal { String name; int age; void run() { print("run..." ); } } class Dog implements Animal { @override int age; @override String name; @override void run() { print("run..." ); }}Copy the code

As you can see, the Animal class is the interface, and the Dog class implements this interface by copying all the properties and methods of the Animal class.

  • If you are reusing an implementation of an existing class, use extends

The above is equivalent to reuse the existing class implementation, can use inheritance method:

class Dog extends Animal {
}
Copy the code
  • If you only use external behavior of an existing class, use implements
abstract class Animal {
   void run();
}

class Dog implements Animal{
  @override
  void run() {
     print("run...");
  }
}
Copy the code

Mixins

  • Mixins are similar to multiple inheritance in that they are a way of reusing code for a class in multiple class inheritance
  • Use the keyword with to connect one or more mixins
void main() {
   var d = D();
   d.a();
   d.b();
   d.c();
}

class A{
   void a(){
     print("a");
   }
}

class B{
  void b(){
    print("b");
  }
}

class C{
  void c(){
    print("c");
  }
}

class D extends A with B, C{

}
Copy the code

As you can see, class D extends A, B, and C through Mixins, and has methods A (), B (), and C (). Methods that use Mixins need to extend A class and with other classes, not with A, B, and C directly.

  • Classes that are Mixins cannot have display declaration constructors
class D extends A with B, C{

}
Copy the code

B and C of class D above are Mixins. They cannot display declaration constructors, that is, they must use default methods, otherwise the editor will prompt an error.

  • Classes that are Mixins can only inherit from Objects
class C2{ } class C extends C2{ void c(){ print("c"); }} class D extends A with B, C{Copy the code

Overwrites the operator

  • The override operator needs to be defined in the class
Return type operator operator (parameter 1, parameter 2...) {implementation body return value}Copy the code
  • If you override ==, you also need to override the object’s hashCode getter method

  • Operators that can be overridden are:

< > < = > = + - * / ~ / % | & ^ < < > > [] [] = ~ = =Copy the code

Example of copying the > and [] operators to compare the size of two people by comparing their ages:

void main() { var p1 = Person(18); var p2 = Person(20); print(p1 > p2); print(p1["aage"]); } class Person { int age; Person(this.age); bool operator >(Person person) { return this.age > person.age; } int operator [](String str) { if ("age" == str) { return age; } return 0; }}Copy the code

The printed result is:

false
0
Copy the code

The enumeration

  • Enumeration is a data type with a finite set of sequences
  • Define an enumeration using the keyword enum
  • Often used in place of constants to control statements
enum Season{
  spring,
  summer,
  autumn,
  winter
}
Copy the code

Dart enumeration features:

  • Index starts at 0 and accumulates
  • Cannot specify a raw value
  • Cannot add methods
void main() {
   print(Season.spring.index);
   print(Season.summer.index);
   print(Season.autumn.index);
   print(Season.winter.index);
}
Copy the code

The printed result is:

0
1
2
3
Copy the code

Unlike Enumerations in Java, enumerations in Dart cannot specify raw values or add methods.

The generic

  • Types are optional in Dart and can be qualified using generics
void main() {
  var list1 = new List();
  list1.add(1);
  list1.add("2");
  
  var list2 = new List<int>();
  list2.add(1);
  list2.add(2);
}
Copy the code

In the code above,list1 does not specify generics and can add values of any type, while List2 specifies generics as ints and can only add values of integer type.

  • Using generics is a great way to reduce code duplication (utility methods can return the result of the specified generic type by passing it in, without having to write duplicate code to return the result of a different type).

The use of generics

  • A generic class
class DataHelper<T>{
   T data;
   setData(T data){
      this.data = data;
   }
}

void main() {
   var helper1 = DataHelper<int>();
   helper1.setData(1);

   var helper2 = DataHelper<String>();
   helper2.setData("2");
}
Copy the code

You can see that we define a DataHelper class that restricts the data types that are passed in through the generics of the incoming class.

  • Method generics
void main() { var helper = DataHelper(); helper.checkData<int>(1); helper.checkData<String>("Hello"); } class DataHelper{ checkData<T>(T data){ if(data is int){ print("data is int"); }else if(data is String){ print("data is String"); }}}Copy the code

You can see that we define a method checkData that requires generics, limiting the types of parameters by specifying generics.

Now that you’ve covered the basics of Dart, you’re ready to try and develop and practice.