Flutter Dart语言(03)面向对象总结

0 说明

该系列教程主要是为有一定语言基础 C/C++的程序员,快速学习一门新语言所采用的方法,属于在C/C++基础上扩展新语言的模式。

1 面向对象基础知识

说明:这里主要是基于C++面向对象着门语言,分析与其不同的部分,属于扩展式的学习模式。Dart语言本身也是面向对象的程序语言,

编码习惯说明:类的首字母要大写,方法首字母小写。

1.1 类的属性信息获取

在dart语言中,属性的获取一般可以用$符号直接获取,这里以Person类为例,具体描述如下:

Dart 复制代码
class Person {
  String name = 'wang';
  int age = 30;
  Person() {}

  void printInfo() {
    print("printInfo:");
    print("use \$ label");
    print("$name----$age");
    print("use this pointer");
    print("${this.name}----${this.age}");
  }
}

void main() {
  Person p = new Person();
  p.printInfo();

  print("Person's property:");
  print("name=${p.name},age=${p.age}");
}

命令执行后效果如下:

bash 复制代码
Connecting to VM Service at ws://127.0.0.1:63468/DKkz_f3A8aw=/ws
printInfo:
use $ label
wang----30
use this pointer
wang----30
Person's property:
name=wang,age=30

1.2 默认构造函数和命名构造函数

Dart中构造函数和C++中有所不同,并不是直接编写的构造函数有多个,而是一个默认构造函数和多个不同的命名构造函数,都可以用于对象的实例化,这里以Person类为例来解读默认构造函数和命名构造函数的差别,代码如下所示:

Dart 复制代码
class Person {
  String name = 'wang';
  int age = 30;

  //1 默认构造函数,当实例化一个对象时,会自动调用到该函数
  //一般编码模式:
  // Person(String name, int age) {
  //   this.name = name;
  //   this.age = age;
  // }
  //Dart语言中的简写模式,功能同上 注释:
  Person(this.name, this.age);

  //2 命名构造函数系列
  Person.now() {
    print("命名构造函数now");
  }
  Person.init(String name) {
    this.name = name;
    print("命名构造函数init:$name");
  }
  void printInfo() {
    print("$name---$age");
  }
}

void main() {
  Person p1 = new Person("wang", 30);
  Person p2 = new Person.now();
  Person p3 = new Person.init("li");

  p1.printInfo();
  p2.printInfo();
  p3.printInfo();
}

命令执行后效果如下:

bash 复制代码
Connecting to VM Service at ws://127.0.0.1:63783/veW3pzv-NKs=/ws
命名构造函数now
命名构造函数init:li
wang---30
wang---30
li---30

1.3 私有(private)属性和公有(public)属性

这里的private变量一般使" _ "开头,而非"_"开头的变量一般都是public变量。代码如下所示:

Dart 复制代码
class Person {
  //public属性
  String name = 'wang';

  //private属性
  //注意:必须在Person独立出的类文件中,才可以使private属性生效,否则无效
  int _age = 30;

  Person(this.name, this._age);
  void printInfo() {
    print("$name---$_age");
  }
}

void main() {
  Person p1 = new Person("wang", 30);
  p1._age = 30;
  p1.printInfo();
}

但要非常注意:直接在该文件中使用时private属性并不生效,即外界依然可以访问。只有在独立类文件Person中时才会生效。命令执行后效果如下:

bash 复制代码
Connecting to VM Service at ws://127.0.0.1:64385/Oid5LlpsVOg=/ws
wang---30

1.4 get和set 计算属性

get和set的使用,代码如下所示:

Dart 复制代码
class Circle {
  double radius;
  Circle(this.radius);

  //getter实现
  // double s() {
  //   return radius * radius * 3.14;
  // }
  //{等价于上面的方法实现}

  //setter实现
  set setRadius(double radius) {
    this.radius = radius;
  }
}

void main() {
  Circle c = new Circle(5.0);
  c.setRadius = 7.0;//setter的使用
  print("r=${c.radius},s=${c.s}");//getter的使用
}

命令执行后效果如下:

bash 复制代码
Connecting to VM Service at ws://127.0.0.1:64936/um9Y1LlW7Zc=/ws
r=7.0,s=153.86

1.5 初始化操作

构建对象前的初始化变量操作,在构造函数运行前赋值,代码如下所示:

Dart 复制代码
class Circle {
  double radius;
  //变量初始化操作。在构造函数运行前赋值
  Circle() : radius = 3.0 {
    print("r=${radius}");
  }

  get s {
    return this.radius * this.radius * 3.14;
  }
}

void main() {
  Circle c = new Circle();
  print("r=${c.radius},s=${c.s}");
}

命令执行后效果如下:

bash 复制代码
Connecting to VM Service at ws://127.0.0.1:65060/-cx0Vbd4POI=/ws
r=3.0
r=3.0,s=28.26

1.6 静态属性和静态方法

在Dart语言中一般使用static关键字来实现对变量和方法的描述。规则如下:

  • 静态方法中不能使用非静态方法和属性。
  • 非静态方法中可以使用静态方法和静态属性。

1.7 级联操作..

代码实现如下:

Dart 复制代码
class Person {
  String name = 'wang';
  int age = 30;

  Person(this.name, this.age);
  void printInfo() {
    print("$name---$age");
  }
}

void main() {
  Person p1 = new Person("wang", 30);

  //级联操作赋值
  p1
    ..name = "wang-5"
    ..age = 40
    ..printInfo();
}

命令执行后效果如下:

bash 复制代码
Connecting to VM Service at ws://127.0.0.1:50341/2a365aWm2oY=/ws
wang-5---40

常量构造函数

2 面向对象(继承、封装、多态)

2.1 抽象类和抽象方法

这里的描述主要针对相比C++语言的抽象类中不同之处,做对比学习,如下:

  • 抽象类主要用于定义标准。使用abstract关键字,抽象类中的抽象方法则无需再使用abstract关键字来声明。
  • 抽象类中如果只声明方法但不实现则是抽象方法,即没有方法体的方法就是抽象方法了。如果实现了的方法就是普通方法,即有方法体的方法。

抽象类及对应方法 代码实现如下:

Dart 复制代码
//抽象类
abstract class Animal {
  //抽象类中的抽象方法
  void eat();
  void run();

  //抽象类中的一般方法
  void printInfo() {
    print("class Animal info");
  }
}

2.2 implements接口

Dart中没有关键字来定义接口的关键字,普通类和抽象类都可以作为接口被实现,使用关键字implements关键字进行实现。如果实现的类是普通类,需要将普通类和抽象中的属性和方法全重写。抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现接口的方式,使用抽象类定义接口。这里要注意extends和implemnets的区别:在Dart语言中,继承抽象类 和实现抽象类是不同的,继承只会重写抽象类里的抽象方法,而实现会重写抽象类里的所有变量和方法。相关代码如下所示:

Dart 复制代码
//复用上一段代码的Animal。。。

//继承:只需要重写抽象类中的抽象方法
class Cat extends Animal {
  @override
  void eat() {
    // TODO: implement eat
  }

  @override
  void run() {
    // TODO: implement run
  }
}
//实现需要重写抽象类中的所有属性和方法
class Dog implements Animal {
  @override
  late String name;

  @override
  void eat() {
    // TODO: implement eat
  }

  @override
  void printInfo() {
    // TODO: implement printInfo
  }

  @override
  void run() {
    // TODO: implement run
  }

}

说明:如果是implements实现多个抽象类,则需要重写多个抽象类里的所有变量和方法。

2.3 mixins功能

主要用于实现类似多继承的功能。mixins的使用条件随着Dart的版本不断更新而有所改,mixins 3.X版本中约束条件如下:

  • 作为mixins的类只能继承自Object,不能继承其他类
  • 作为mixins的类不能有构造函数
  • 一个类可以mixins多个mixins类
  • mixins不是继承,也不是接口,而是一种全新的特性

代码实现如下所示:

Dart 复制代码
mixin A {
  //作为minxins类,只能继承自Object
  printA() {
    print("This is A");
  }

  run() {
    print("run A");
  }
}

mixin B {
  //作为minxins类,只能继承自Object
  printB() {
    print("This is B");
  }

  run() {
    print("run B");
  }
}

//C混合了A类和B类,类似继承,C的实例化类可以使用A类以及B类中的方法
class C with A, B {}

main() {
  C c = new C();
  c.printA();
  c.printB();
  c.run();
}

命令执行后效果如下:

bash 复制代码
Connecting to VM Service at ws://127.0.0.1:55350/kWXd6C3DRl4=/ws
This is A
This is B
run B

注意:如果有相同方法,则执行时主要依赖with的顺序。

同时这里也可以同时extends其他类基础上再使用mixins机制。关键代码如下所示:

Dart 复制代码
class C extends  X with A, B {}

2.4 late关键字

表示延迟初始化,不在对象初始化时初始化,而是在对象初始化之后。参考2.2 implements接口中demo。

2.5 identical函数

主要用于检查两个引用是否指向同一个对象。关于identicial的判定,参考如下代码:

Dart 复制代码
void main() {
  var o1 = new Object();
  var o2 = new Object();
  var isIdentical = identical(o1, o2); // false, diff objects.
  isIdentical = identical(o1, o1); // true, same object
  isIdentical =
      identical(const Object(), const Object()); // true, const canonicalizes
  isIdentical = identical([10], [10]); // false
  isIdentical = identical(const [10], const [10]); // true
  isIdentical = identical(const [1], const [2]); // false
}

2.6 常量构造函数

在Dart语言中,const一方面是内存开销减少,另一方面源自从常量组件是不应该改变的需求。常量构造函数需要满足以下约束:

  • 常量构造函数需要以const关键字修饰;
  • const构造函数必须用于成员变量都是final的类;
  • 如果实例化不加const修饰符,即使调用的是常量构造函数,实例化的对象也不是常量实例对象;
  • 实例化常量的构造函数的时候,多个地方创建这个对象,如果传入的值相同,只会保留一个对象;

这里给出一个demo,代码如下所示:

Dart 复制代码
class Rect {
  final int width;
  final int height;
  const Rect(
      {required this.width, required this.height}
  ); 
}

3 泛型

和C++基本一致,主要解决代码中数据类型的复用问题。一般都是泛型方法和泛型类中使用。

相关推荐
孤鸿玉12 小时前
Fluter InteractiveViewer 与ScrollView滑动冲突问题解决
flutter
叽哥19 小时前
Flutter Riverpod上手指南
android·flutter·ios
BG1 天前
Flutter 简仿Excel表格组件介绍
flutter
zhangmeng2 天前
FlutterBoost在iOS26真机运行崩溃问题
flutter·app·swift
恋猫de小郭2 天前
对于普通程序员来说 AI 是什么?AI 究竟用的是什么?
前端·flutter·ai编程
卡尔特斯2 天前
Flutter A GlobalKey was used multipletimes inside one widget'schild list.The ...
flutter
w_y_fan2 天前
Flutter 滚动组件总结
前端·flutter
醉过才知酒浓2 天前
Flutter Getx 的页面传参
flutter
火柴就是我3 天前
flutter 之真手势冲突处理
android·flutter
Speed1233 天前
`mockito` 的核心“打桩”规则
flutter·dart