FlutterBasics - extends 和 with/mixin

238 阅读2分钟

Flutter.png

extends(继承)

就像孩子继承父亲的姓氏和家产:

  • 只能有一个父亲(单继承)

  • 会继承父亲的所有特征和财产(属性和方法)

  • 可以覆盖(重写)父亲的一些特征

// 父类
class Animal {

  void eat() => print('吃东西');

}

// 子类

class Dog extends Animal {

  // 自动获得了 eat() 方法

  // 可以重写父类方法

  @override

  void eat() => print('啃骨头');

}

with(混入)

就像给人穿衣服:

  • 可以穿多件衣服(多个 mixin)

  • 每件衣服都给你增加一些功能

  • 后穿的衣服(后面的 mixin)会覆盖前面相同的功能

// 定义 mixin

mixin Swimming {

  void swim() => print('会游泳');

}

mixin Flying {

  void fly() => print('会飞');

}

// 使用 mixin

class Duck extends Animal with SwimmingFlying {

  // 同时具备:

  // - Animal 的 eat()

  // - Swimming 的 swim()

  // - Flying 的 fly()

}

主要区别

  1. 数量限制:

    • extends 只能继承一个类

    • with 可以混入多个 mixin

  2. 使用场景:

    • extends 用于表示"是一个"的关系(狗是一种动物)

    • with 用于表示"具有某种能力"的关系(鸭子具有游泳能力)

  3. 代码复用方式:

  • extends 是垂直方向的继承关系
  • with 是水平方向的功能扩展

mixin 是什么?

mixin 是一种代码复用的方式,可以理解为一组可以被重复使用的方法和属性的集合。就像是一个"功能包":

  • 你可以把常用的功能打包起来

  • 需要的时候用 with 关键字把这个"功能包"混入到任何类中

基本用法

// 定义一个 mixin
mixin Logger {
    void log(String msg) {
        print('日志: $msg');
    }
}
// 使用 mixin
class UserService with Logger {
    void saveUser() {
        log('保存用户信息');
        // 可以直接使用 mixin 中的方法  
    }
}

mixin 的特点

  • 可以包含方法和属性
mixin Musical {

  String instrument = '钢琴';  // 属性

  void playMusic() {          // 方法

    print('演奏$instrument');

  }

}
  • 可以使用多个 mixin
class SuperStar with SingerDancerActor {

    // 同时具备唱歌、跳舞、演戏的能力

}
  • 可以限制使用范围
// 只有 Performer 类或其子类才能使用这个 mixin

mixin VIP on Performer {

  void vipService() {

    print('享受 VIP 服务');

  }

}
  • 可以访问和重写方法
mixin A {

  void method() => print('A');

}

mixin B {

  void method() => print('B');

}

// C 会使用最后一个 mixin (B) 的 method 实现

class C with AB {

  // method() 输出 'B'

}

使用场景

  1. 共享功能:
mixin HttpHandler {

  Future<voidget(String url) { /* ... */ }

  Future<void> post(String url) { /* ... */ }

}

// 多个类都需要处理 HTTP 请求
class UserApi with HttpHandler /* ... */ }

class ProductApi with HttpHandler /* ... */ }
  1. 状态管理:
  mixin LoadingState {

  bool _isLoading = false;

  bool get isLoading => _isLoading;

  void startLoading() {

    _isLoading = true;

  }
  void stopLoading() {

    _isLoading = false;

  }
}

总的来说,mixin 是一种非常灵活的代码复用方式,特别适合那些需要在多个不相关的类之间共享功能的场景。它比继承更灵活,因为可以混入多个 mixin,而且不会产生复杂的继承层次结构。