Dart之类


重要的事情说三遍:
dart中每个类除了object外只能有一个基类(或者叫超类)
dart中每个类除了object外只能有一个基类(或者叫超类)
dart中每个类除了object外只能有一个基类(或者叫超类)

dart类的有一个不一样的地方就是类属性和类方法:

通常我们都是实例化对象后进行调用的,但是dart类本身也是一种对象,所以使用类名也可以直接进行调用
比如

class people{
	
	String name = "susuan";
	func(){
		print("hello world");
	}
}
main(){
	print(people.name);
	people.func();
}

1.定义一个类

注意 和C++不一样的是 类的{}后面不用加分号“;”

class Person {
  String name;
  int age;

  Person(String name, int age) {
    this.name = name;
    this.age = age;
  }
}

简化后可写成

class  Person {
    String name;
    int age;

    // 在构造方法中初始化成员变量时,可使用如下写法简化
    Person(this.name, this.age);
}

如需处理其他变量时,也可单独对其操作

class  Person {
    String name;
    int age;// 如需处理其他变量时,也可单独对其操作
    Person(this.name, this.age, String address){
        print(address);
    }
}

如需处理其他变量时,也可单独对其操作

class  Person {
    String name;
    int age;// 如需处理其他变量时,也可单独对其操作
    Person(this.name, this.age, String address){
        print(address);
    }
}

2.命名构造方法

不支持构造方法重载,但有命名构造方法
可以快速构建你想要的实例对象

class  Person {
    String userName;
    int age;

    Person(this.userName, this.age);

    // 命名构造方法
    Person.fromData(Map data) {
        this.userName = data['name'];
        this.age = data['age'];
    }
}

void  main() {
    // 使用命名构造方法创建对象
    var p = new Person.fromData({
        "name":"Bob",
        "age":19
    });
    print(p.userName);
}

3.可以通过实现 getters 和 setters 来创建附加属性

也就是直接使用 get 和 set 关键词:
可以通过实现 getters 和 setters 来创建附加属性,使用get关键字定义getter或访问器。Setter或存取器是使用set关键字定义的。可以通过显式定义setter/getter来覆盖默认值。getter没有参数并返回一个值,setter只有一个参数但不返回值。
set是用来创建对象使用,get是输出的时候用的。

class Rectangle {
   num left;
   num top;
   num width;
   num height;

   Rectangle(this.left, this.top, this.width, this.height);

   // 定义两个计算属性: right and bottom.
   num get right => left + width;
   set right(num value) => left = value - width;
   num get bottom => top + height;
   set bottom(num value) => top = value - height;
}

main() {
   var rect = new Rectangle(3, 4, 20, 15);
   assert(rect.left == 3);
   rect.right = 12;
   assert(rect.left == -8);
}

4.抽象类

书p53
抽象类实际就是一个接口,它是没有被实现的类。标识符是在class前加abstract就表明这个类是接口类。
接口中定义了未实现的方法告诉调用者,如果有类实现了这个接口,这个类(实现类)就拥有了接口所描述的功能
实现的时候用implements来继承接口类
注意:一个类可以实现多个接口类
抽象类是不能被实例化的,子类继承抽象类时,必须实现全部抽象方法。

abstract class Base {
    // 省略函数体即可定义抽象方法,不需加关键字
    func1();
    func2();
}

隐式接口(见53页)

实际上在Dart中,每个类都隐式的定义了一个包含所有实例成员的接口, 并且该类实现了这个接口

因此,如果我们想实现某个接口,但有又不想继承,则可以使用这种隐式接口机制。我们需要用到关键字implements

比如abstract的抽象类就可以放在新类中并使用implements进行实现

5.常量构造函数

如果想提供一个状态永远不变的对像,在Dart中,我们可以创建一个编译时常量对象,节省开销。

如果类提供的是状态不变的对象,那么可以把这些对象定义为编译时常量,实现这种功能可以定义const构造函数,且声明所有类的变量为final,如:

class ConstPoint {
  final num x;
  final num y;

  // 使用const修构造方法
  const ConstPoint(this.x, this.y);

  // 编译时常量对象,需使用const来创建对象

  // 常量如果是类级别的,请使用 static

  static final ConstPoint origin = const ConstPoint(0, 0);

}

void main() {
  print(ConstPoint.origin.x);
  print(ConstPoint.origin.y);
}

6、静态方法、静态常量

static 关键字来实现类级别的变量和函数、类中的常量需要使用static const声明

静态成员不能访问非静态成员、非静态成员可以访问静态成员

class People{
  static int age;
  static void Say(){
    print('hello!');
  }
}

void main(){
  People.age = 10;
  People.Say();
}

7.工厂构造方法

当我们需要创建一个新的对象或者从缓存中取一个对象时,工厂构造方法就派上了用场。

注意:工厂构造函数不能用 this。

class  Logger {
    final String name;

    // 创建一个静态Map做为缓存,
    static final Map<String, Logger> _cache =  <String, Logger>{};

    // 定义一个命名构造方法,用下划线"_"修饰,将构造方法私有化
    Logger._internal(this.name);

    // 使用关键字factory修饰类同名构造方法
    factory Logger(String name) {
        if (_cache.containsKey(name)) {
            return _cache[name];
        } else {
            // 调用命名构造方法创建新对象
            final logger= new  Logger._internal(name);
            _cache[name] = logger; // 存入缓存
            return logger;
        }
    }
}

void  main() {
    var uiLog = new Logger('UI');
    var eventLog = new Logger('event');
}

8.构造方法重定向

有时候一个构造方法会调动类中的其他构造方法来实例化,这时候可以使用构造方法重定向

class Point {
  num x;
  num y;

  // 同名构造方法
  Point(this.x, this.y);

  // 命名构造方法重定向到同名构造方法,中间使用一个冒号
  Point.alongXAxis(num x) : this(x, 0);
}

9.类的初始化列表

位于构造方法(而不是类前后)的小括号与大括号之间,在初始化列表之前需添加一个冒号

逗号分隔的一些赋值语句组成

适合用来初始化 final修饰的变量

调用是在构造方法之前

在这里插入图片描述

class  Point {
    final  num x;
    final  num y;
    final  num distance;

    Point(x, y)
        : x = x,
          y = y,
          distance =  sqrt(x * x + y * y){
             print("这是构造方法");
          }
}

void  main() {
    var p =  new  Point(2, 3);
    print(p.distance);
}

10.运算符重写

格式:
类的返回值类型 operator 运算符(参数列表){
函数体
}

class Point {
  int x;
  int y;

  Point(this.x, this.y);

  // 使用operator关键字,为该类重载"+"运算符
  Point operator +(Point p) {
    return new Point(this.x + p.x, this.y + p.y);
  }

  // 为该类重载"-"运算符
  Point operator -(Point p) {
    return new Point(this.x - p.x, this.y - p.y);
  }
}

void main(){
   var p1 = new Point(1,5);
   var p2 = new Point(7,10);

   // 重载运算符后,类可以使用“+”、“-” 运算符操作
   var p3 = p1 + p2;
   var p4 = p2 - p1;

   print("${p3.x}, ${p3.y}");
   print("${p4.x}, ${p4.y}");
}

11.类的单继承

书55页
类的单继承要注意的几个点:

  1. 关键之是extends
  2. 是单继承
  3. 构造方法是不会继承的
  4. 但是可以用super方法调用父类的构造方法(小技巧比如父类是people我们就可以把super等价想象成people即可,比如peolpe的构造函数是people(){} 对吧,那么子类调用父类的构造方法就是super(){}是不是很清楚)
  5. 可以重写父类的方法,@override可以省略起到注释重写方法的作用
class Father {
    myFunction(){
        // do something
    }
}

class Son extends Father {

    @override//重写父类的函数
    myFunction(){
        super.myFunction();
        // do something
    }
}

12.mixin 混入(用with作为关键字)

见书58页
当我们的继承父类不是同一个的,同时子类里面需要实现同样的功能时,Mixin显得尤为重要。
简单来说就是多继承
注意几个点:

  1. 多继承用wiht作为关键字
  2. mixin类中不能实现构造方法,否则不能被其他类进行混合
  3. dart中每个类除了object外只能有一个基类
  4. mixin类虽然不能定义构造方法,但是可以用默认构造方法进行实例化
  5. 如果不想实例化用mixin关键字代替class,同时也不能被继承
  6. mixin类本身可以继承,只是不能被继承,用on取代extends关键字进行继承

6.类的继承

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值