在C#中有許多種修飾詞,
public, private, protect, virtual, new, partial, sealed, internal, readonly, volitile, unsafe…等,
修飾詞又依據功能分成多種,而有些修飾詞在不同情況下有不同的功能,
以下將介紹幾種修飾詞:
例如:Object obj = new Object(),
但當new當作修飾詞使用時,
它代表的意思是用來區別該成員與基底類別相同名稱的成員不同,
如果不使用new可以將該同名的成員重新命名,但會比較麻煩。
雖然說可以不用特別使用new修飾詞來取代,
但沒使用new編譯時會出現警告,
所以正確來說new可用來隱藏這些警告,
更加明確的說明了該衍伸類別所定義的同名成員覆蓋了基底類別的成員,
另外,new不僅可用在成員與方法,也可用在class。
範例:
輸出:
下圖為未加入new修飾詞時所出現的警告
public, private, protect, virtual, new, partial, sealed, internal, readonly, volitile, unsafe…等,
修飾詞又依據功能分成多種,而有些修飾詞在不同情況下有不同的功能,
以下將介紹幾種修飾詞:
new
new一般都是用來當作產生一個物件實體的動作,例如:Object obj = new Object(),
但當new當作修飾詞使用時,
它代表的意思是用來區別該成員與基底類別相同名稱的成員不同,
如果不使用new可以將該同名的成員重新命名,但會比較麻煩。
雖然說可以不用特別使用new修飾詞來取代,
但沒使用new編譯時會出現警告,
所以正確來說new可用來隱藏這些警告,
更加明確的說明了該衍伸類別所定義的同名成員覆蓋了基底類別的成員,
另外,new不僅可用在成員與方法,也可用在class。
範例:
using System;
namespace ConsoleAutoTesting
{
class Program
{
static void Main(string[] args)
{
(new Concrete()).Hello();
(new Base()).Hello();
Console.ReadKey();
}
}
public class Base
{
public int X = 10;
public void Hello()
{
Console.WriteLine("Hello Base");
}
}
public class Concrete : Base
{
public new void Hello()
{
Console.WriteLine("Hello Concrete");
}
}
}
輸出:
下圖為未加入new修飾詞時所出現的警告
virtual
virtual修飾詞用來表示該方法或屬性可以在衍伸類別中被覆寫,
在衍伸類別覆寫時,加上Base.方法()即可使用基底類別的方法,
然後再此敘述前後加入覆寫的程式碼,
只有宣告為virtual的方法或屬性才可以override。
使用override代表將基底類別同名稱的成員覆蓋掉,
在該延伸類別中只有唯一名稱的成員。
在衍伸類別覆寫時,加上Base.方法()即可使用基底類別的方法,
然後再此敘述前後加入覆寫的程式碼,
只有宣告為virtual的方法或屬性才可以override。
使用override代表將基底類別同名稱的成員覆蓋掉,
在該延伸類別中只有唯一名稱的成員。
範例
using System;
namespace ConsoleAutoTesting
{
class Program
{
static void Main(string[] args)
{
(new Concrete()).Hello();
Console.ReadKey();
}
}
public abstract class Base
{
public virtual int X { get; set; }
public virtual void Hello()
{
Console.WriteLine("Hello Base");
}
}
public class Concrete : Base
{
public override void Hello()
{
base.Hello();
Console.WriteLine("Hello Concrete");
}
}
}
virtual不可用於靜態屬性
接著來看看new與virtual使用時的差異,
從下面的範例執行結果就可以看到使用new來覆寫基底類別的方法,
當降轉成基底類別呼叫該方法時,
會呼叫到基底類別的方法,而不會呼叫延伸類別所覆寫的方法,
這種情況下反而使用override會正常。
因為對A來說同時存在兩個相同名稱的方法,
基底類別的Echo與自身定義的Echo,
所以當降轉成Base後,
當然就無法識別A中new的Echo。
執行結果:
參考來源:
MSDN new 修飾詞 (C# 參考)
MSDN virtual (C# 參考)
MSDN 了解使用 Override 和 New 關鍵字的時機
MSDN 使用 Override 和 New 關鍵字進行版本控制
接著來看看new與virtual使用時的差異,
從下面的範例執行結果就可以看到使用new來覆寫基底類別的方法,
當降轉成基底類別呼叫該方法時,
會呼叫到基底類別的方法,而不會呼叫延伸類別所覆寫的方法,
這種情況下反而使用override會正常。
因為對A來說同時存在兩個相同名稱的方法,
基底類別的Echo與自身定義的Echo,
所以當降轉成Base後,
當然就無法識別A中new的Echo。
using System;
using System.Linq;
namespace ConsoleTest
{
class Program
{
static void Main(String[] args)
{
var instances = new Base[3];
instances[0] = new Base();
instances[1] = new A();
instances[2] = new B();
instances.ToList().ForEach(i => i.Echo());
Console.ReadLine();
}
}
public class Base
{
public virtual void Echo()
{
Console.WriteLine(this.GetType());
Console.WriteLine("Hello");
}
}
public class A : Base
{
public new void Echo()
{
base.Echo();
Console.WriteLine("Hi A");
}
}
public class B : Base
{
public override void Echo()
{
base.Echo();
Console.WriteLine(("Hi B"));
}
}
}
執行結果:
參考來源:
MSDN new 修飾詞 (C# 參考)
MSDN virtual (C# 參考)
MSDN 了解使用 Override 和 New 關鍵字的時機
MSDN 使用 Override 和 New 關鍵字進行版本控制
留言
張貼留言