Dart 用法

2023-10-07  本文已影响0人  Abner_XuanYuan

1、类的创建

//创建类
class CoustomClassOne {
  String name = "历史";
  int age = 18;

  void getClassInfo() {
    print("${this.name} -----  ${this.age}");
  }

  void setClassInfo(int age) {
    this.age = age;
  }
}
//使用
void main() {
  //普通使用
  var classOne = CoustomClassOne();
  classOne.getClassInfo();

  //级联调用
  // CoustomClassOne p = CoustomClassOne();
  // p
  //   ..name = "王五"
  //   ..age = 22
  //   .. getClassInfo();
}
1、默认初始化函数
class CustomClassTwo {
  // String name = "";
  // int age = 0;

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

  late String name;
  late int age;

  CustomClassTwo(this.name, this.age);
}
//使用
void main() {
  CustomClassTwo ppp = CustomClassTwo("张三", 30);
  print("name: ${ppp.name} ----- age: ${ppp.age}");
}
2、命名构造函数
class CustomClassThree {
  late String name;
  late int age;

   //初始化函数,只能有一个
  CustomClassThree(String name, int age);

  //命名初始化函数,可以有多个,但函数名不能相同
  CustomClassThree.setInfo(this.name, this.age);
  // CustomClassThree.setInfo(this.name);
  CustomClassThree.setInfoName(this.name);
  CustomClassThree.setInfoAge(this.age);
}
//使用
void main() {
  CustomClassThree three = CustomClassThree("wangwu", 44);
  print(three);
  CustomClassThree three2 = CustomClassThree.setInfo("liliu", 54);
  print(three2);
  CustomClassThree three3 = CustomClassThree.setInfoName("zhangsan");
  print(three3);
  CustomClassThree three4 = CustomClassThree.setInfoAge(32);
  print(three4);
}
3、重定向构造函数

有时构造函数的唯一目的是重定向到同一个类中的另一个构造函数。重定向构造函数的函数体为空,构造函数的调用在冒号 (:) 之后。

class Point {
  num x, y;

  // 类的主构造函数。
  Point(this.x, this.y);

  // 指向主构造函数
  Point.alongXAxis(num x) : this(x, 0);
}
4、常量构造函数

如果该类生成的对象是固定不变的,那么就可以把这些对象定义为编译时常量。为此,需要定义一个 const 构造函数,并且声明所有实例变量为 final。

class ImmutablePoint {
  static final ImmutablePoint origin = const ImmutablePoint(0, 0);
  final num x, y;
  const ImmutablePoint(this.x, this.y);
}
5、工厂构造函数

当执行构造函数并不总是创建这个类的一个新实例时,则使用 factory 关键字。

class Logger {
  final String name;
  bool mute = false;

  // 从命名的 _ 可以知,
  // _cache 是私有属性。
  static final Map<String, Logger> _cache =
      <String, Logger>{};

  factory Logger(String name) {
    if (_cache.containsKey(name)) {
      return _cache[name];
    } else {
      final logger = Logger._internal(name);
      _cache[name] = logger;
      return logger;
    }
  }

  Logger._internal(this.name);

  void log(String msg) {
    if (!mute) print(msg);
  }
}

注: 工厂构造函数无法访问 this
6、get set 方法
class Rectangle {
  num left, top, width, height;

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

  // 定义两个计算属性: right 和 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;
}
void main() {
  var rect = Rectangle(3, 4, 20, 15);
  assert(rect.left == 3);
  rect.right = 12;
  assert(rect.left == -8);
}
7、初始化时默认赋值
class CustomClassFive {
  late String name;
  late int age;
  CustomClassFive()
      : name = "张三",
        age = 22 {
    print("name: ${this.name} ----- age: ${this.age}");
  }
}
//使用
void main() {
  CustomClassFive five = CustomClassFive();
}

2、继承(extends)

1、静态变量和静态方法
class CustomClass {
  static String name = "立式";
  static int age = 20;
  // String name = "立式";
  // int age = 20;
  static void getInfo() {
    print("name:  ${name} -----  age:  ${age}");
  }
}
//使用
void main(List<String> args) {
  print(CustomClass.name);
  CustomClass.name = "王五";
  print(CustomClass.name);
  CustomClass.getInfo();
}
2、extends
//父类
class CustomSuperClass {
  late String name;
  late int age;
  CustomSuperClass(this.name, this.age);
  void printInfoFunc() {
    print("superClass: name: ${name} ----- age: ${age}");
  }
}
//子类
class CustomSubClass extends CustomSuperClass {
  late String sex;

  CustomSubClass(super.name, super.age, this.sex);
  @override
  void printInfoFunc() {
    super.printInfoFunc();
    // TODO: implement printInfoFunc
    print(
        "subClass override name: ${this.name} -- age: ${this.age} -- sex: ${this.sex}");
  }

  void run() {
    print(
        "subClass-- name: ${this.name} -- age: ${this.age} -- sex: ${this.sex}");
  }
}
//使用
void main(List<String> args) {
  CustomSubClass subClass = CustomSubClass("张三", 20, "male");
  subClass.printInfoFunc();
  subClass.run();
}
3、noSuchMethod()

当代码尝试使用不存在的方法或实例变量时,通过重写 noSuchMethod() 方法,来实现检测和应对处理。

class A {
  // 如果不重写 noSuchMethod,访问不存在的实例变量时会导致 NoSuchMethodError 错误。
  @override
  void noSuchMethod(Invocation invocation) {
    print('You tried to use a non-existent member: ' +
        '${invocation.memberName}');
  }
}

3、抽象类(abstract)

使用 abstract 修饰符来定义抽象类,抽象类不能实例化。抽象类通常用来定义接口以及部分实现。(如果希望抽象类能够被实例化,那么可以通过定义一个工厂构造函数来实现)

//抽象类
abstract class Animal {
  eat();
  run();
  void printInfo() {
    print("抽象类里面的普通方法");
  }
}
//实现类
class Dog extends Animal {
  @override
  eat() {
    // TODO: implement eat
    print("狗东西");
    // throw UnimplementedError();
  }

  @override
  run() {
    // TODO: implement run
    print("四条腿");
    // throw UnimplementedError();
  }
}
class Cat extends Animal {
  @override
  eat() {
    // TODO: implement eat
    print("猫南北");
    // throw UnimplementedError();
  }

  @override
  run() {
    // TODO: implement run
    print("也是四条腿");
    // throw UnimplementedError();
  }
}
//使用
void main(List<String> args) {
  Dog d = Dog();
  // d.eat();
  // d.run();
  // d.printInfo();
  d
    ..eat()
    ..run()
    ..printInfo();
  Cat c = Cat();
  // c.eat();
  // c.run();
  // c.printInfo();
  c
    ..eat()
    ..run()
    ..printInfo();
}

4、接口(implements)

每个类都隐式的定义了一个接口,接口包含了该类所有的实例成员及其实现的接口。如果要创建一个 A 类,A 要支持 B 类的 API ,但是不需要继承 B 的实现,那么可以通过 A 实现 B 的接口。一个类可以通过 implements 关键字来实现一个或者多个接口,并实现每个接口要求的 API。

extends 和 implements 的区别
1、extends 用于继承;implements 用于定义接口。
2、extends 即要复用抽象类里面的方法,又要把抽象类当做标准来约束实用类;implements 只是把抽象类当做标准来约束实用类。

示例
构建数据库 mysql,mssql,mongodb

//抽象类
abstract class DataBase {
  late String baseURL;

  add(String obj);
  delete(String obj);
  update(String obj);
  read(String obj);
}
//mysql
class Mysql implements DataBase {
  @override
  late String baseURL;

  @override
  add(String obj) => print("Mysql 中增加数据" + obj);

  @override
  delete(String obj) => print("Mysql 中删除数据" + obj);

  @override
  read(String obj) => print("Mysql 中读取数据" + obj);

  @override
  update(String obj) => print("Mysql 中更改数据" + obj);
}
//mssql
class Mssql implements DataBase {
  @override
  late String baseURL;

  @override
  add(String obj) {
    // TODO: implement add
    // throw UnimplementedError();
    print("Mssql 中增加数据" + obj);
  }

  @override
  delete(String obj) {
    // TODO: implement delete
    // throw UnimplementedError();
    print("Mssql 中删除数据" + obj);
  }

  @override
  read(String obj) {
    // TODO: implement read
    // throw UnimplementedError();
    print("Mssql 中读取数据" + obj);
  }

  @override
  update(String obj) {
    // TODO: implement update
    // throw UnimplementedError();
    print("Mssql 中更改数据" + obj);
  }
}
//mongodb
class Mongodb implements DataBase {
  @override
  late String baseURL;

  @override
  add(String obj) => print("Mongodb 中增加数据" + obj);

  @override
  delete(String obj) => print("Mongodb 中删除数据" + obj);

  @override
  read(String obj) => print("Mongodb 中读取数据" + obj);

  @override
  update(String obj) => print("Mongodb 中更改数据" + obj);

  Mongodb(this.baseURL);
}
//使用
void main(List<String> args) {
  Mysql my = Mysql();
  my.baseURL = "MYXXXXXXXXXX";
  my.add(my.baseURL);
  my.delete(my.baseURL);
  my.update(my.baseURL);
  my.read(my.baseURL);

  Mssql ms = Mssql();
  ms.baseURL = "MSYYYYYYYYYY";
  ms.add(ms.baseURL);
  ms.delete(ms.baseURL);
  ms.update(ms.baseURL);
  ms.read(ms.baseURL);

  Mongodb mo = Mongodb("MOZZZZZZZZZZ");
  // mo.baseURL = "MOZZZZZZZZZZ";
  mo.add(mo.baseURL);
  mo.delete(mo.baseURL);
  mo.update(mo.baseURL);
  mo.read(mo.baseURL);
}

5、混入(mixins):实现类似多继承功能

为类添加功能。Mixin 是复用类代码的一种途径,复用的类可以在不同层级,之间可以不存在继承关系。通过 with 后面跟一个或多个混入的名称,来使用 Mixin。

实现条件:
1、只能继承自 object 类。
2、不能有构造函数。
3、一个类可以 mixins 多个 mixins 类。
4、mixins 不是继承,也不是接口,而是一种新特性。

示例

mixin ClassA {
  String infoA = "infoA";
  // printInfo(){
  //   print("printInfoA");
  // }
  printInfoA() => print("printInfoA");
}

mixin ClassB {
  String infoB = "infoB";
  printInfoB() => print("printInfoB");
}

class ClassC with ClassA, ClassB {}
void main(List<String> args) {
  var c = ClassC();
  print(c.infoA);
  print(c.printInfoA());
  print(c.infoB);
  print(c.printInfoB());
}
//继承
abstract class ClassD {
  String infoD = "infoD";
  printInfoD() => print("printInfoD");
}

class ClassC extends ClassD with ClassA, ClassB {}
void main(List<String> args) {
  var c = ClassC();
  print(c.infoA);
  print(c.printInfoA());
  print(c.infoB);
  print(c.printInfoB());
  print(c.infoD);
  print(c.printInfoD());
}

注:
1、若 with 后面的类 ClassA,ClassB 中有同名方法,则后加入的方法会执行。
2、可以使用 on 来指定哪些类可以使用 mixin 类。当声明一个 mixin 时,on 后面的类是使用这个 mixin 的父类约束。也就是说一个类若是要 with 这个 mixin,则这个类必须继承或实现这个 mixin 的父类约束。

mixin ClassE on ClassD {}

6、泛型

解决代码复用和类型校验。

1、泛型方法
T getRuturn<T>(T value) => value;
A getReturn1<A>(A value) => value;
AB getReturn2<AB>(AB value) => value;
fan getReturn3<fan>(fan value) => value;
b getReturn4<b>(b value) => value;

void main(List<String> args) {
  print(getRuturn<String>("哈哈哈"));
  print(getRuturn<int>(12345));
  print(getReturn1<String>("啊啊啊啊啊"));
  print(getReturn1<int>(98765655));
  print(getReturn2<String>("略略略..."));
  print(getReturn2<int>(6666666));
}

注:泛型符号可以用任何字母,但不可以是汉字、数字。
2、泛型类
//泛型类
class Mylist<T> {
  List l = <T>[];

  add(T value) => this.l.add(value);
  getList() => l;
}

void main(List<String> args) {
  Mylist l = Mylist();
  l.add("哈哈");
  l.add(12345);
  l.add(true);
  print(l.getList());
}

 //指定类型
void main(List<String> args) {
  Mylist l = Mylist<String>();
  l.add("123");
  l.add("456");
  l.add("789");
  print(l.getList());
}
3、泛型接口
//泛型接口
abstract class Cache<T> {
  getByKey(String key);
  setByKey(String key, T value);
}
//接口实现
class FileCache<T> implements Cache<T> {
  @override
  getByKey(String key) {
    // TODO: implement getByKey
    // throw UnimplementedError();
    print("FileCache -- getByKey -- key: " + key);
  }

  @override
  setByKey(String key, T value) {
    // TODO: implement setByKey
    // throw UnimplementedError();
    print("FileCache -- setByKey -- key: " + key + "value: ${value}");
  }
}

class MemoryCahce<T> implements Cache<T> {
  @override
  getByKey(String key) => print("MemoryCahce -- getByKey -- key: " + key);

  @override
  setByKey(String key, T value) =>
      print("MemoryCahce -- setByKey -- key: " + key + "value: ${value}");
}
void main(List<String> args) {
  FileCache file = FileCache();
  file.setByKey("哈哈", 12345);
  file.getByKey("咯咯咯");
  MemoryCahce mem = MemoryCahce<String>();
  mem.setByKey("嘻嘻", "jjjjj");
  mem.getByKey("叽叽叽");
}

7、异步

async:让方法异步执行。(如果要使用 async 关键字,则必须要使用 await 关键字)。
await:等待异步方法执行完成。

void main(List<String> args) async {
  var t = await testAsync();
  print(t);
}

//异步方法
testAsync() async {
  return "异步方法";
}
上一篇 下一篇

猜你喜欢

热点阅读