Dart 语言入门 5: 类别(Class)

Dart是一个物件导向语言,同时支持混入(mixin)的继承机制。每个物件都是一个类别的实体,所有的类别都继承于object。基于Mixin的继承意味着每个类别(Object除外)都只有一个父类别,一个类别可以在其他多个类别继承中重複使用。使用new关键字和建构式来建立新的物件。建构式的名字可以为ClassName或者ClassName.identifier。

宣告类别

宣告一个类别,使用关键字class开头,后跟类别名称; 接着使用一对大括号包围程式码。如下所示

语法

class class_name {     <fields>    <getters/setters>    <constructors>    <functions> }

类别可包括以下内容:
栏位(fields) - 栏位是类别中宣告的变数。
getters和setters - 允许程式初始化和检索类别栏位的值,预设的getter/setter与每个类别相关联。但是可以通过显式定义setter/getter来覆盖预设值。
建构式(constructors) - 为类别的物件分配记忆体。
函式(functions) - 函式表示物件可以採取的操作,也称为方法。
以上称为类别的资料成员。
做一个範例如下,宣告一个类别Car。该类别有一个brand的栏位;一个简单的方法 disp(),列印出厂牌这个栏位的值。

class Car {  // field  String brand = 'Tesla';  // function  void disp() {    print(brand);  }}

建立类别的实体(Creating Instance of the class)

语法
目前建立类别的实体,不用加上new, 这样看起来更简洁。直接让变数等于建构式即可。

var object_name = class_name([ arguments ]);

把上面的Car类别,建立出实体

void main() {  var car1 = Car();       //建立 Car 的实体 物件:car1  print(car1.brand);      //Tesla}class Car {  // field  String brand = 'Tesla';  // function  void disp() {    print(brand);  }}

建构式

建构式是类别的特殊函式,负责初始化类别。建构式是一个与类别名称相同的函式,它是一个函式,因此可以传入参数。但是与函式不同的地方,在于建构式不能具有返回型别。如果未宣告建构式,则会预设无参数的建构式。
语法

class_name(parameter_list) {    //constructor body }

用上面的Car类别来修改,加上含有一个参数的建构式。这里有用到 this 关键字, 代表物件本身。

void main() {  var car1 = Car('Benz');  var car2 = Car('BMW');  print(car1.brand);  car2.disp();}class Car {  // field  String brand = 'Tesla';  //constructors  Car(String b) {    this.brand = b;  }  // function  void disp() {    print('The brand of the car is $brand');  }}

http://img2.58codes.com/2024/20121852YnJIuqOZmD.png

命名建构式

由于Dart不支援同一名称但是不同参数的多形建构式,以 Car 类别为例子,只能有一个名称叫做Car的建构式,
若是需要建立其他的建构式,需要命名为其他名称来建立,例如 Car.fromBC(brand, color)来建立。

void main() {  var car1 = Car('Benz');  var car2 = Car.fromBC('BMW', 'black');  car1.color = 'red';  car1.disp();  car2.disp();}class Car {  // field  String brand;  String color;  //constructors  Car(String brand) {    this.brand = brand;  }  //这里採用命名建构式,并使用简写方式建立  Car.fromBC(this.brand, this.color);  // function  void disp() {    print('The brand of the car is $brand and color is $color.');  }}

http://img2.58codes.com/2024/20121852lntan7c80U.png

Getters和Setter

Getters(存取器)和Setter(更改器)允许程式分别初始化和检索类栏位的值。
Getters:使用get关键字定义。没有参数,会回传值。
Setter:使用set关键字定义。只有一个参数,且不回传值。
语法

//getterreturn_type  get identifier { }//setterset identifier { }
void main() {  var car1 = Car('Benz', 'red');  var car2 = Car('BMW', 'blue');  car1.disp();  car2.disp();  car1.setColor = 'black';  print('The Color of this car reset to ${car1.getColor}');}class Car {  // field  String brand;  String color;  //constructors  Car(this.brand, this.color);  //Setter  set setColor(String c) {    color = c;  }  set setBrand(String b) {    brand = b;  }  //getter  String get getColor => color;  String get getBrand => brand;  // function  void disp() {    print('The brand of the car is $brand and color is $color.');  }}

http://img2.58codes.com/2024/201218528G5vBoLA2t.png

静态(static)用法

利用static 可以实现,在相同的类别之间的物件,可以共享栏位值与函式。要注意的是,若修改了类别上的static 的值,则所有该类别产生的物件都会受到影响,使用时需特别小心。

void main() {  var person1 = Person('Dragon', 'Chen');  var person2 = Person('Jefferson', 'Lin');  print(person1.showFullName);  print(person2.showFullName);  Person.sayHi(person1);  Person.sayHi(person2);  Person.label = 'Your name is';  print(person1.showFullName);  print(person2.showFullName);  Person.sayHi(person1);  Person.sayHi(person2);}class Person {  // field  String firstName;  String lastName;  static String label = "Person's name is ";  //constructors  Person(this.firstName, this.lastName);  //Setter  set fullName(String f) {    var temp = f.split(' ') ;    firstName =  temp.first;    lastName = temp.last;  }  set setFirstName(String f) {    firstName = f;  }  set setLastName(String l){    lastName = l;  }  //getter  String get getFirstName => firstName;  String get getLastName => lastName;  String get showFullName => '$label $firstName $lastName';  // static function  static void sayHi(Person p) {    print('Hi $label ${p.firstName} ${p.lastName}');  }}

http://img2.58codes.com/2024/20121852fk6h0Dq0Rf.png

继承

extends: 关键字来继承类别。要注意的是,除了建构式之外,全部的成员都会继承。不支援多重继承。
super: 可呼叫父层变数,属性或函式等等。。
@override: 重载(reload),也就是重新定义父层的函式,但是参数的数量和型别必须匹配。
语法

class child_class_name extends parent_class_name
void main() {     var circle1 = Circle();      circle1.area();     circle1.color = 'red';     print('my color is ${circle1.showColor}'); }  class Shape {   String color;   void area() {       print("show area");    }    String get showColor => color; }  class Circle extends Shape {}

http://img2.58codes.com/2024/20121852yYjWSsvwVe.png

void main() {      var person1 = Person('Dragon','Chen');    var person2 = Doctor('Jefferson','Lin','Badboy');    print(person1);    print(person2);}  class Person {   String firstName;  String lastName;  String get fullName => '$firstName $lastName';  Person(this.firstName, this.lastName);}  class Doctor extends Person{  String nickName;  Doctor(String f, String l, this.nickName) :super(f,l);  @override String toString() => 'Hi Doctor $fullName, also known as $nickName';}

http://img2.58codes.com/2024/20121852tm3HhzmASZ.png

抽象类别(Abstract class)

使用abstract关键字定义一个抽象类别,一个不能被实体化的类别,抽象类别通常用来定义介面(interface)。

void main() {  var doctor1 = Doctor('Dragon', 'Chen', 'DC');  print(doctor1.fullName);}abstract class Person {  String firstName;  String lastName;  String get fullName;  Person(this.firstName, this.lastName);}class Doctor extends Person {  String nickName;  Doctor(String f, String l, this.nickName) : super(f, l);  @override  String get fullName =>      'Hi Doctor $firstName $lastName, also known as $nickName';}

http://img2.58codes.com/2024/201218521ATvLpX6lH.png
例子中可以看出,实体化Doctor类别,而不是实体化Person。而Person类别中的 fullName为抽象的getter且未实作,因此在子类别 Doctor中需实作 fullName。

介面(Interface)

Dart语言中,并未定义interface这个关键字,而是类别本身就是介面,也就是说类别除了可以被继承也可以被实作(implements)。

void main() {  var doctor1 = Doctor('Dragon', 'Chen', 'DC');  print(doctor1.fullName);}abstract class Person {  String firstName;  String lastName;  String get fullName;  Person(this.firstName, this.lastName);}class Doctor implements Person {  String nickName;  @override String firstName;  @override String lastName;  Doctor(this.firstName, this.lastName, this.nickName);  @override  String get fullName =>      'Hi Doctor $firstName $lastName, also known as $nickName';}

http://img2.58codes.com/2024/20121852pzh1Jkcp0v.png
上面的例子显示,实作介面,就像是Person类别先设定好该有的成员,然后Doctor类别将内容实作出来。

实现多个介面

实现多个介面,介面名称之间用逗号分隔。语法如下:

class identifier implements interface-1,interface_2,interface_4…….
void main() {    var c = Calculator();    print('The gross total : ${c.retTot()}');    print('Discount :${c.retDis()}'); }  class CalculateTotal {    // ignore: missing_return   int retTot() {} }  class CalculateDiscount {    // ignore: missing_return   int retDis() {} }class Calculator  implements CalculateTotal,CalculateDiscount {    @override  int retTot() {       return 1000;    }    @override  int retDis() {       return 50;    } }

http://img2.58codes.com/2024/20121852pgBAPNOaYx.png

混入(Mixin)

因为只能单一继承,若是想要增加别的类别的函式功能,类似多重继承,就是使用混入(mixin)。
可以使用关键字mixin来取代class来宣告一个混入的类别,该类别就是一个让别的类别混入的类别。
混入类别无法被继承,且没有建构式。若要限制使用混入的类别,可用on关键字指定。
使用 with 来添加混入的类别。

mixin ProgrammerSkills on Developer{  void coding(){    print('writing code');  }}class Developer extends Person with ProgrammerSkills, ManagerSkills{  ...}```

关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章