Flutter基础:Dart 面向对象

573 阅读3分钟

一、Dart 类和对象

  • 使用class关键字声明一个类;
  • 所有的对象都继承Object类 ;
  • Dart 中默认会生成gettersetter方法;
  • 属性和方法都通过.访问;
  • final修饰的属性必须定义初始值;
void main() {
  SSLPerson p = SSLPerson();
  p.age = 18;
  p.height = 180;
  p.run();
}

class SSLPerson {
  int? age;
  final String? name = "ssl";
  int? height;

  run() {
    print('age=$age name=$name height=$height');
  }
}

执行结果:
flutter: age=18 name=ssl height=180
  • dart 中用_修饰时代表私有属性
  • 同一文件中可以访问私有变量,不同文件不可以访问私有属性。

我们创建ssl_person.dart文件,在这里定义SSLPerson类,其中_age为私有属性:

class SSLPerson {
  int? _age;
  final String? name = "ssl";
  int? height;

  void run() {
    print('age=$_age name=$name height=$height');
  }
}

这时main.dart中就会因为不能访问私有属性而报错:

image.png

二、Dart 的构造函数

2.1 默认构造函数

dart 中定义完一个类后,就会有一个默认的构造函数类似下面这样:

SSLPerson(){};

2.2 自定义构造函数

如果我们自己定义一个构造函数,默认的就没有意义了
SSLPerson类中添加构造函数:

class SSLPerson {
  int? _age;
  final String? name = "ssl";
  int? _height;

  SSLPerson(int age, int height) {
    _age = age;
    _height = height;
  } 

  void run() {
    print('age=$_age name=$name height=$_height');
  }
}

这时我们再调用默认的构造函数就会报错:

image.png

下面的构造函数语法糖,可以达到上面相同的赋值效果:

SSLPerson(this._age,this._height);

2.3 final赋值 构造函数

我们第部分的时候说过,final修饰的属性必须有初始值,其实通过构造函数进行赋值也是可以的:

void main() {
  SSLPerson p = SSLPerson(18, 180,'ssl');
  p.run();
}

class SSLPerson {
  int? _age;
  final String? name;
  int? _height;

  SSLPerson(this._age,this._height,this.name);

  void run() {
    print('age=$_age name=$name height=$_height');
  }
}

执行结果:
flutter: age=18 name=ssl height=180

2.4 命名构造函数

我们在SSLPerson中再加一个命名构造函数:

void main() {
    SSLPerson p = SSLPerson.withName('ssl');
    p.run();
}

class SSLPerson {
  int? _age;
  final String? name;
  int? _height;

  SSLPerson(this._age,this._height,this.name);
  SSLPerson.withName(this.name);

  void run() {
    print('age=$_age name=$name height=$_height');
  }
}

执行结果:
flutter: age=null name=ssl height=null

2.5 常量对象 构造函数

当一个对象所有的成员属性都是 final 的时候,那么这个对象可以被创建为常量对象,使用const修饰构造函数。

void main() {
  SSLPerson p = SSLPerson(18, 180, 'ssl'); // 这个时候创建的p就是常量对象
}

class SSLPerson {
  final int _age;
  final String name;
  final int _height;

  const SSLPerson(this._age,this._height,this.name);
} 

三、Dart 的工厂构造&单例对象&初始化列表

3.1 工厂构造&单例对象

创建FactoryClass类,定义为单例,并在main.dart中调用。

void main() => factoryDemo();

void factoryDemo() {
  FactoryClass fac1 = FactoryClass();
  FactoryClass fac2 = FactoryClass();
  print(fac1 == fac2);
}

class FactoryClass {
  static FactoryClass? _instance;
  
  // 构造函数有返回值,必须用factory修饰
  factory FactoryClass() {
    return _instance ??= FactoryClass._init();
  }

  // 私有的命名构造函数!
  FactoryClass._init();
}

执行结果:
flutter: true

3.2 初始化列表

void main() => personDemo();

void personDemo() {
  Person p = Person("ssl", -18, -180);
}

//初始化列表。目的:1、给final变量赋值 2、校验传递的值
class Person {
  String name;
  int age;
  int _height;
  bool get isFree => _height < 110;

  Person(this.name, this.age, int h)
      : _height = h,
        assert(h >= 0),
        assert(age >= 0) {
    print('name:$name age:$age height:$_height');
  }
}

执行结果(报错):
[VERBOSE-2:ui_dart_state.cc(209)] Unhandled Exception: 
'package:flutter_oop/person.dart': 
Failed assertion: line 11 pos 16: 'h >= 0': is not true.

四、Dart 类方法和对象操作符

4.1 类方法

void main() => staticDemo();

void staticDemo() {
  StaticClass.count = 11;
  print(StaticClass.sum(20));
}

class StaticClass {
  // 静态属性
  static int count = 1;
  
  // 常量属性必须用static修饰
  static const String str = 'ssl';

  //静态方法
  static int sum(int a) {
    return a + count;
  }
}

执行结果:
flutter: 31

4.2 对象操作符

void main() => staticDemo();

void staticDemo() {
  var s1 = Object();
  s1 = StaticClass();
  
  // print((s1 as StaticClass).sum2(10)); // 强制转换
  
  if (s1 is StaticClass) { // 判断类型
    print(s1.sum2(10));
    print(s1..currentCount = 15..sum2(20)); // 链式编程
  }
}

class StaticClass {
  //实例属性
  int currentCount = 0;

  //实例方法
  int sum2(int a) {
    return currentCount + a;
  }
}

执行结果:
flutter: 10
flutter: Instance of 'StaticClass'

五、Dart 的继承

5.1 继承

  • Dart 中的继承,使用extends继承一个类;
  • 子类会继承除了构造方法以外的属性方法
  • Dart 是单继承的。
void main() => extendsDemo();

void extendsDemo() {
  Student st = Student();
  st.run();
  st.study();
  st.name = 'ssl';
  st.age = 18;
  print(st.isFree);
}

class Student extends Person {
  study() {
    print('认真学习!');
  }
  @override
  bool get isFree => age! < 18;
}

class Person {
  String? name;
  int? age;
  int? _height;
  bool get isFree => _height! < 110;
  run() {
    print('Person run......');
  }
}

执行结果:
flutter: Person run......
flutter: 认真学习!
flutter: false

5.2 多态

void extendsDemo() {
  Person st = Student();
  st.run();
  if (st is Student) {
    st.study();
    st.name = 'ssl';
    st.age = 18;
    print(st.isFree);
  } 
}

5.3 toString

toString类似OC中的description

void extendsDemo() {
  Person st = Student();
  if (st is Student) {
    print(st);
  }
}

class Student extends Person {
  @override
  String toString() {
    return "Student extends Person";
  }
}

执行结果:
flutter: Student extends Person

5.4 构造方法的继承

子类会继承父类的默认构造方法

void main() => extendsDemo();

void extendsDemo() {
  Person st = Student();
}

class Student extends Person {
  
}

class Person {
  Person() {
    print("person");
  }
}

执行结果:
flutter: person

父类的命名构造方法需要子类重写

void extendsDemo() {
  Person st = Student.withName('ssl');
  if (st is Student) {
    print(st.subName);
  }
} 

class Student extends Person {
  String? subName;
  Student.withName(String? name) : subName = name, super.withName(name);
}

class Person {
  Person.withName(String? name);
}

执行结果:
flutter: ssl

六、Dart 的抽象类和接口

6.1 抽象类的继承

抽象类:不能被实例化的类,使用abstract修饰

abstractDemo() {
  AbstractClass sub = SubClass();
  sub.sum(10, 20);
}

// 抽象类
abstract class AbstractClass {
  // 抽象方法
  int sum(int a, int b);
}

class SubClass extends AbstractClass {
  @override // 子类必须实现抽象方法
  int sum(int a, int b) {
    print('a + b = ${a+b}');
    return a + b;
  }
}

执行结果:
flutter: a + b = 30

6.2 抽象类的实现

类继承抽象类时不可以多继承,但是实现抽象类是可以实现多个

void main() => abstractDemo();

abstractDemo() {
  SubClass sub = SubClass();
  sub.sum(10, 20);
  sub.sum1(20, 30);
  sub.sum2(30, 40);
}

abstract class AbstractClass {
  // 这就是抽象方法
  int sum(int a, int b);
}
abstract class AbstractClass1 {
  // 这就是抽象方法
  int sum1(int a, int b);
}
abstract class AbstractClass2 {
  // 这就是抽象方法
  int sum2(int a, int b);
}

class SubClass implements AbstractClass,AbstractClass1,AbstractClass2 {
  @override
  int sum(int a, int b) {
    print('subClass..sum0');
    return 0;
  }

  @override
  int sum1(int a, int b) {
    print('subClass..sum1');
    return 1;
  }

  @override
  int sum2(int a, int b) {
    print('subClass..sum2');
    return 2;
  }
}

执行结果:
flutter: subClass..sum0
flutter: subClass..sum1
flutter: subClass..sum2

七、Dart Mixins混入

  • 混入, 说白了就是多继承;
  • 作为混入类,是不能实现构造方法的。
void main() => mixinDemo();

mixinDemo() {
  D d = D();
  d.a();
  d.b();
  d.c();
}

class A {
  a() => print('a.......');
}

class B {
  b() => print('b.......');
}

class C {
  c() => print('c.......');
}

class D extends A with B,C {

}

八、Dart 重载操作符

void main() => operatorDemo();

operatorDemo() {
  OperatorClass op1 = OperatorClass(18);
  OperatorClass op2 = OperatorClass(20);
  print(op1 > op2); // > 符号,正常来说是不可以使用的
}

class OperatorClass {
  int age;
  OperatorClass(this.age);
  // 重载了 > 这个操作符
  bool operator > (OperatorClass other) => age > other.age;
}

执行结果:
flutter: false