前言
mixin是dart2.1版本之后引入的新的語法特性,它和abstract功能差不多堤器,但是又比abstract有更多的特性颖御。接下來通過代碼來分別講述abstract和mixin的區(qū)別
1银酬、mixin可減少實現(xiàn)多繼承時的代碼冗余
假設有一個接口Walk嘲更,它有一個walk()方法,有一個類Person要實現(xiàn)該方法揩瞪,那么用abstract和mixin的實現(xiàn)分別為:
abstract實現(xiàn)
abstract class Walk {
walk(){}
}
// 如果是單繼承赋朦,那么這里為walk()的默認實現(xiàn)
class Animal extends Walk {
}
// 這里是實現(xiàn)接口,所以必須實現(xiàn)walk方法
class Person implements Walk{
@override
walk() {
}
}
abstract實現(xiàn)李破,它的語法特性為:
1宠哄、表示抽象類,即相當于c++中的接口嗤攻,通過implements實現(xiàn)接口毛嫉,一個類可以實現(xiàn)多個接口
2、它的方法既可以沒有函數(shù)體也可以有函數(shù)體妇菱,實現(xiàn)接口時必須要實現(xiàn)此方法否則報錯
3承粤、它也可以通過extends關鍵字實現(xiàn)單繼承(如果定義了默認方法,則子類不必實現(xiàn)該方法)
mixin實現(xiàn)
mixin Walk_mixin {
walk() {}
}
// 因為Walk_mixin有默認實現(xiàn)闯团,所以這里可以不實現(xiàn)
class PersonMixin with Walk_mixin {
}
1辛臊、通過with實現(xiàn)接口,一個類可以實現(xiàn)多個接口
2房交、它的方法既可以沒有函數(shù)體也可以有函數(shù)體彻舰,當接口有函數(shù)體時類在實現(xiàn)接口時可以選擇接口的默認實現(xiàn)
所以abstract修飾的類既可以表示接口又可以用于單繼承,而mixin只能用于接口候味,其次mixin在給出了方法的默認實現(xiàn)后實現(xiàn)該接口的類可以不用再次實現(xiàn)該方法刃唤,而abstract則必須要實現(xiàn)口猜,故mixin可以減少代碼冗余
mixin和abstract不可同時使用
2、mixin不支持單繼承
abstract關鍵字在被當做接口使用時是支持繼承的透揣,即通過extends關鍵字實現(xiàn)接口的繼承,代碼如下:
// 飛翔
abstract class Flying{
flying();
}
// 高空飛翔
abstract class HighFlying extends Flying{
highFlying();
}
class Bird implements HighFlying {
@override
flying() {
}
@override
highFlying() {
}
}
上面HighFlying繼承于Flying接口川抡,所以HighFlying相當于有了兩個方法flying()和highFlying()辐真。那么Bird實現(xiàn)了HighFlying則必須實現(xiàn)這兩個方法
mixin關鍵字繼承
mixin Flying_mixin{
flying() {
print("Flying_mixin");
}
}
// 高空飛翔
mixin HighFlying_mixin on Flying{
highFlying() {}
}
// 高空飛翔;此種方式實現(xiàn)接口的多繼承是錯誤的
mixin HighFlying_mixin2 on Flying_mixin{
highFlying();
}
class BirdMixin extends Flying with HighFlying_mixin {
@override
flying() {
}
}
1、mixin不可繼承mixin接口崖堤,但它可以通過on關鍵字來繼承abstract class修飾的接口(可以試驗侍咱,如果將上面的HighFlying_mixin2放開,那么會報錯)
2密幔、mixin通過on關鍵字繼承class修飾的類楔脯,那么此時with后面的mixin類必須要與當前類繼承自同一父類
即這里的BirdMixin和HighFlying_mixin都繼承于Flying抽象類。
3胯甩、mixin實現(xiàn)的多個接口中有同名的方法
還是以上面圖中的繼承關系為例昧廷,假設又多了一個接口MyFlying,它里面也有一個flying();方法偎箫,那么當某個類同時實現(xiàn)Flying和MyFlying兩個接口木柬,這個類的實例調(diào)用此方法時是調(diào)用的哪個接口的方法呢?根據(jù)官方的說法淹办,有兩種情況:
1眉枕、類未實現(xiàn)接口的這個方法,那么將采用距離with關鍵字越遠的類的實現(xiàn)方法
2怜森、類實現(xiàn)了接口的這個方法速挑,那么將采用自身的實現(xiàn)
mixin Flying_mixin{
flying() {
print("Flying_mixin");
}
}
mixin MyFlying_mixin {
flying() {
print("MyFlying ");
}
}
class HighBird with Flying_mixin,MyFlying_mixin{
@override
flying() {
super.flying();
print("調(diào)用的方法");
}
}
4、mixin也可以實現(xiàn)abstract class修飾的接口
假設某個mixin接口A實現(xiàn)了一個abstract class修飾的接口副硅,另外一個mixin接口B又通過on關鍵字繼承了該abstract class
修飾的接口姥宝,那么類在使用with關鍵字實現(xiàn)這兩個mixin接口時,A必須寫在B的前面想许,如下
abstract class HitTest{
hitTest(){
print("hitTest");
}
}
//GestureBinding
mixin GestureBinding implements HitTest{
@override
hitTest() {
}
}
//RendererBinding
mixin RendererBinding on HitTest{
@override
hitTest() {
// TODO: implement hitTest
return super.hitTest();
}
}
// 因為with關鍵字和implement關鍵字不能同時使用伶授,這里采用取巧的辦法,通過Mixin來實現(xiàn)接口流纹,然后
// 用with實現(xiàn)這個mixin接口糜烹,這樣相當于類間接實現(xiàn)了接口
class WidgetsFlutterBinding with GestureBinding,RendererBinding {
@override
hitTest() {
// TODO: implement hitTest
return super.hitTest();
}
}
前面說到mixin通過on關鍵字繼承abstract class修飾的接口時,當被類繼承時二者必須繼承于同一個類漱凝,否則會報錯疮蹦,這里給出了另外一種寫法,即如果mixin實現(xiàn)了abstract class修飾的類茸炒,那么就相當于默認實現(xiàn)了類也繼承了這個
abstract class修飾的類