抽象類與接口的不同,請大家參考再談抽象類與接口的區別,我也就不說了,那什麼時候選 抽象類, 又什麼時候選接口呢,好現在我來說一種情況。
現在我定義一個人的類,簡單起見,我略寫,如下:
public abstract class Person { public abstract float GetWeight(); }
好了,現在我又有一個歌唱家,顯然,他是一個人,好說繼承,如下:
public abstract class Singer : Person { public abstract void SingSong(); }
現在,我又有一個舞蹈家,顯然,這也簡單,他也是人,也好說繼承,如下:
public abstract class Dancer : Person { public abstract void Dance(); }
到現在一切都很好 ,也沒有任何的問題,可是,又來了一個人,他說他又會唱歌,又會跳舞,我叫這 個類為SingerDancer,好,我在定義一個類,
public abstract class SingerDancer : Singer, Dancer
可是這樣對嗎?C#裡面是不准許多繼承的,這是不允許編譯通過的,從另一個層面講,這個明顯的違 反了單一職責的原則,那這裡是不能用抽象類的。
我們再來一個例子:
鳥是可以飛的,這就沒有問題,好,先定義 一個類先,如下:
public abstract class Bird { public abstract void Fly(); }
在他之上,烏鴉,鴿子,好說,
public abstract class Crow : Bird { } public abstract class Pigeon : Bird { }
似乎都很好,沒有問題,可是,突然有一天,你在電視裡看到說,企鵝也是一種鳥,但是不會飛,這 下,你就不好辦了,如果,你把這個企鵝類也一樣的繼承Bird類嗎?
public abstract class Penguin : Bird { }
可是這樣就不好了,你的基類Bird明顯就這樣設計就不好,明顯就有了他不該有的方法。
基於上面的兩個例子,接口的威力也就顯示也來了,好重新上面的人的例子,用接口來做,
還是一個人類:
public abstract class Dancer : Person { public abstract void Dance(); }
對於歌唱家,我們可以這樣:
public interface ISing { void SingSong(); } public abstract class Singer : Person, ISing { public void SingSong() { } }
同樣,對於舞蹈家,我們可以這樣,
public interface IDance { void Dance(); } public abstract class Dancer : Person, IDance { public void Dance() { } }
對於一個SingerDancer就可以這樣比較好的做了,
public abstract class SingerDancer : Person, ISing, IDance { public void SingSong() { } public void Dance() { } }
對於Bird,同樣的,我們也可以這樣來做,下面我就直接給出示例來好了:
public abstract class Bird { } public interface IFly { void Fly(); } public abstract class Crow : Bird, IFly { } public abstract class Pigeon : Bird, IFly { } public abstract class Penguin : Bird { }
這樣是不是比較好的解決了上面由抽象類而帶來的問題呢。
那什麼時候用接口呢,也就是在進行行為建模的時候來用接口類,在自己類的固有屬性的時候就用抽 象類。