Dart13类
Dart13类
1.声明一个类
class class_name {
<fields>
<getters/setters>
<constructors>
<functions>
}
示例:
class Car {
// field
String engine = "EA888";
// function
void disp() {
print(engine);
}
}
2.构造函数
2.1.默认构造函数
与类同名的函数,在实例化时,自动被调用
class Point {
num x, y;
// 默认构造函数
Point() {
print('这是默认的构造函数,实例化时,会第一个被调用。');
}
}
void main() {
Point p = new Point();
print(p.x);
// 这是默认的构造函数,实例化时,会第一个被调用。
// null
}
构造函数是类的特殊函数,负责初始化类的变量。
class Car {
String engine;
Car(String engine) {
this.engine = engine;
print("The engine is : ${engine}");
}
}
void main() {
Car c1 = new Car('EA888');
}
2.2.命名构造函数
在类中使用命名构造函数(类名.函数名)实现多个构造器,可以提供额外的清晰度
语法:
class_name.constructor_name(param_list)
以下示例显示如何在Dart中使用命名构造函数:
void main() {
Car c1 = new Car.namedConst('EA888');
Car c2 = new Car();
}
class Car {
Car() {
print("Non-parameterized constructor invoked");
}
Car.namedConst(String engine) {
print("The engine is : ${engine}");
}
}
执行上面示例代码,得到以下结果:
The engine is : EA888
Non-parameterized constructor invoked
2.3.常量构造函数
如果类生成的对象不会改变,可以通过常量构造函数使这些对象成为编译时常量
class Book {
// 属性必须通过 final 声明
final String name;
// const String author; // Only static fields can be declared as const
final String author;
// 常量构造函数,必须通过 const 声明
const Book(this.name, this.author);
}
void main() {
// 声明不可变对象,必须通过 const 关键字
var c1 = const Book('西游记', '吴承恩');
var c2 = const Book('西游记', '吴承恩');
print(c1 == c2); // true
// 常量构造函数,可以当作普通构造函数使用
var c3 = new Book('西游记', '吴承恩');
var c4 = new Book('西游记', '吴承恩');
print(c3 == c4); // false
// 实例化时,new关键字可以省略
var c5 = new Book('西游记', '吴承恩');
var c6 = new Book('西游记', '吴承恩');
print(c5 == c6); // false
}
2.4.identical
检查两个引用是否指向同一个对象。
class Book {
// 属性必须通过 final 声明
final String name;
final String author;
// 常量构造函数,必须通过 const 声明
const Book(this.name, this.author);
}
void main() {
// 声明不可变对象,必须通过 const 关键字
var c1 = const Book('西游记', '吴承恩');
var c2 = const Book('西游记', '吴承恩');
print(c1 == c2); // true
print(identical(c1, c2)); // true
// 常量构造函数,可以当作普通构造函数使用
var c3 = new Book('西游记', '吴承恩');
var c4 = new Book('西游记', '吴承恩');
print(c3 == c4); // false
print(identical(c3, c4)); // false
}
2.5.工厂构造函数
通过 factory 声明,工厂函数不会自动生成实例,而是通过代码来决定返回的实例
class Car {
int wheels;
static Car instance;
// 命名构造函数
Car.newCar(this.wheels);
// 工厂构造函数 -- 接受一个可选参数并赋默认值4
factory Car([int wheels = 4]) {
// 工厂构造函数中,不能使用 this 关键字
// print(this.wheels); // Invalid reference to 'this' expression
// 第一次实例化
if (Car.instance == null) {
Car.instance = new Car.newCar(wheels);
}
// 非第一次实例化
return Car.instance;
}
}
void main() {
// Car c1 = new Car();
// Car c2 = new Car(6);
// print(c1.wheels); // 4
// print(c2.wheels); // 4
Car c1 = new Car(6);
Car c2 = new Car();
print(c1.wheels); // 6
print(c2.wheels); // 6
print(c1 == c2); // true
}
3.Getter、Setter
默认的 getter/setter 与每个类相关联。但是,可以通过显式定义 setter/getter 来覆盖默认值。getter 没有参数并返回一个值,setter 只有一个参数但不返回值。
示例:
class Student {
String name;
int age;
String get stud_name {
return name;
}
void set stud_name(String name) {
this.name = name;
}
void set stud_age(int age) {
if(age<= 15) {
print("Age should be greater than 15");
} else {
this.age = age;
}
}
int get stud_age {
return age;
}
}
void main() {
Student s1 = new Student();
s1.stud_name = 'Maxsu';
s1.stud_age = 0;
print(s1.stud_name);
print(s1.stud_age);
}
4.访问修饰
Dart 没有访问修饰符(public, protected, private),在 Dart 类中,默认的访问修饰符是公开的(即 public)
如果要使用私有属性(private),需要同时满足以下两个条件:
- 属性或方法以_(下划线)开头
- 只有把类单独抽离出去,私有属性和方法才起作用
class Person {
String name;
// 声明私有属性
num _age = 8;
Person(this.name);
num getAge() {
return this._age;
}
}
import 'lib/Person.dart';
void main() {
Person p = new Person('Rogers');
print(p.name); // Rogers
// 访问私有属性
// print(p._age); // The getter '_age' isn't defined for the type 'Person'.
print(p.getAge()); // 8
}
5.继承
一个类使用extends关键字从另一个类继承,子类继承除父类的构造函数之外的所有属性和方法。
示例
class Shape {
void cal_area() {
print("calling calc area defined in the Shape class");
}
}
class Circle extends Shape {}
void main() {
var obj = new Circle();
obj.cal_area();
}
6.方法重写
方法重写是子类在其父类中重新定义方法的机制。以下示例说明了相同的情况:
class Parent {
void m1(int a){ print("value of a ${a}");}
}
class Child extends Parent {
@override
void m1(int b) {
print("value of b ${b}");
}
}
void main() {
Child c = new Child();
c.m1(12);
}
重写方法时,函数参数的数量和类型必须匹配。如果参数数量或其数据类型不匹配,Dart编译器将抛出错误。
7.static
static关键字可以应用于类的数据成员,即字段和方法。静态变量保留其值,直到程序完成执行。静态成员由类名引用。
示例
class StaticMem {
static int num;
static disp() {
print("The value of num is ${StaticMem.num}") ;
}
}
void main() {
StaticMem.num = 12;
// initialize the static variable }
StaticMem.disp();
// invoke the static method
}
执行上面示例代码,得到以下结果 -
执行上面示例代码,得到以下结果 -
8.super
supper关键字可用于引用超类的变量,属性或方法等等。
class Parent {
String msg = "message variable from the parent class";
void m1(int a){ print("value of a ${a}");}
}
class Child extends Parent {
@override
void m1(int b) {
print("value of b ${b}");
super.m1(13);
print("${super.msg}") ;
}
}
void main() {
Child c = new Child();
c.m1(12);
}
9.抽象类
使用 abstract 修饰符来定义抽象类
abstract class Doer {
// 定义实例变量和方法 ...
void doSomething(); // 定义一个抽象方法。
}
class EffectiveDoer extends Doer {
void doSomething() {
// 提供方法实现,所以这里的方法就不是抽象方法了...
}
}
10.接口
通过 implements 实现多个接口
abstract class A {
late String name;
printA();
}
abstract class B {
printB();
}
class C implements A, B {
@override
late String name;
@override
printA() {
print('printA');
}
@override
printB() {
print('printB');
}
}
void main() {
C c = new C();
c.printA(); // printA
c.printB(); // printB
}
11.mixins
在 Dart 中本不可以实现多继承,利用 mixins 可实现类似多继承的功能。
- 作为 mixins 的类只能继承自 Object,不能继承其他类。
- 作为 mixins 的类不能有构造函数。
- 一个类可以 mixins 多个 mixins 类。
- mixins 绝不是继承,也不是接口,而是一种全新的特性。
class A {
String info="this is A";
void printA(){
print("A");
}
}
class B {
void printB(){
print("B");
}
}
class Person {
String name;
num age;
Person(this.name, this.age);
printInfo() {
print('${this.name}----${this.age}');
}
void run() {
print("Person Run");
}
}
// 使用 with 关键字实现 mixins
class C with A,B{}
// 既继承自 Person 又 mixins A 和 B,with 后跟的类有顺序之分,后类的方法会覆盖前类的方法
class D extends Person with A, B {
C(String name, num age) : super(name, age);
}
void main(){
var c=new C();
c.printA(); // A
c.printB(); // B
print(c.info); // this is A
var D = new C('张三', 20);
D.printInfo(); // 张三----20
D.run(); // B Run
}
mixins 的类型
mixins的类型就是其超类的子类型。
class A {
String info="this is A";
void printA(){
print("A");
}
}
class B {
void printB(){
print("B");
}
}
class C with A,B{}
void main(){
var c=new C();
print(c is C); //true
print(c is A); //true
print(c is B); //true
var a=new A();
print(a is Object); //true
}