一、基本概念
首先我們來了解兩個基本概念:實現繼承和接口繼承
(1)、實現繼承,表示一個類派生於一個基類型,並擁有該基類型的所有成員字段和函數。
(2)、接口繼承,表示一個類型只繼承了函數的簽名,沒有任何實現的代碼。在需要指定該類型具有某些可用的特性時,最好使用這種繼承。
注意,在C#中,不支持多重繼承,但一個類卻可以實現多個接口。同樣,結構總是派生於System.ValueType , 他們還可以派生於任意多個接口。
二、實現繼承。
(1)、我們先來看個例子。
using System;
namespace gosoa.com.cn
{
public class baseClass
{
public string getUrl()
{
return "www.gosoa.com.cn";
}
}
public class test : baseClass
{
static void Main()
{
test classOne=new test();
Console.WriteLine(classOne.getUrl());
}
}
}
在上面的例子中,public class test : baseClass 就是聲明了類test繼承自baseClass。這樣,在類test中也就具有了父類的方法,getUrl() 。在上例中輸出結果是 www.gosoa.com.cn
(2)、虛方法
把一個基類中的方法聲明為 virtual ,則該函數可以在任何派生類中重寫了。
在C#中,函數默認下不是虛擬的,需要顯式的聲明。但在java中,所有函數都是虛擬的。C#中,派生類的函數重寫另一個函數時,要使用override 關鍵字顯式的聲明。如果聲明了 override 函數,但在基類中如果沒有可以重寫的函數,編譯器就會報錯了。
注意,成員字段和靜態函數都不能聲明為 virtual ,因為這個概念只對類中的實例函數成員有意義。
我們來看個例子。
using System;
namespace gosoa.com.cn
{
public class baseClass
{
public virtual string getUrl()
{
return "cnblogs.com";
}
}
public class baseClass2:baseClass
{
public override string getUrl()
{
return "gosoa.com.cn";
}
}
public class test : baseClass2
{
public override string getUrl()
{
return "www.gosoa.com.cn";
}
static void Main()
{
test classOne=new test();
Console.WriteLine(classOne.getUrl());
}
}
}
本例的輸出結果是 www.gosoa.com.cn
(3)、隱藏方法。
在上例中,baseClass2類的getUrl()方法,如果沒有override 關鍵字,則baseClass2類的getUrl()方法就會隱藏基類的getUrl()方法。在編譯的時候,系統會給予警告。
(4)、調用函數的基本版本
還是看上一個例子,我們稍作修改,如下,
public class test : baseClass2
{
public override string getUrl()
{
string url="http://";
url+=base.getUrl();
return url;
}
static void Main()
{
test classOne=new test();
Console.WriteLine(classOne.getUrl());
}
}
我們來看url+=base.getUrl();這一句,base就是調用基類的意思,所以,本例的輸出結果是
http://gosoa.com.cn
(5)、抽象類和抽象方法。
C#允許把類聲明為 abstract ,抽象類不能實例化,抽象方法不沒有執行代碼。
我覺得抽象類和抽象方法沒有什麼用,一般我們用接口就可以了。搞不太明白C#中這個抽象類和抽象方法到底想用來干什麼。
(6)、密封類和密封方法。
如果把類聲明為 sealed 即標明該類不可以被繼承,如果是方法,則方法不可以被重寫。
(7)、派生類的構造方法。
在派生類中,構造方法是依次從基類中執行,最後到派生類本身的構造函數。
我們來看下面的例子:
using System;
namespace gosoa.com.cn
{
public class userBase
{
private string username;
public userBase()
{
Console.WriteLine( "I'm good men");
}
public userBase(string username)
{
this.username=username;
}
}
public class oneMen : userBase
{
public oneMen()
{
Console.WriteLine( "Yes , I'm very good !");
}
public oneMen(string username):base(username)
{
Console.WriteLine( username +" is a good men!");
}
public oneMen(string username,string hisWebSite):base(username)
{
Console.WriteLine( username +"'s webSite is "+hisWebSite);
}
public static void Main()
{
oneMen classOne=new oneMen();
//oneMen classTwo=new oneMen("pan");
//oneMen classThree=new oneMen("pan","www.gosoa.com.cn");
}
}
}
我們先聲明了一個 userBase 類,其有個私有成員變量,還有兩個構造函數。oneMen類派生自userBase 類。並且oneMen類有其自己的三個構造函數。public oneMen(string username):base(username)這個構造函數繼承了基類中的構造函數,間接的給基類中的私有字段賦值了。public oneMen(string username,string hisWebSite):base(username) 這個構造函數也繼承了基類的構造函數,在Main()函數中我們依次通過三種方式實例化oneMen類的時候,依次輸出的結果是
oneMen():
I'm good men
Yes , I'm very good !
oneMen("pan"):
pan is a good men!
oneMen("pan","www.gosoa.com.cn"):
pan’s 's webSite is www.gosoa.com.cn
希望通過這個例子讓大家了解到派生類的構造函數。