kind
class definition
//Define a class of Person class Person { //Attributes String userName = 'Tobu'; int age = 25; String blogAdress = 'https://www.cnblogs.com/TobuTobu'; String userInfo = 'Hello, I am Tobu, A mobile developer'; //method _printInfo() { print('Username: $userName\n User age: $age\n blog address: $blogAdress\n User Profile: $userInfo'); } }
instantiation of the class
//instantiate class Person p = new Person(); //Attributes of the referenced class print(p.userName); print(p.age); print(p.blogAdress); print(p.userInfo); print('------------------------------------------'); //method of reference class p._printInfo(); /* Tobu 25 https://www.cnblogs.com/TobuTobu Hello, I am Tobu, A mobile developer ------------------------------------------ Username: Tobu User age: 25 Blog address: https://www.cnblogs.com/TobuTobu User Profile: Hello, I am Tobu, A mobile developer */
Constructor
default constructor
//The contents of the constructor are automatically triggered when instantiated class Person { //Attributes String userName; int age; String blogAdress; //default constructor Person(this.userName, this.age, this.blogAdress); } //----------------------------------------------------- //declare variable String userName = 'Tobu'; int age = 25; String blogAdress = 'https://www.cnblogs.com/TobuTobu'; //instantiate class Person p = new Person(userName, age, blogAdress); print(p.userName); print(p.age); print(p.blogAdress); /* Tobu 25 https://www.cnblogs.com/TobuTobu */
named constructor
class Person { //Attributes String blogAdress; //named constructor Person.blogAdress(this.blogAdress) { print('My blog address is: $blogAdress'); } } main(List<String> args) { //declare variable String blogAdress = 'https://www.cnblogs.com/TobuTobu'; //instantiate class Person p1 = new Person.blogAdress(blogAdress); } /* My blog address is: https://www.cnblogs.com/TobuTobu */
getter s and setter s
getter
//useless getter main(List<String> args) { Area a = new Area(10, 20); print(a._getArea()); } class Area { double height; double width; Area(this.height, this.width); _getArea() { return height * width; } } //Using getter, access _getArea directly by accessing properties main(List<String> args) { Area a = new Area(10, 20); print(a._getArea);//changed } class Area { double height; double width; Area(this.height, this.width); get _getArea {//changed return height * width; } }
setter
main(List<String> args) { Area a = new Area(10, 20); a._setHeight = 5.0;//Modify height print(a._getArea); } class Area { double height; double width; Area(this.height, this.width); get _getArea { return height * width; } set _setHeight(value) { this.height = value; } }
Static members and static methods
main(List<String> args) { //Non-static methods need to instantiate the class var p = new Person(); p._printInfo(); //Static methods do not need to instantiate the class Person._show(); } class Person { static String name = 'Tobu'; //static properties int age = 25; //non-static properties //Static methods cannot call non-static members (properties and methods) static _show() { print(name); } //Non-static methods can access both static and non-static members _printInfo() { print(name); //Accessing static properties cannot use this print(this.age); //Access non-static properties _show();//access static methods } } /*Summarize: 1: static property + static method = static member | non-static property + non-static method = non-static member 2: Static methods cannot call non-static members (properties and methods) 3: Non-static methods can access both static and non-static members 4: Accessing static properties directly does not require this pointer---print(name) 5: Static methods do not need to instantiate classes---Person.show() */
object operator
? Conditional operator
main(List<String> args) { //No instantiation, p is empty, no error will be reported (nothing after p? This will report an error) Person p; p?._printInfo(); //Instantiate, p1 is not empty, execute as usual Person p1 = new Person(); p1?._printInfo(); } class Person { String name = 'Tobu'; int age = 25; _printInfo() { print('$name\n$age'); } }
as type conversion
var p; p = ''; p = new Person(); (p as Person)._printInfo();//convert p to Person
is type judgment
Person p = new Person(); print(p is Object);//true
.. cascade operation
Person p = new Person('Tobu', 25); p .._printInfo() ..name = 'Taco' ..age = 25 .._printInfo(); // p._printInfo(); // p.name = 'Taco'; // p.age = 20; // p._printInfo();
class inheritance
Inheritance of classes in Dart
1: The subclass uses the extends keyword to inherit the parent class
2: The subclass will inherit the properties and methods visible in the parent class, but will not inherit the constructor
3: The subclass can overwrite the method getter and setter of the superclass
extends inheritance
main(List<String> args) { Web w = new Web(); //Subclasses access properties and methods visible to the parent class print(w.name); w._printInfo(); } //Web subclass inherits parent class Person class Web extends Person {} class Person { String name = 'Tobu'; int age = 25; _printInfo() { print('$name\n$age'); } }
super pass parameter to parent class constructor
main(List<String> args) { Web w = new Web('Tobu', 23); print(w.name); w._printInfo(); } class Web extends Person { //Because the parent class constructor cannot be directly accessed by the child class, assign parameters to the parent class constructor through super Web(String name, int age) : super(name, age); } class Person { String name; int age; Person(this.name, this.age); _printInfo() { print('$name\n$age'); } }
Subclass properties and methods
main(List<String> args) { Web w = new Web('Tobu', 23, 'male'); w._printInfo(); w.run(); } class Web extends Person { //Subclass properties String sex; //Because the parent class constructor cannot be directly accessed by the child class, assign parameters to the parent class constructor through super Web(String name, int age, String sex) : super(name, age) { this.sex = sex; } /*Pass arguments to the parent class named constructor Web(String name, int age, String sex) : super.now(name, age) { this.sex = sex; } */ //subclass method run() { print('$name\n$age\n$sex'); } } class Person { String name; int age; Person(this.name, this.age); _printInfo() { print('$name\n$age'); } }
@override overrides (overrides) parent class methods
main(List<String> args) { Web w = new Web('Tobu', 23); w._printInfo();//Prioritize the subclass's own methods (override the superclass's method) } class Web extends Person { Web(String name, int age) : super(name, age); //Override parent class method @override _printInfo() { print('$name'); } } class Person { String name; int age; Person(this.name, this.age); _printInfo() { print('$name\n$age'); } }
abstract class
abstract abstract class
Abstract classes in Dart: Dart abstract classes are mainly used to define standards. Subclasses can inherit abstract classes or implement abstract class interfaces.
1. An abstract class is defined by the abstract keyword
2. An abstract method in Dart cannot be declared with abstract, and a method without a method body is called an abstract method such as: eat();
3. If the subclass inherits the abstract class, it must implement the abstract method in it
4. If an abstract class is implemented as an interface, all the properties and methods defined in the abstract class must be implemented.
5. An abstract class cannot be instantiated, only subclasses that inherit it can.
Polymorphism in Dart:
1. It is allowed to assign the pointer of the subclass type to the pointer of the superclass type, and the same function call will have different execution effects.
2. The instance of the subclass is assigned to the reference of the parent class
3. Polymorphism means that the parent class defines a method and does not implement it, but lets the subclasses that inherit it implement it. Each subclass has different performances.
Such as the following abstract class example is the performance of polymorphism.
//define an abstract class abstract class Animal { //An abstract method is an abstract method if it does not implement the method body eat(); run(); //non-abstract method printInfo() { print('I am a normal method in an abstract class'); } } //Subclass Dog inherits abstract parent class Animal class Dog extends Animal { @override eat() { print('puppy eating bone'); } @override run() { // TODO: implement run print('puppy running'); } } //Subclass Cat inherits abstract parent class Animal class Cat extends Animal { @override eat() { print('cat eating fish'); } @override run() { // TODO: implement run print('cat is running'); } } main() { //instantiate class Dog d = new Dog(); d.eat(); d.run(); //instantiate class Cat c = new Cat(); c.eat(); c.run(); }
implements interface
1. Ordinary classes or abstract classes can be implemented as interfaces
2. Use the implements keyword to implement
3. If a common class is implemented, all the properties and methods in the common class and abstract need to be rewritten
4. Because abstract classes can define abstract methods, ordinary classes cannot, so abstract classes are generally used to define interfaces
abstract class Db { String uri; add(String data); save(); delete(); } class Mysql implements Db { @override add(String data) { print('This is Mysql of add method' + data); } @override save() {} @override delete() {} Mysql(this.uri); @override String uri; } class Mssql implements Db { @override add(String data) {} @override save() {} @override delete() {} @override String uri; } class Mongodb implements Db { @override add(String data) {} @override save() {} @override delete() {} @override String uri; } main(List<String> args) { Mysql mysql = new Mysql('xxxxxx'); mysql.uri = '127.0.0.1'; mysql.add('added data'); }
The difference between extends and implements
1. If the methods in the abstract class are reused, and the subclasses are bound by abstract methods, we use extends to inherit the abstract class.
2. If we only use abstract classes as standards, we use Implements to implement abstract classes.
multiple interfaces
abstract class A { String name; printA(); } abstract class B { printB(); } class C implements A, B { @override String name; @override printA() { print('printA'); } @override printB() { print('printB'); } } main(List<String> args) { C c = new C(); c.printA(); c.printB(); }
mixins (similar to multiple inheritance, no constraints)
1. Classes as mixins can only inherit from object and cannot inherit from other classes
2. Classes as mixins cannot have constructors
3. A class can mixins multiple mixins classes
4. mixins are by no means inheritance or interfaces, but a new feature
class Person { String name; int age; Person(this.name, this.age); printInfo() { print('$name--------$age'); } } abstract class A { printA(); } abstract class B { printB(); } //Can inherit + mixins, the inherited parent class can have a constructor, but the mixins cannot have a constructor class C extends Person with A, B { C(String name, int age) : super(name, age); @override printA() { print('printA'); } @override printB() { print('printB'); } } main(List<String> args) { C c = new C('Tobu', 25); c.printInfo(); c.printA(); c.printB(); }
Generics
generic method
//No generics are added, getData1(value) { return value; } //Added generics to solve the problem of inconsistent parameter and return value types T getData<T>(T value) { return value; } main(List<String> args) { //no type checking getData('Hello'); //Add type checking, only the specified type of data can be entered print(getData<String>('Hello')); } //Popular understanding: generics are to solve the reusability of class interface methods, as well as support for unspecific data types (type verification)
generic class
main(List<String> args) { //Type verification, only String can be added PrintClass p = new PrintClass<String>(); p.add('Tobu'); p.printInfo(); //Type check, only int can be added PrintClass p1 = new PrintClass<int>(); p1.add(12); p1.printInfo(); } //define generic class class PrintClass<T> { List list = new List<T>(); void add(T value) { this.list.add(value); } void printInfo() { for (var i = 0; i < this.list.length; i++) { print(this.list[i]); } } }
generic interface
//define a generic interface abstract class Cache<T> { getByKey(String key); setByKey(String key, T value); } class FileCache<T> implements Cache<T> { @override getByKey(String key) {} @override setByKey(String key, T value) { print('FileCache--setByKey:key=${key},value=${value}'); } } class MemoryCache<T> implements Cache<T> { @override getByKey(String key) {} @override setByKey(String key, T value) { print('MemoryCache--setByKey:key=${key},value=${value}'); } } main(List<String> args) { //Type verification, value can only be passed in String FileCache f = new FileCache<String>(); f.setByKey('index', 'file1'); }