目錄:
【C#小知識】C#中一些易混淆概念總結--------數據類型存儲位置,方法調用,out和ref參數的使用
-----------------------------------------分割線----------------------------------------------
我筆記本上C#方面的知識基本上整理的差不多了,所以這個關於《C#小知識》的系列估計就要完結了,這個過程中謝謝大家一直來對於我的支持,你們給我的寶貴的意見對我幫助很大。
在介紹抽象類和抽象方法之前還是先提一下多態的基本概念。
其實在上一篇關於裡氏替換原則就已經說明了多態的精髓“子類對象可以替換父類對象的位置,而程序的功能不受影響”。還是來看一段代碼吧:
////// Create By:ZhiQiang /// Create Time:2014-2-9 /// class Person { //定義虛方法以備子類重寫,當子類替換父類對象的位置時,可以表現出多態 public virtual void Run() { Console.WriteLine("我是人,我會跑!"); } public virtual void Say() { Console.WriteLine("我是人,我會說話!"); } }
子類的代碼如下:
//定義Teacher類繼承Person
class Teacher:Person
{
public override void Run()
{
Console.WriteLine("我是老師,我必須慢速跑");
}
public override void Say()
{
Console.WriteLine("我是老師,我得說表揚的話!");
}
}
//定義Student類繼承Person
class Student : Person
{
//子類重寫了父類的虛方法
public override void Run()
{
Console.WriteLine("我是學生,我會加速跑!");
}
public override void Say()
{
Console.WriteLine("我是學生,我會說英語!");
}
}
下面需要一個實現多態的類,代碼如下:
//實現多態的類
class FeatureHuman
{
///
/// 這個方法就提現了多態,當傳入的是子類的對象的時候,p指向的是子類對象,就可以調用子類重寫父類方法後的方法
///
///父類或者子類對象
public void OutPutFeature(Person p)
{
p.Run();
p.Say();
}
}
主體代碼和實現多態的方法如下:
class Program
{
static void Main(string[] args)
{
//人的特點
Person p = new Person();
Program pro = new Program();
pro.OutPutFeature(p);
//學生的特點
Student s = new Student();
pro.OutPutFeature(s);
//老師的特點
Teacher t = new Teacher();
pro.OutPutFeature(t);
Console.ReadKey();
}
}
運行,打印結果如下:

這裡可以發現,我們outputFeature方法根據傳入的實體對象不同(父類變量指向了子類的對象),而打印出了不同人物的特點,這就是多態。
代碼圖解如下:

多態總結如下:

二,抽象類和抽象方法
在C#中使用abstract關鍵字修飾的類和方法,叫做抽象類和抽象方法。
1)抽象類中可以擁有沒抽象成員,為了繼承給他的子類調用 (抽象類就是為了定義抽象成員,繼承給子類去實現,同時子類也可以調用父類的非抽象成員)
abstract class Person
{
//private int nAge;
//abstract string strName;
//抽象類可以包含不抽象的成員,可以給繼承的子類使用
public void Say()
{
Console.WriteLine("我是父類,我是人!");
}
public virtual void Sing()
{
Console.WriteLine("我是父類,我是人,我可以唱歌!");
}
//Run的抽象方法
public abstract void Run();
}
2)抽象類中可以有virtual修飾的虛方法
如上面的代碼,在抽象類中定義了virtual修飾的方法,編譯通過。抽象類就是為了定義抽象成員,繼承給子類去實現,所以子類也可以實現抽象類中的虛方法。
3)抽象類不能實例化,因為有抽象成員,而抽象成員沒有方法體,如下圖,

4)抽象成員不能私有,如果私有子類沒有辦法訪問
我們可以在抽象類中定義私有成員,但是沒有意義。因為子類根本訪問不到這些私有成員,而抽象類本身也不能實例化,所以私有成員訪問不到。
5)子類必須重寫父類的抽象方法
在上面代碼的基礎上,我們定義一個Student類,繼承抽象類,但是不實現抽象類的抽象方法,編譯報錯。代碼如下:

6)在子類中沒有辦法通過base關鍵字調用父類抽象方法
原理同上,抽象類的抽象發放沒有實現語句,就算調用也沒有意義。但是可以使用base關鍵字調用非抽象方法,代碼如下:
class Program
{
static void Main(string[] args)
{
//Person p = new Person();
Student s = new Student();
s.Run();
Console.ReadLine();
}
}
class Student : Person
{
public override void Run()
{
base.Say();
Console.WriteLine("我是學生,繼承了父類,我可以跑!");
}
}
打印結果如下:

抽象類思維導圖總結如下:

抽象方法
1)抽象方法必須定義在抽象類中,
class Student : Person
{
public abstract void Swiming();
public override void Run()
{
base.Say();
Console.WriteLine("我是學生,繼承了父類,我可以跑!");
}
}
代碼編譯會報錯,如下圖:

2)抽象方法必須使用關鍵字修飾,示例代碼如下:
abstract class Person
{
//private int nAge;
//abstract string strName;
//抽象類可以包含不抽象的成員,可以給繼承的子類使用
public void Say()
{
Console.WriteLine("我是父類,我是人!");
}
public virtual void Sing()
{
Console.WriteLine("我是父類,我是人,我可以唱歌!");
}
//Run的抽象方法,不能有方法體,留給子類實現
public abstract void Run();
抽象方法思維導圖總結如下:

那麼什麼時候使用抽象類呢?
①子類必須重寫父類的方法(相當於定義了一個標准,規范)
②父類沒有必要實例化,就用抽象類
③抽象類是為了繼承,為了多態
最後來看一個示例代碼:
定義一個抽象類,其中包含抽象方法Run()
abstract class Person
{//Run的抽象方法,只要是繼承我的子類都要實現這個方法
public abstract void Run();
}
分別定義兩個子類,繼承抽象類Person
class Student : Person
{
//public abstract void Swiming();
public override void Run()
{
// base.Say();
Console.WriteLine("我是學生,繼承了父類,我可以跑!");
}
}
class Worker:Person
{
public override void Run()
{
Console.WriteLine("我是工人,繼承了父類,我每天在廠區跑!");
}
}
為了表現多態,我們編寫一個方法如下:
//該方法變現了多態,根據需要返回子類的對象
public static Person GetEntity(string str)
{
if(str=="學生")
{
return new Student();
}
else if(str=="工人")
{
return new Worker();
}
return null;
}
main函數中的代碼如下:
static void Main(string[] args)
{
//不直接實例化父類對象,只是聲明一個父類對象的變量來接收方法的返回值
Person p = GetEntity(Console.ReadLine());
p.Run();
Console.ReadLine();
}
運行,分別輸入“工人”和“學生”的打印結果如下:

到這裡這一部分的內容就結束了,希望大家多多提寶貴的意見。
畢業實習交流群:221376964。你也可以關注我的新浪微博進行交流。