c#這種完全物件導向的程式語言提供了兩個重要的特性:繼承和多型
簡單定義
不同的物件對同一訊息作出不同的響應就是多型。
繼承是使用已存在的類的定義作為基礎建立新類的技術,新類的定義可以增加新的資料或新的功能,也可以用已存在的類的功能。
下面用例項來理解
1最簡單的繼承
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;
//在c#中新建控制台程式,將**拷貝過去就可以實現
class duck
}class realduck : duck
class xpduck : duck
class muduck : duck
class program
}
輸出結果:
上面就是乙個最簡單的繼承的例子,子類通過繼承父類,呼叫父類的方法,這樣不必在每個子類都去寫「swim()」這個方法
2.但是上面例子並沒有體現出多型,下面對例子進行修改
class duck
}class realduck : duck
}class xpduck : duck
}class muduck : duck
}class program
}
輸出結果:
這裡只是從效果上實現了多型,即實現了不同的物件對同一訊息作出不同的響應。
(以下先不用深究,只用理解了上面多型就夠了,具體new和override差別在後面6中單獨詳解)
在c#中:一般用override重寫,是指對父類中的虛方法(標記為override)或抽象方法(標記為abstract)進行重寫,實現新的功能,它必須與父類方法的簽名完全一致,而且與父類方法的可訪問性也必須一致
這裡的new方法,是指在子類中重新定義乙個簽名與父類的方法相同的方法,這個方法可以不用new修飾,只是編譯時會彈出乙個警告資訊:如果是有意隱藏,請使用關鍵字 new。
3.override重寫實現多型
這個例子將更加規範的實現多型
要注意兩點:
(1)父類要允許子類重寫,方法必須標識為virtual 或 abstract
(2)重寫方法 必須用override標識
class duck
}class realduck : duck
}class xpduck : duck
}class muduck : duck
}class program
}
輸出結果:
這樣我們就實現了乙個標準的多型。這裡用的是virtual,並沒有用abstract,下面介紹用abstract類
4 abstract重寫實現多型
這裡我只談談我個人的見解,上面那個例子並不完全貼切抽象類,為了更好理解抽象類的多型,我這裡舉另外乙個例子
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;
namespace 抽象類練習
}abstract class shape
class circle : shape
//建構函式,賦值圓半徑
public circle(double r)
public override double getarea()
}class square : shape
public double kuan
//建構函式,賦值矩形的長和寬
public square(double c, double k)
public override double getarea()}}
這個例子實現了計算圓和矩形的面積,多變形是父類,所有多邊形都能夠計算面積,但是計算面積的引數以及方法都不一樣,這樣我們把父類定義為抽象類,在子類中重寫計算方法
這裡我個人理解為什麼說這個用抽象類更貼切,因為這裡只有例項化了圓和矩形在計算面積時沒有公用部分,只有例項化之後,才能去計算面積,否則沒有意義,而抽象類語法中有乙個規定:抽象類不能被例項化(不能被new建立),所以這裡正好用抽象類
5 介面
介面是方法的抽象,如果不同的類有同樣的方法,那麼就應該考慮使用介面。這裡看其實介面和繼承差不多(這裡我就不做深入理解了,只是簡單使用一下介面),因為c#是單繼承,介面是解決c#裡面類可以同時繼承多個基類的問題。
namespace 介面練習
}class duck
}//抽象類中可以有非抽象方法。介面中則不能有實現方法
inte***ce ibark
class realduck : duck,ibark
}class xpduck : duck, ibark
}class muduck : duck
}
輸出結果:
這裡實現介面的時候和繼承不一樣,這裡通過宣告父類去指向子類物件,實現子類的功能。
介面就更像是一種能力,真鴨子和橡皮鴨子具有這種能力,所以實現了這個介面,而木頭鴨子就沒實現。
當然,這個其實也可以用繼承類來實現,但是因為已經繼承了duck類,所以這裡用了介面,介面和抽象類在很多地方都是很像的。這裡簡單區分一下介面和抽象類:
(1)abstract class 在c#語言中表示的是一種繼承關係,乙個類只能使用一次繼承關係。但是,乙個類卻可以實現多個inte***ce。
(2)在abstract class 中可以有自己的資料成員,也可以有非abstarct的成員方法,而在inte***ce中,只能夠有靜態的不能被修改的資料成員(也就是必須是static final的,不過在 inte***ce中一般不定義資料成員),所有的成員方法都是abstract的。
(3)abstract class和inte***ce所反映出的設計理念不同。其實abstract class表示的是"is-a"關係,inte***ce表示的是"like-a"關係。
(4)實現抽象類和介面的類必須實現其中的所有方法。抽象類中可以有非抽象方法。介面中則不能有實現方法。
(5)介面中的方法預設都是 public,abstract 型別的。
6 補充:c#中override重寫與new隱藏的區別
直接看**
class a //父類 }
class b : a }
class c : a }
public class program
}
輸出結果:
b繼承了a並對a類的方法進行了override重寫,c繼承了a對方法進行了重定義。
首先對比例項1和例項2,只要例項是b,無論定義是a還是b,都執行b的方法,這正是我們重寫想要的結果
而對比例項3和例項4,例項3中雖然例項了c,但是此時如果拿父類a來接收,那麼執行的就是父類的方法;僅當例項和定義都是c的時候,才會執行c
Java核心 介面 繼承和多型 多型
利用多型可以使程式具有良好的擴充套件性,並可以對所有類物件進行通用的處理。eg 定義乙個平行四邊形的類 parallelogram 在類中頂乙個 draw 方法。public class parallelogram 如果需要頂乙個繪製正方形的方法,通過定義乙個正方形類來處理正方形物件,會出現 冗餘的...
C 程式筆記 繼承和多型程式例項
函式重定義和派生類的繼承方式的例項 多重繼承下的派生類定義 分析與總結 多重繼承中的二義性問題 使用虛擬繼承和虛擬基類 知識點 派生類建構函式的宣告方法 派生類類名 形參列表 基類類名 基類初始化的形參列表 c 實現 person.件 include include using namespace ...
C 繼承和多型
在c 的物件導向的大家庭裡,我感覺繼承算是很重要的了,因為有很多的東西都是依賴於繼承和多型的,所以單獨的在第三篇部落格裡做總結和昇華。繼承在面相物件的地方是乙個很是重要的東西,可以說在物件導向的世界裡沒有了繼承就沒有了這麼多的東西,而沒有了多型就沒有了多彩的世界。類的繼承是最為普遍的事情了,可是類又...