Re: 虛擬函式的使用
※ 引述《atowng (阿棠)》之銘言:
: 書看了一陣子,還是不是很清楚這個東西該怎麼使用,我們說
: public class 父類別
: {
: public virtual int 屬性名稱
: {
: get{return 0;}
: }
: public virtual string 方法名稱();
: }
: public class 子類別 : 父類別
: {
: public new int 屬性名稱
: {
: get{return 1;}
: }
: public overrde string 方法名稱();
: }
: 一個是用"new"去取代原先父類別的成員,一個是使用"overrde"去覆寫父類別中的
: 虛擬成員。
: 這邊小弟就迷惑了:1.一個類別中可能有許多的成員,一個子類別去繼承了它,對於
: 父類別中的虛擬成員,子類別一定要覆寫嗎?
: 2.我們知道C#中還有抽象類別與介面,也是可以實現物件的多型,這三者之間該怎麼
: 運用適當。
Abstract class 主要用來表達有同樣的 property / method / event 的物件
並且這些物件間會有繼承的關係,EX:
+--正方形(Square)
+----四邊形---+--長方形(Rectangle)
| (Quadrangle)
形狀(Shape)----+----三角形-------+--等腰三角形(IsoscelesTriangle)
| (Triangle) |--正三角形(RegularTraiangle)
+----圓形
(Circle)
上面所有的有關形狀的 class 都由形狀這個 base abstract class 繼承而來
假設形狀這個 base class 有一個叫「算面積(CalcArea)」的 virtual function
這個「算面積()」的功能在形狀這個 class 裡絕對算不出來(因為沒長寬,也沒半徑)
但是你知道所有的形狀都可以算的出面積
於是你必需在所有繼承形狀的 class 裡實作這個「算面積()」
但是對於程式設計師來說,不管是什麼樣的形狀,只要繼承自形狀
都可以操作「形狀.算面積()」這個 base class 裡的 function 來求出它的面積
範例 code:
Shape a = new Rectangle(width, height);
Shape b = new RegularTriangle(base, height);
double aa = a.CalcArea();
double ba = b.CalcArea();
請注意上面 new 出來的物件是一個 Rectangle,一個 RegularTriagnle
但是都使用 Shape 這個 base class 做操作
再來談 interface,interface 和 abstract class 不同之處
在於它只是一種標記,只要有這種標記的 class,它就「必需」要「能執行」
該 interface 裡所宣告的所有的事項(包括 method, property, event)
也因此 interface 主要用來定立一些共通的操作界面
EX: 汽車喇叭可以按(Push)、販賣機的按鈕也可以按
但顯然我們不會用同一個 base class 來描述汽車喇叭和販賣機
另外一般來說,interface 給人的感覺會很像簡易版的抽像類別
但它有以下的不同點
1、interface 裡所有被宣告的 property、method、event 都是 public 的
abstract class 裡你可以有 private 和 protected 的相關宣告
2、interface 裡所有被宣告的 property、method 都必需要被繼承且實作才能使用
abstract class 你可以不用實作,因為你可以 new 一個 abstract class
雖然那沒什麼意義,但是你沒辦法直接 new 一個 interface
你必需 new 出繼承了該 interface 並實作的 class,
再從那上面取得(Query)該interface
3、interface 在 C# 裡可以多重繼承,class 只能單一繼承
上面看了一定霧殺殺,我用剛剛的 shape 來舉例子
像上面所有繼承自 Shape 的 class 都可以算面積
也因此我可以宣告一個 interface 叫 ICanCalcArea
裡面有一個 CalcArea(),代表含有這個 interface 的 class 都要可以執行
CalcArea() 這件工作
interface ICanCalcArea
{
double CalcArea();
}
也因此
public class Triangle() : ICanCalcArea { ..... }
public class Rectangle() : ICanCalcArea { ..... }
這代三角形和長方形的 class 都可以含有 ICanCalcArea 這個 interface
也就是說它們都可以算面積,那這樣和 abstract class 有什麼不一樣嗎?
我們再加上一個 class
public class Robot() : ICanCalcArea, IRobotAction { ..... }
一個和形狀扯不上邊的 class -> Robot(機器人) 也可以含有這個 interface
只要它被宣告含有這個 interface,管你是機器人還是火箭,它就是要能夠算面積
並且上面的宣告中,Robot這個 class 還含有另一個 IRobotAction 的 interface
這代表 Robot 這個 class 也必需要能執行 IRobotAction 裡宣告的工作
而 interface 的使用呼叫上也是有所不同的:
// new 出一個 Rectangle 物件 a
Rectangle a = new Rectangle(Width, Height);
// 從 a 上 query 出 ia 這個 ICanCalcArea 的 interface
ICanCalcArea ia = a as ICanCalcArea;
// 使用 query 出的 ICanCalcArea 的 interface 來執行 CalcArea()
if (ia != null)
double aa = ia.CalcArea();
那 Robot 呢?
Robot b = new Robot(....);
ICanCalcArea ib = b as ICanCalcArea;
if (ib != null)
double ba = ib.CalcArea();
// 接下來 Query 出 IRobotAction 來執行這個 interface 上的工作
IRobotAction irab = b as IRobotAction;
if (irab != null)
irab.自爆(); //執行 IRobotAction 裡的 method 自爆
先寫到這,有錯請幫忙訂正
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 122.116.82.44
※ 編輯: toki 來自: 122.116.82.44 (02/18 01:50)
→
02/18 16:44, , 1F
02/18 16:44, 1F
推
02/18 18:03, , 2F
02/18 18:03, 2F
推
02/19 16:41, , 3F
02/19 16:41, 3F
推
02/20 23:55, , 4F
02/20 23:55, 4F
討論串 (同標題文章)