Flutter学习笔记3 -- Dart语法学习扩展

本文是对Dart语法的一些补充内容

类的特性

  • 1.工厂构造函数
    普通构造函数会默认返回创建的对象,工厂构造函数需要手动返回一个对象
factory 类名(参数列表){
  ……
  return … 
}

工厂函数中不能使用this关键字,有时需要借助命名构造函数完成功能

void main(){
  var a = FactoryTest("haha");
  var b = FactoryTest("haha");
  var c = FactoryTest("xixi");
  print(a.hashCode);
  print(b.hashCode);
  print(c.hashCode);
  print(a == b);
}

class FactoryTest{
  String _name;
  static Map cache_map = new Map();

  factory FactoryTest(String name){ //工厂构造函数
    if(cache_map.containsKey(name)){
      return cache_map[name];
    }else{
      FactoryTest temp = FactoryTest.createInstance(name);
      cache_map[name] = temp;
      return temp;
    }
  }
  FactoryTest.createInstance(this._name);//命名构造函数
  void test(){
    print(_name);
  }
}
  • 2.setter和getter
    属性前加下划线,则只能在本模块中访问 例如: _name
    语法如下:
class Person {
  String? name;

  // setter
  set setName(String name) {
    this.name = name;
  }

  // getter
  String? get getName {
    return this.name;
  }
}
  • 3.继承
    Dart语言中使用extends作为继承关键字,子类会继承父类的数据和函数。
    注意:子类的构造函数需要调用父类的构造函数
  • 4.重写 @override
    例如可以重写toString方法修改对象的打印结果
class Person {
  String? name;

  @override
  String toString() {
    return "$name";
  }
}

操作符重写:Dart语言支持操作符的重写,常规的四则运算和比较运算符都可以进行重写,其中只有!=不可重写

  • 5.抽象类
    抽象abstract是面向对象中的一个非常重要的概念,通常用于描述父类拥有一种行为但无法给出细节实现,而需要通过子类来实现抽象的细节。这种情况下父类被定义为抽象类,子类继承父类后实现其中的抽象方法。
    子类继承抽象类后必须实现其中的抽象函数。
main(){
  var d = new Dog();
  d.name = "dog";
  d.eat();
  d.display();
}

abstract class Animal{
  String? name;  //数据
  void display(){  //普通函数
    print("名字是:${name}");
  }
  void eat(); //抽象函数
}

class Dog extends Animal{
  @override
  void eat() { //实现抽象函数
    print("eat");
  }
}

抽象类不能通过常规方式实例化,但是可以通过工厂函数等特殊方式来进行实例化

main() {
  var d = new Dog();
  d.name = "dog";
  d.eat();
  d.display();
}

abstract class Animal {
  String name = ""; //数据
  void display() {
    //普通函数
    print("名字是:${name}");
  }

  void eat(); //抽象函数

  Animal(){
  }
  factory Animal.create() {
    return Dog();
  }
}

class Dog extends Animal {
  @override
  void eat() {
    //实现抽象函数
    print("eat");
  }
}

  • 6.隐式接口
    Dart语言中没有接口(interface)的关键字,但是有实现(implements)关键字
    Dart中可以将类当做隐式接口直接使用,当需要使用接口时,可以声明类来代替
    当将一个类当做接口使用时,那么实现这个接口的类,必须实现这个接口中所有方法 (不一定要重写,父类实现也可以)
abstract class swimable{ //抽象类作为接口
  void swim();
}

class walkable{ //普通类作为接口
  void walk(){}
}

class Dog extends Animal implements swimable, walkable{
  @override
  void eat() {
    print("eat");
  }
  @override
  void swim() {
    print("swim");
  }
  @override
  void walk() {
    print("walk");
  }
}
  • 7.混入(mixin)
    使用混入的关键字是with,它的后面可以跟随一个或多个类名
    混入跟接口的区别在于,混入不需要实现接口
class Cat extends Mammal with Walker, Climber {}

如果不想类被实例化,可以使用抽象类+工厂方式定义

abstract class Walker {
  factory Walker._() => null; 
  void walk() { 
    print("I'm walking");
  }
}

如果Mixin的类和继承类,或者混入的类之间有相同的方法,在调用时会产生什么样的情况

mixin A {
  String getMessage() => 'A';
  void PrintSelf() {
    print("this is A");
  }
}

mixin B {
  String getMessage() => 'B';
  void PrintSelf() {
    print("this is B");
  }
}

class P {
  String getMessage() => 'P';
}

class AB extends P with A, B {}

class BA extends P with B, A {}

void main() {
  String result = '';
  AB ab = AB();
  result += ab.getMessage();
  BA ba = BA();
  result += ba.getMessage();
  print(result);
  ab.PrintSelf();
  ba.PrintSelf();
}

运行结果: BA
Dart中的Mixins通过创建一个新类来实现,该类将mixin的实现层叠在一个超类之上以创建一个新类 ,它不是“在超类中”,而是在超类的“顶部”
可以理解为处于Mixin结尾的类将前面的getMessage方法都覆盖(override)掉了
如果该类自己实现了此方法,优先自己的方法实现
优先级顺序:类内部实现 > 混入 > 继承

混入类如果希望被继承,可以使用class作为关键字替代mixin

创建混入类的时候,可以使用关键字on来确定某些类才能混入该混入类

泛型

main(){
  DataUtil d = new DataUtil();
  d.show(32);
}
class DataUtil{
  void show(T a) => print("数据:${a}");
}

此处也可以使用T extends num形式约束泛型只能输入num或num类型的子类

  • 9.external
    使用external实现方法的声明和方法的实现分离
    @patch完成方法的实现

枚举

enum创建枚举
可以查看所有元素和下标

main(List args) {
  print(Colors.values);
  print(Colors.gray.index);
}

enum Colors { red, gray, blue }

库的使用

Dart中默认情况下,一个dart文件就是一个模块(库文件)

    1. 使用系统的库
      Dart核心库不需要导入即可使用
      部分系统库使用时需要导入头文件
import 'dart:io';

如果使用系统库里面的方法跟自定义方法冲突,可以使用as关键字给引用文件取别名的方式来解决

import '../../02_函数使用/函数使用.dart' as mutils;

main(List args) {
  print(mutils.sum(1, 2));
}
  • 2.使用自定义的库
    导入库的路径
import 'utils/math_utils.dart';
  • 3.默认情况下导入一个库时,导入这个库中所有的内容
    show 执行要导入的内容
    hide 隐藏某个内容,导入其他内容
import '../../02_函数使用/函数使用.dart' show sum, mul;
import '../../02_函数使用/函数使用.dart' hide mul;
  • 4.当需要导入多个头文件,可以创建一个头文件,存放所有的头文件路径导入,之后引用这一个即可
  • 5.下划线是区分私有和公共的一种方式 属性或方法前面加下划线_即为私有属性方法
  • 6.使用第三方库
    第三方库查找: pub.dev
    1) 在需要的文件夹内创建pubspec.yaml文件,填充内容
name: coderwhy
description: a dart lib 
dependencies:
  http: ^0.13.3

dependencies根据需要依赖的第三方库找到
2)在终端工具中,进入刚才的路径,使用pub get指令,即可完成依赖拉取

  1. 在需要使用的文件中导入库
import 'package:http/http.dart';

你可能感兴趣的:(Flutter学习笔记3 -- Dart语法学习扩展)