轉型
先說說繼承中的轉型
參考
https://www.cnblogs.com/fuyouchen/p/9363989.html
https://blog.csdn.net/limlimlim/article/details/7817677
https://www.cnblogs.com/qixuejia/p/4383068.html
向上轉型:將子類對象轉為父類對象。此處父類對象可以是接口
轉化后的父類對象具有父類所有方法,若方法被子類重寫override,那么實際調用時,調用的是重寫后的實現。
向下轉型:把父類對象轉為子類對象。
具有子類所有方法(包括重寫方法)+父類所有方法(被重寫的方法,按重寫的算。)
抽象中的繼承就是
向上轉型時,轉型后的對象只具有父類方法和子類對父類重新(實現)的方法。并沒有子類自帶的方法
協變和逆變
1.數組的協變
比如Animal 類 Dog繼承于他
Animal[] animalArray = new Dog[]{};
2.委托的協變和逆變
1.協變
//Dog:Animal
public delegate Animal GetAnimal();
static Dog GetDog(){return new Dog();}
//GetDog的返回值是Dog, Dog是Animal的子類;
//返回一個Dog肯定就相當于返回了一個Animal;
//所以下面對委托的賦值是有效的
GetAnimal getMethod = GetDog;
2.逆變
//Dog:Animal
public delegate void FeedDog(Dog target);
static void FeedAnimal(Animal target){}
//FeedAnimal接受的參數是animal,Dog是可以隱式轉變成Animal的
//所以委托可以安全的的做類型轉換
FeedDog feedDogMethod = FeedAnimal;
3.泛型委托的協變和逆變
image.png
1.協變
//Dog:Animal
public delegate T Find<out T>();
Find<Dog> findDog = ()=>new Dog();
//類型T從Dog向Animal轉變是協變
Find<Animal> findAnimal = findDog;
2.逆變
//Dog:Animal
public delegate void Feed<in T>(T target);
Feed<Animal> feedAnimalMethod = a=>Console.WriteLine(“Feed animal lambda”);
//因為在定義泛型委托時有in關鍵字,如果把in關鍵字去掉,編譯器會認為不合法
Feed<Dog> feedDogMethod = feedAnimalMethod;
接口跟這個類似
也就是說可以再不知道是否傳入有繼承關系時候泛型方法的向轉型,感覺和泛型約束能點出來差不多
也和傳參in out差不多
協變必須有返回值 且不能當做參數傳遞
image.png
逆變不能有返回值
image.png
可以在一定程度上簡化代碼吧
之前有高手指點看這個,本來是想優化下我之前的消息分發,因為泛型太多了,結果還是不行