之前有个技改任务,把司机学堂代码由原生转到Flutter。过程中遇到一个问题,学堂资料有pdf、视频、和图片,三种学习都会有几个共同的方法,比如学习进度更新、弹窗提示、完成接口调用等。在iOS中是用协议方法来实现,方法公用,那在Flutter中是否有相同的方法呢?
官方定义:
Mixins are a way of reusing a class’s code in multiple class hierarchies.
Mixins 是一种在多个类层次结构中重用类代码的方法。
官方文档翻译如下:
在面向对象的编程语言中,mixin(或mix-in)是一个类,其中包含供其他类使用的方法,而不必成为其他类的父类。 这些其他类如何获得对mixin方法的访问权限取决于语言。 混合素有时被描述为“包含”而不是“继承”。
Mixins鼓励代码重用,并且可用于避免多重继承可能导致的继承歧义,或解决语言中对多重继承的支持不足的问题。 混合也可以看作是已实现方法的接口。 此模式是强制执行依赖关系反转原理的示例。
看文档描述,和iOS的协议方法差不多,下面看下如何使用。
首先定义个Vehicle类,内部有个驾驶的方法。然后有2个类继承Vehicle。
// 汽车
class Vehicle {drive(){print("驾驶");}
}// 汽车A
class VehicleA extends Vehicle{}
// 汽车B
class VehicleB extends Vehicle {}
这2个类继承自Vehicle,所以都可以调用driver方法,这个和原生一样就简单过了。
VehicleA().drive();VehicleB().drive();
定义一个通用功能,放音乐,使用mixin来实现。
mixin MusicMixin{music(){print("放音乐");}
}
VehicleA和VehicleB都使用with关键字,混入MusicMixin,就可以调用听音乐方法。
// 汽车A
class VehicleA extends Vehicle with MusicMixin {}
// 汽车B
class VehicleB extends Vehicle with MusicMixin {}
调用方法:
VehicleA().music();
VehicleB().music();
和协议一样,在本类中也可以重写混入中的方法:
// 汽车A
class VehicleA extends Vehicle with MusicMixin {@overridemusic() {return super.music();}
}
汽车有可能还会有加油,充电,自动驾驶等功能。定义成mixin类。
mixin MusicMixin{music(){print("放音乐");}
}mixin GasMixin{gas(){print("加汽油");}
}mixin ChargeMixin{charge(){print("汽车充电");}
}
汽车A是油车所以需要加油,使用GasMixin。而汽车B是电车需要充电,使用ChargeMixin。
// 汽车A
class VehicleA extends Vehicle with MusicMixin, GasMixin {}
// 汽车B
class VehicleB extends Vehicle with MusicMixin, ChargeMixin{}
这样,A和B除了听音乐,还分别可以使用加油、充电的方法。
VehicleA().music();
VehicleA().gas();
VehicleB().music();
VehicleB().charge();
特定调价需要使用关键字on,后面加上限定的类。来表示该mixin只能这个类及其子类使用。
新增一个Plan类,创建一个PlanA集成自Plan类。
/ 飞机
class Plane{}// 飞机A
class PlaneA extends Plane with PlaneMixin{}
创建一个PlaneMixin的混入类,加上关键字on,表示该mixin只能Plan类及其子类使用。
mixin PlaneMixin on Plane {fly(){print("起飞");}
}
使用和上面一样,PlanA混入PlaneMixin,PlanA就可以使用fly方法了。
// 飞机A
class PlaneA extends Plane with PlaneMixin{}
PlaneA().fly();
其他类使用该mixin就会报错:

有可能混入多个mixin类,会有重复方法定义,会使用哪个mixin里的方法呢?
在MusicMixin和GasMixin中都定义一个aaa方法,并且打印不同日志。
mixin MusicMixin{music(){print("放音乐");}aaa(){print("Music aaa");}
}mixin GasMixin{gas(){print("加汽油");}aaa(){print("Gas aaa");}
}
还是原来的多个混入
// 汽车A
class VehicleA extends Vehicle with MusicMixin, GasMixin {}
调用VehicleA().aaa(); 会打印哪个日志呢?

打印了 GasMixin中的aaa方法。
再换下导入顺序看看:
// 汽车A
class VehicleA extends Vehicle with GasMixin, MusicMixin {}
调用VehicleA().aaa(); 会打印哪个日志呢?

打印了 MusicMixin中的aaa方法。
如果在本类中也有相同方法呢?
// 汽车A
class VehicleA extends Vehicle with GasMixin, MusicMixin {aaa(){print("VehicleA aaa");}
}
再次打印

就会调用本类的方法
多个方法相同的混入,后面导入的会覆盖前面导入的方法。如果本类也有相同方法,优先本类中的方法。
上一篇:足字成语大全集