5 抽象類別和封閉類
(1)封閉類又稱最終類,他的特點簡單:不能被繼承.要用sealed 修飾成為封閉類的類似通常是些不宜改動的.
(2)抽象方法,屬性,索引器
抽象方法格式:abstract 傳回型別 方法名(參數列表);
抽象屬性格式:abstrct 傳回型別 屬性名稱{get;set;}
索引器格式:abstrart 傳回型別 this[參數列表]{get;set;}
(3)抽象類別格式:
abstract class 類名{....}
雖然抽象類別不能產生對象,但是抽象類別完全可以有建構函式.
抽象類別是被繼承,所以不能和sealed聯用.
抽象類別的衍生類別可以是抽象類別,只有當衍生類別實現了所有抽象成員後,才演化為一個普通的類,這熟才能產生對象.
6 多態
(1)虛成員
關鍵字virtual修飾的成員陳為虛方法.虛成員有虛方法,虛屬性,虛索引器.
(2)重寫
重寫又是覆蓋,需要關鍵字override.如果重寫基類的virtual成員,衍生類別的同名成員沒有用 override就等於是預設了new關鍵字,就產生了一個新的成員,並且隱藏了(而不是重寫了)基類的同名的虛成員.
(3)多態
用基類類名聲名,但是用衍生類別建構函式建立.
(4)上溯
把衍生類別的對象當作基類的對象來處理,陳之為上溯.
程式3
using System;
using System.Collections.Generic;
using System.Text;
namespace school
{
class A
{
public void Func() //基類A非虛方法
{
Console.WriteLine("Func()in A");
}
public virtual void VO() //基類A虛方法
{
Console.WriteLine("BaseClass.VO()");
}
}
class B : A
{
public int j;
new public void Func() //衍生類別B隱藏基類非虛方法
{
j = 2;
Console.WriteLine("Func()inB,the new member="+j);
}
public override void VO() // 衍生類別B重寫基類虛方法
{
j = 2;
Console.WriteLine("VO()inB,the new member="+j);
}
public void FromBase() //衍生類別B調用基類虛方法
{
base.VO();
}
}
class C:B
{
public int k;
new public void Func() //衍生類別C隱藏基類非虛方法
{
k = 3;
Console.WriteLine("Func()inC,the new member=" + k);
}
public override void VO() //衍生類別C重寫基類虛方法
{
k = 3;
Console.WriteLine("VO()in C,the new member="+k);
}
}
class D : C
{
public int m;
new public void Func() //衍生類別D隱藏基類非虛方法
{
m = 4;
Console.WriteLine("Func()in D,the new member="+m);
}
new public virtual void VO() //衍生類別D隱藏基類虛方法
{
m = 4;
Console.WriteLine("Func()in D,the new member=" + m);
}
}
class E : D
{
public int n;
new public void Func() //衍生類別E隱藏基類虛方法
{
n = 5;
Console.WriteLine("Func()in E,the new member="+n);
}
public override void VO() //衍生類別E重寫基類虛方法
{
n = 5;
Console.WriteLine("VO()in E,the new member="+n);
}
}
class Test
{
public static void VirtualandOverride(A a)
{
a.Func();
a.VO();
}
public static void Main()
{
A aa = new A(); //基類對象 aa
A ab = new B(); //或者A ab=bb;用基類名聲明,用衍生類別建構函式
B bb = new B(); //衍生類別對象bb
ab.Func(); //調用非虛方法,輸出:“Func()in A”
bb.Func(); // 調用非虛方法,Func()in B,the new member=2
aa.VO(); // 輸出:“baseclass.VO()”
// Console .WriteLine("ab.j"); //錯誤:A中並不包含對J的定義。ab的類型是A?
ab.VO(); //調用虛方法,輸出:"VO()in B,the new member=2"
bb.VO(); // 調用虛方法,輸出:"VO()in B,the new member=2"
bb.FromBase (); //輸出:"BaseClass.VO()"
Console .WriteLine ("ab.Totring()"); //輸出:"B".ab的類型是B?
Console .WriteLine ("Testing");
VirtualandOverride (aa);
VirtualandOverride(ab);
A ac=new C();
VirtualandOverride(ab);
A ae=new E();
VirtualandOverride(ae);
}
}
}
程式3的輸出如下:
Func()in A
Func()in B,the new member=2
BaseClass.VO()
VO()in B,the new member=2
VO()in B,the new member=2
BaseClass.VO()
B
Testing
Func()in A
BaseClass.VO()
Func()in A
VO()in B,the new member=2
Func()in A
VO()in C,the new member=3
Func()in A
VO()in C,the new member=3
Func()in A
VO()in C,the new member=3
Test類中首先定義了測試方法VirtualandOverride,其作用是依次調用一個對象的非虛方法Func()和虛方法vo().
在Main方法中首先建立了基類對象aa,衍生類別B的對象bb,還用基類A生命,用衍生類別B建構函式建立的多態對象ab.
ab.Func();通過多態對象調用非虛方法(),調用A中定義的Func(),還是調用B中定義的Func,取決於ab的類型,ab是用A聲明的,所以調用A中的Func類型.
B ba;
ba=aa; //錯誤:無法將類型"A"隱式轉換為"B"
ba=ab; //錯誤:無法將類型"A"隱式轉換為"B"
ba=(B)aa; //編譯通過,執行中錯誤
ba=(B)ab; //正確
aa=ab; //正確
ab=aa; //正確
可以看出,通過多態對象的形式,基類對象使用了衍生類別的方法;這樣,基類在不用改變方法代碼的條件下,改進或擴張了自身的功能.
Console .WriteLine ("ab.Totring()"); Object.Tostring()方法是虛方法,在調用虛方法時,系統回把多態看成是衍生類別的案例.
Func()是非虛方法,程式按聲明的內容執行.VO()方法是重寫方法,是按照運行中的實際對象決定調用哪個類中的方法.多態對象調用虛方法時或虛方法重寫時,調用的是重寫方法.多態對象ac調用Func()和VO()方法,ac中VO是重寫的方法,override後的方法是可以再次被衍生類別使用,當一個衍生類別被多次重寫時,決定究竟是哪個方法被調用是由上溯決定的,這裡由A到B,由B到C,調用C中的重寫方法.
在D定義中VO並沒有使用override,而是使用Virtual new,這樣D中的VO就隱藏了積累中的VO方法,如果有以下:
D dd=new D();
dd.VO();輸出為:VO()in D,the new member=4
如果ae改為以下:D ae=new E();
de.vo()輸出為:VO() in E,the new member=5
7 結構和類的比較
結構是實值型別,結構對象存放在棧中;類是參考型別.類的對象存放在堆中.
參考書<<Visual c#.NET程式設計教程>>