interface用來聲明接口 1.只提供一些方法規(guī)約,不提供方法主體 如 public interface IPerson { void getName();//不包含方法主體 } 2.方法不能用public abstract等修飾,無字段變量,無構(gòu)造函數(shù)。 3.方法可包含參數(shù) 如 public interface IPerson { void getAge(string s); }
一個例子(例1): public interface IPerson { IPerson(); //錯誤 string name; //錯誤 public void getIDcard();//錯誤
void getName(); //right void getAge(string s); //right }
實現(xiàn)interface的類 1.與繼承類的格式一致,如 public class Chinese:IPerson{} 2.必須實現(xiàn)interface中的各個方法
例2,繼承例1 public class Chinese:IPerson { public Chinese(){} //添加構(gòu)造 public void getName(){} //實現(xiàn)getName() public void getAge(string s){} //實現(xiàn)getAge() }
abstract聲明抽象類、抽象方法 1.抽象方法所在類必須為抽象類 2.抽象類不能直接實例化,必須由其派生類實現(xiàn)。 3.抽象方法不包含方法主體,必須由派生類以override方式實現(xiàn)此方法,這點跟interface中的方法類似
如 public abstract class Book { public Book() { }
public abstract void getPrice(); //抽象方法,不含主體 public virtual void getName() //虛方法,可覆蓋 { Console.WriteLine("this is a test:virtual getName()"); } public virtual void getContent() //虛方法,可覆蓋 { Console.WriteLine("this is a test:virtual getContent()"); } public void getDate() //一般方法,若在派生類中重寫,須使用new關(guān)鍵字 { Console.WriteLine("this is a test: void getDate()"); } }
public class JavaBook:Book { public override void getPrice() //實現(xiàn)抽象方法,必須實現(xiàn) { Console.WriteLine("this is a test:JavaBook override abstract getPrice()"); } public override void getName() //覆蓋原方法,不是必須的 { Console.WriteLine("this is a test:JavaBook override virtual getName()"); } }
測試如下: public class test { public test() { JavaBook jbook=new JavaBook(); jbook.getPrice(); //將調(diào)用JavaBook中g(shù)etPrice() jbook.getName(); //將調(diào)用JavaBook中g(shù)etName() jbook.getContent(); //將調(diào)用Book中g(shù)etContent() jbook.getDate(); //將調(diào)用Book中g(shù)etDate() } public static void Main() {test t=new test(); } }
virtual標記方法為虛方法 1.可在派生類中以override覆蓋此方法 2.不覆蓋也可由對象調(diào)用 3.無此標記的方法(也無其他標記),重寫時需用new隱藏原方法 virtual 關(guān)鍵字用于修飾方法、屬性、索引器或事件聲明,并且允許在派生類中重寫這些對象。例如,此方法可被任何繼承它的類重寫。 public virtual double Area() { return x * y; }
虛擬成員的實現(xiàn)可由派生類中的重寫成員更改。有關(guān)使用 virtual 關(guān)鍵字的更多信息,請參見使用 Override 和 New 關(guān)鍵字進行版本控制(C# 編程指南) 和了解何時使用 Override 和 New 關(guān)鍵字(C# 編程指南)。
調(diào)用虛方法時,將為重寫成員檢查該對象的運行時類型。將調(diào)用大部分派生類中的該重寫成員,如果沒有派生類重寫該成員,則它可能是原始成員。
默認情況下,方法是非虛擬的。不能重寫非虛方法。
virtual 修飾符不能與 static、abstract, private 或 override 修飾符一起使用。
除了聲明和調(diào)用語法不同外,虛擬屬性的行為與抽象方法一樣。
在靜態(tài)屬性上使用 virtual 修飾符是錯誤的。
通過包括使用 override 修飾符的屬性聲明,可在派生類中重寫虛擬繼承屬性
abstract與virtual: 方法重寫時都使用 override 關(guān)鍵字 interface中的方法和abstract方法都要求實現(xiàn)
new 修飾符(C# 參考)
在用作修飾符時,new 關(guān)鍵字可以顯式隱藏從基類繼承的成員。隱藏繼承的成員意味著該成員的派生版本將替換基類版本。在不使用 new 修飾符的情況下隱藏成員是允許的,但會生成警告。使用 new 顯式隱藏成員會取消此警告,并記錄代之以派生版本這一事實。
若要隱藏繼承的成員,請使用相同名稱在派生類中聲明該成員,并使用 new 修飾符修飾該成員。例如:
復(fù)制代碼 public class BaseC { public int x; public void Invoke() {} } public class DerivedC : BaseC { new public void Invoke() {} 在這個示例中,DerivedC.Invoke 隱藏了 BaseC.Invoke。 字段 x 不受影響,因為它沒有被類似名稱的字段隱藏。 通過繼承隱藏名稱采用下列形式之一: 引入類或結(jié)構(gòu)中的常數(shù)、指定、屬性或類型隱藏具有相同名稱的所有基類成員。 引入類或結(jié)構(gòu)中的方法隱藏基類中具有相同名稱的屬性、字段和類型。同時也隱藏具有相同簽名的所有基類方法。 引入類或結(jié)構(gòu)中的索引器將隱藏具有相同名稱的所有基類索引器。
對同一成員同時使用 new 和 override 是錯誤的,因為這兩個修飾符在含義上相互排斥。使用 new 會用同樣的名稱創(chuàng)建一個新成員并使原始成員變?yōu)殡[藏的,而 override 則擴展繼承成員的實現(xiàn)。 在不隱藏繼承成員的聲明中使用 new 修飾符將會生成警告。
示例 在該例中,基類 BaseC 和派生類 DerivedC 使用相同的字段名 x,從而隱藏了繼承字段的值。該示例演示了 new 修飾符的用法。另外還演示了如何使用完全限定名訪問基類的隱藏成員。 復(fù)制代碼 // cs_modifier_new.cs // The new modifier. using System; public class BaseC { public static int x = 55; public static int y = 22; }
public class DerivedC : BaseC { // Hide field ’x’ new public static int x = 100;
static void Main() { // Display the new value of x: Console.WriteLine(x); // Display the hidden value of x: Console.WriteLine(BaseC.x); // Display the unhidden member y: Console.WriteLine(y); } }
輸出 100 55 22 在此示例中,嵌套類隱藏了基類中具有相同名稱的類。該示例不僅演示了如何使用 new 修飾符來消除警告消息,而且還演示了如何使用完全限定名來訪問隱藏的類成員。
復(fù)制代碼 // cs_modifer_new_nested.cs // Using the new modifier with nested types. using System; public class BaseC { public class NestedC { public int x = 200; public int y; } }
public class DerivedC : BaseC { // Nested type hiding the base type members. new public class NestedC { public int x = 100; public int y; public int z; }
static void Main() { // Creating an object from the overlapping class: NestedC c1 = new NestedC();
// Creating an object from the hidden class: BaseC.NestedC c2 = new BaseC.NestedC();
Console.WriteLine(c1.x); Console.WriteLine(c2.x); } } as(C# 參考) 用于在兼容的引用類型之間執(zhí)行轉(zhuǎn)換。例如: 復(fù)制代碼 string s = someObject as string; if (s != null) { // someObject is a string. } 備注 as 運算符類似于強制轉(zhuǎn)換操作;但是,如果轉(zhuǎn)換不可行,as 會返回 null 而不是引發(fā)異常。更嚴格地說,這種形式的表達式 復(fù)制代碼 expression as type 等效于 復(fù)制代碼 expression is type ? (type)expression : (type)null 只是 expression 只被計算一次。 注意,as 運算符只執(zhí)行引用轉(zhuǎn)換和裝箱轉(zhuǎn)換。as 運算符無法執(zhí)行其他轉(zhuǎn)換,如用戶定義的轉(zhuǎn)換,這類轉(zhuǎn)換應(yīng)使用 cast 表達式來執(zhí)行。 示例 復(fù)制代碼 // cs_keyword_as.cs // The as operator. using System; class Class1 { } class Class2 { } class MainClass { static void Main() { object[] objArray = new object[6]; objArray[0] = new Class1(); objArray[1] = new Class2(); objArray[2] = "hello"; objArray[3] = 123; objArray[4] = 123.4; objArray[5] = null;
for (int i = 0; i < objArray.Length; ++i) { string s = objArray[i] as string; Console.Write("{0}:", i); if (s != null) { Console.WriteLine("’" + s + "’"); } else { Console.WriteLine("not a string"); } } } } is 如果所提供的表達式非空,并且所提供的對象可以強制轉(zhuǎn)換為所提供的類型而不會導(dǎo)致引發(fā)異常,則 is 表達式的計算結(jié)果將是 true。有關(guān)更多信息,請參見 7.6.6 強制轉(zhuǎn)換表達式。
如果已知表達式將始終是 true 或始終是 false,則 is 關(guān)鍵字將導(dǎo)致編譯時警告,但是,通常在運行時才計算類型兼容性。
不能重載 is 運算符。
請注意,is 運算符只考慮引用轉(zhuǎn)換、裝箱轉(zhuǎn)換和取消裝箱轉(zhuǎn)換。不考慮其他轉(zhuǎn)換,如用戶定義的轉(zhuǎn)換 // cs_keyword_is.cs // The is operator. using System; class Class1 { } class Class2 { } class IsTest { static void Test(object o) { Class1 a; Class2 b;
if (o is Class1) { Console.WriteLine("o is Class1"); a = (Class1)o; // Do something with "a." } else if (o is Class2) { Console.WriteLine("o is Class2"); b = (Class2)o; // Do something with "b." } else { Console.WriteLine("o is neither Class1 nor Class2."); } } static void Main() { Class1 c1 = new Class1(); Class2 c2 = new Class2(); Test(c1); Test(c2); Test("a string"); } }
|