1.解釋什么是抽象類(lèi)?
抽象類(lèi)是包含抽象方法的類(lèi)。那么什么又是抽象方法呢?抽象方法是沒(méi)有方法內容的,只有一個(gè)方法名和參數列表的方法。并以;結尾。為了標注他的與眾不同,在他的返回類(lèi)型前加abstract。并在class前加abstract。
簡(jiǎn)言之,由abstract修飾的方法和類(lèi)就是抽象的方法和類(lèi)。
2. 抽象類(lèi)的特點(diǎn)
① 抽象類(lèi)只能做父類(lèi)
② 抽象類(lèi)不能實(shí)例化,既不能用new來(lái)產(chǎn)生屬于抽象類(lèi)的對象
③ 抽象類(lèi)中除了抽象方法與普通方法不一樣以外,其他的部分和普通類(lèi)一樣。即抽象類(lèi)是普通類(lèi)的特例,他特殊只是有抽象方法。所以它里面可以有字段,屬性,普通方法。
3.抽象方法的特點(diǎn)
① 抽象方法是沒(méi)有方法內容的,只有一個(gè)方法名和參數列表的方法。并以;結尾。
② 在方法的返回類(lèi)型前加abstract
③ 抽象方法的內容由他的繼承類(lèi)根據繼承類(lèi)自身情況去寫(xiě)。重寫(xiě)這個(gè)方法時(shí)把abstract替換成override
注意:②③也是抽象屬性的定義和實(shí)現的方法
例如:
abstract class Class1 //定義抽象類(lèi)
{
protected string name;
protected abstract string Name { //定義抽象屬性 get; }
protected int age;
protected Class1()
{
name = "a";
age = 4;
}
protected abstract void A(); //定義抽象方法
}
class Class2:Class1 {
protected override string Nam
{
//實(shí)現抽象屬性get { return name; }
}
//實(shí)現方法時(shí)他的修飾符只能是范圍比父類(lèi)大,或是相同
protected override void A()
{
//實(shí)現抽象方法
Console.WriteLine("aaaaaaaaaaaa"); }
static void Main()
{
Class2 c = new Class2(); //正確,繼承類(lèi)可以定義自己的對象
Class1 c1=new Class1(); //錯誤,抽象類(lèi)不能定義自己的對象
Console.WriteLine(c.Name + "/n" + c.age);
c.A();
}
}
4.抽象類(lèi)里的普通方法如果也想在子類(lèi)中重寫(xiě),有兩種方法:
①在父類(lèi)普通方法的返回類(lèi)型前寫(xiě)virtual,這就告訴系統父類(lèi)這個(gè)方法是虛的方法,在子類(lèi)中重寫(xiě)該方法時(shí),在方法的返回類(lèi)型前可以什么也不寫(xiě),可以寫(xiě)new,也可以寫(xiě)override,然后子類(lèi)對象調用的方法就是在子類(lèi)中重寫(xiě)的方法。
②在父類(lèi)普通方法的返回類(lèi)型前什么都不寫(xiě),在子類(lèi)中重寫(xiě)該方法時(shí),在方法的返回類(lèi)型前可以什么也不寫(xiě),可以寫(xiě)new 。然后子類(lèi)對象調用的方法就是在子類(lèi)中重寫(xiě)的方法。
例如:
Abstract Class C
{
Protected abstract void A();
Protected void B(){
Console.WriteLine("bbbbb");
}
}
Class Class1:C
{
Protected void A() {
Console.WriteLine("aaaaaaa"); }
//Protected new void B(){ //正確}
//Protected override void B(){//正確}
Protected void B(){ //正確
Console.WriteLine("cccccccccccccc");
}
Static void Main() {
Class1 c1=new Class();
c.A(); 結果是:aaaaaaa
cccccccccccccc
c.B();
}
}
本文來(lái)自CSDN博客,轉載請標明出處:http://blog.csdn.net/wochuailimin/archive/2010/05/27/5629044.aspx
抽象類(lèi)和接口
抽象類(lèi)
類(lèi)中定義一些不含方法體的方法,它的方法體實(shí)現交給該類(lèi)的子類(lèi)根據自己的情況去實(shí)現,這樣的方法就是抽象方法,包含抽象方法的類(lèi)就是抽象類(lèi)。包含的抽象方法一個(gè)或多個(gè)。。
定義規則:
A. 抽象類(lèi)abstract修飾符來(lái)修飾,抽象方法用abstract來(lái)修飾
B. 抽象類(lèi)不能實(shí)例化(就是不能用new 去生成對象)
C. 抽象方法只需聲明,不需實(shí)現,
D. 抽象方法的類(lèi)必須聲明是抽象類(lèi),抽象類(lèi)的子類(lèi)必須覆蓋所有抽象方法后,才能被實(shí)例化,否則還是個(gè)抽象類(lèi)
abstract int aa(int a){} // 錯,有花括號,有實(shí)現部分,只不過(guò)為空、、、
正確的形式是:abstract int aa(int a);
抽象類(lèi)中抽象的方法,必須有關(guān)鍵字abstract
Vehicle v = new Car(); 正確
// 多態(tài)的體現,雖然抽象類(lèi)不可以創(chuàng )建對象,但是可以聲明一個(gè)變量,引用可以實(shí)現了抽象方法的的子類(lèi)對象,
子類(lèi)可以繼承抽象類(lèi)的屬性和方法(和普通類(lèi)繼承一樣),父類(lèi)抽象類(lèi)定義非private的成員變量,子類(lèi)可以繼承
接口(interface)
如果一個(gè)抽象類(lèi)的所有方法都是抽象的,就可以將這個(gè)類(lèi)用另外一種方式定義,用接口定義。
接口是抽象方法和常量值的集合,從本質(zhì)上講,接口是一種特殊的抽象類(lèi),其中沒(méi)有變量和方法實(shí)現。
定義:
public interface Runner{
int ID=1;
void run( );//// 不用abstract修飾??!這點(diǎn)和抽象類(lèi)不同。。要abstract也可以。
}
接口的特點(diǎn) :
u 在接口里只能聲明抽象方法。
u 接口只能聲明常量(final)
u 接口里只能聲明public的訪(fǎng)問(wèn)權限
int ID = 1; 相當于public static final int ID = 1;
接口定義中成員默認都是public訪(fǎng)問(wèn)類(lèi)型的,
變量默認都是public static final標識的,所以接口中定義的變量都是全局靜態(tài)常量
用法:
u 定義一個(gè)新接口,用extends繼承一個(gè)已有接口
u 定義一個(gè)類(lèi),用implements去實(shí)現一個(gè)接口中所有方法
u 定義一個(gè)抽象類(lèi),用implements去實(shí)現已有接口中的部分方法
u 可以實(shí)現多態(tài),例子如下
Fly[] flys = new Fly[2];
//可以實(shí)現多態(tài),只要實(shí)現了接口Fly的類(lèi)的對象都可以用flys中元素指向
flys[0] = new Plane();
flys[1] = new Bird();
但是只能直接訪(fǎng)問(wèn)該接口中的定義的方法,如果要調用另外一個(gè)接口中定義的方法,要進(jìn)行格式轉換
Sing s = new Plane();
s.sing();
if (s instanceof Fly){ // 飛機實(shí)現了Fly,和Sing兩個(gè)接口
((Fly)s).fly();
}
u 多個(gè)接口,用逗號分隔。例如:class A implements Fly, Sing{};
接口和抽象類(lèi)的區別?
1.從使用目的來(lái)看:
接口只是一個(gè)類(lèi)間的協(xié)議,它并沒(méi)有規定怎么去實(shí)現;
抽象類(lèi)可以重用你代碼使你的代碼更加簡(jiǎn)潔;
2.從行為來(lái)看:
接口可以多繼承,multi-implement
抽象類(lèi)不能實(shí)例化,必須子類(lèi)化才能實(shí)例化;
3.從屬性來(lái)看:
接口的屬性必須是常量;即public static final;
抽象類(lèi)的屬性沒(méi)有要求;
4.從方法來(lái)看:
接口的每個(gè)方法只是聲明不包括內容;
抽象類(lèi)的方法即可以是抽象的也可以不是抽象的;一般至少有一個(gè)是抽象的;
聯(lián)系客服