[Dart语法]第八章:类

类的定义

//定义一个Person的类
class Person {
  //属性
  String userName = 'Tobu';
  int age = 25;
  String blogAdress = 'https://www.cnblogs.com/TobuTobu';
  String userInfo = 'Hello, I am Tobu, A mobile developer';

  //方法
  _printInfo() {
    print('用户名字:$userName\n用户年龄:$age\n博客地址:$blogAdress\n用户简介:$userInfo');
  }
}

类的实例化

//实例化类
Person p = new Person();
//引用类的属性
print(p.userName);
print(p.age);
print(p.blogAdress);
print(p.userInfo);
print('------------------------------------------');
//引用类的方法
p._printInfo();
/*
Tobu
25
https://www.cnblogs.com/TobuTobu
Hello, I am Tobu, A mobile developer
------------------------------------------
用户名字:Tobu
用户年龄:25
博客地址:https://www.cnblogs.com/TobuTobu
用户简介:Hello, I am Tobu, A mobile developer
*/

构造函数

默认构造函数

//构造函数的内容在实例化的时候自动触发
class Person {
  //属性
  String userName;
  int age;
  String blogAdress;

  //默认构造函数
  Person(this.userName, this.age, this.blogAdress);
}
//-----------------------------------------------------
//声明变量
String userName = 'Tobu';
int age = 25;
String blogAdress = 'https://www.cnblogs.com/TobuTobu';
//实例化类
Person p = new Person(userName, age, blogAdress);
print(p.userName);
print(p.age);
print(p.blogAdress);
/*
Tobu
25
https://www.cnblogs.com/TobuTobu
*/

命名构造函数

class Person {
    //属性
    String blogAdress;
    //命名构造函数
    Person.blogAdress(this.blogAdress) {
        print('我的博客地址是:$blogAdress');
    }
}

main(List<String> args) {
  //声明变量
  String blogAdress = 'https://www.cnblogs.com/TobuTobu';
  //实例化类
  Person p1 = new Person.blogAdress(blogAdress);
}
/*
我的博客地址是:https://www.cnblogs.com/TobuTobu
*/

getter和setter

getter

//没用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;
    }
}

//用了getter,直接通过访问属性的方式访问_getArea
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;//修改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;
    }
}

静态成员和静态方法

main(List<String> args) {
    //非静态方法需要实例化类
    var p = new Person();
    p._printInfo();

    //静态方法无须实例化类
    Person._show();
}

class Person {
    static String name = 'Tobu'; //静态属性
    int age = 25; //非静态属性

    //静态方法	不能调用非静态成员(属性和方法)
    static _show() {
        print(name);
    }

    //非静态方法  可以访问静态成员和非静态成员
    _printInfo() {
        print(name); //访问静态属性 不能用this
        print(this.age); //访问非静态属性
        _show();//访问静态方法
    }
}

/*总结:
1:静态属性+静态方法=静态成员 | 非静态属性+非静态方法=非静态成员
2:静态方法不能调用非静态成员(属性和方法)
3:非静态方法可以访问静态成员和非静态成员
4:访问静态属性直接不需要this指针---print(name)
5:静态方法无需实例化类---Person.show()
*/

对象操作符

? 条件运算符

main(List<String> args) {
    //没实例化,p为空,不会报错 (p后面不加?此条会报错)
    Person p;
    p?._printInfo();

    //实例化,p1不为空,照常执行
    Person p1 = new Person();
    p1?._printInfo();
}

class Person {
    String name = 'Tobu';
    int age = 25;
    _printInfo() {
        print('$name\n$age');
    }
}

as 类型转换

var p;
p = '';
p = new Person();
(p as Person)._printInfo();//把p转换为Person

is 类型判断

Person p = new Person();
print(p is Object);//true

.. 级联操作

Person p = new Person('Tobu', 25);

p
    .._printInfo()
    ..name = 'Taco'
    ..age = 25
    .._printInfo();

// p._printInfo();
// p.name = 'Taco';
// p.age = 20;
// p._printInfo();

类的继承

Dart中的类的继承
1:子类使用extends关键词来继承父类
2:子类会继承父类里面可见的属性和方法,但是不会继承构造函数
3:子类能复写父类的方法 getter和setter

extends继承

main(List<String> args) {
    Web w = new Web();
    //子类访问父类可见的属性和方法
    print(w.name);
    w._printInfo();
}
//Web子类继承父类Person
class Web extends Person {}

class Person {
    String name = 'Tobu';
    int age = 25;
    _printInfo() {
        print('$name\n$age');
    }
}

super传参给父类构造函数

main(List<String> args) {
    Web w = new Web('Tobu', 23);
    print(w.name);
    w._printInfo();
}

class Web extends Person {
    //因为父类构造函数不可以直接被子类访问,通过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');
    }
}

子类的属性和方法

main(List<String> args) {
    Web w = new Web('Tobu', 23, '男');
    w._printInfo();
    w.run();
}

class Web extends Person {
    //子类的属性
    String sex;

    //因为父类构造函数不可以直接被子类访问,通过super把参数赋给父类的构造函数
    Web(String name, int age, String sex) : super(name, age) {
        this.sex = sex;
    }
   /*给父类命名构造函数传参
   Web(String name, int age, String sex) : super.now(name, age) {
        this.sex = sex;
    }
    */

    //子类的方法
    run() {
        print('$name\n$age\n$sex');
    }
}

class Person {
    String name;
    int age;
    Person(this.name, this.age);
    _printInfo() {
        print('$name\n$age');
    }
}

@override覆写(重写)父类方法

main(List<String> args) {
    Web w = new Web('Tobu', 23);
    w._printInfo();//优先子类自己的方法(重写父类的方法)
}

class Web extends Person {
    Web(String name, int age) : super(name, age);

    //重写父类方法
    @override
    _printInfo() {
        print('$name');
    }
}

class Person {
    String name;
    int age;
    Person(this.name, this.age);
    _printInfo() {
        print('$name\n$age');
    }
}

抽象类

abstract抽象类

Dart中抽象类:Dart抽象类主要用于定义标准,子类可以继承抽象类,也可以实现抽象类接口。

1、抽象类通过abstract关键字来定义

2、Dart中的抽象方法不能用abstract声明,没有方法体的方法称为抽象方法如:eat();

3、如果子类继承抽象类必须得实现里面的抽象方法

4、如果把抽象类当做接口实现的话必须得实现抽象类里面定义的所有属性和方法。

5、抽象类不能被实例化,只有继承它的子类可以。

Dart中的多态

1、允许将子类类型的指针赋值给父类类型的指针,同一个函数调用会有不同的执行效果。

2、子类的实例赋值给父类的引用

3、多态就是父类定义一个方法不去实现,让继承他的子类去实现,每个子类有不同的表现。

如下面的抽象类例子就是多态的表现。

//定义一个抽象类
abstract class Animal {
  //抽象方法 不实现方法体就是抽象方法
  eat();
  run();

  //非抽象方法
  printInfo() {
    print('我是抽象类里面的普通方法');
  }
}

//子类Dog继承抽象父类Animal
class Dog extends Animal {
  @override
  eat() {
    print('小狗在吃骨头');
  }

  @override
  run() {
    // TODO: implement run
    print('小狗在跑');
  }
}

//子类Cat继承抽象父类Animal
class Cat extends Animal {
  @override
  eat() {
    print('小猫在吃鱼');
  }

  @override
  run() {
    // TODO: implement run
    print('小猫在跑');
  }
}

main() {
  //实例化类
  Dog d = new Dog();
  d.eat();
  d.run();

  //实例化类
  Cat c = new Cat();
  c.eat();
  c.run();
}

implements接口

1、普通类或抽象类都可以作为接口被实现

2、使用implements关键字进行实现

3、如果实现的是普通类,会将普通类和抽象中的属性和方法全部需要重写一遍

4、因为抽象类可以定义抽象方法,普通类不行,所以一般使用抽象类定义接口

 abstract class Db {
  String uri;
  add(String data);
  save();
  delete();
}

class Mysql implements Db {
  @override
  add(String data) {
    print('这是Mysql的add方法' + 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('增加的数据');
}

extends和implements的区别

1、如果复用抽象类里面的方法,并且要用抽象方法约束子类的话我们就用extends继承抽象类。

2、如果只是把抽象类当做标准的话我们就用Implements实现抽象类。

多接口

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混合(类似多继承,无约束)

1、作为mixins的类只能继承自object,不能继承其他类

2、作为mixins的类不能有构造函数

3、一个类可以mixins多个mixins类

4、mixins绝不是继承,也不是接口,而是一种全新的特性

class Person {
    String name;
    int age;
    Person(this.name, this.age);
    printInfo() {
        print('$name--------$age');
    }
}

abstract class A {
    printA();
}

abstract class B {
    printB();
}
//可以继承+mixins,继承的父类可以有构造函数,而mixins的不能有构造函数
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();
}

泛型

泛型方法
//没加泛型,
getData1(value) {
    return value;
}

//加了泛型,解决了传参和返回值类型不一致的问题
T getData<T>(T value) {
    return value;
}

main(List<String> args) {
    //没加类型检查
    getData('你好');

    //加入类型检查,只能输入指定类型的数据
    print(getData<String>('你好'));
}


//通俗理解:泛型就是解决类 接口 方法的复用性,以及对不特定数据类型的支持(类型校验)
泛型类
main(List<String> args) {
    //类型校验,只能增加String
    PrintClass p = new PrintClass<String>();
    p.add('Tobu');
    p.printInfo();

    //类型校验,只能增加int
    PrintClass p1 = new PrintClass<int>();
    p1.add(12);
    p1.printInfo();
}

//定义泛型类
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]);
        }
    }
}

泛型接口
//定义一个泛型接口
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) {
    //类型校验,value只能传入String
    FileCache f = new FileCache<String>();
    f.setByKey('index', 'file1');
}

posted @ 2021-02-15 16:05  漫游者杰特  阅读(268)  评论(0编辑  收藏  举报