C#經(jīng)典問題回答_第1頁
C#經(jīng)典問題回答_第2頁
C#經(jīng)典問題回答_第3頁
C#經(jīng)典問題回答_第4頁
C#經(jīng)典問題回答_第5頁
已閱讀5頁,還剩56頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1.靜態(tài)成員和非靜態(tài)成員的區(qū)別?................................................1

2.const和staticreadonly區(qū)別?..........................................3

3.extern是什么意思?........................................................6

4.abstract是什么意思?......................................................8

5.internal修飾符起什么作用?.................................................13

6.sealed修飾符是干什么的?..................................................16

7.override和overload的區(qū)別?.................................................20

8.什么是索引指示器?.........................................................22

9.new修飾符是起什么作用?...................................................25

lO.this關(guān)鍵字的含義?........................................................26

11.可以使用抽象函數(shù)重寫基類中的虛函數(shù)嗎?....................................28

12.密封類可以有虛函數(shù)嗎?.....................................................29

13.什么是屬性訪問器?.........................................................29

14.abstract可以和virtual一起使用嗎?可以和override一起使用嗎?...........30

15.接口可以包含哪些成員?.....................................................30

16.類和結(jié)構(gòu)的區(qū)別?...........................................................30

17.接口的多繼承會帶來哪些問題?.............................................34

18.抽象類和接口的區(qū)別?.....................................................37

L靜態(tài)成員和非靜態(tài)成員的區(qū)別?

答:

靜態(tài)變量使用static修飾符進(jìn)行聲明,在類被實例化時創(chuàng)建,通過類進(jìn)行訪問

不帶有static修飾符聲明的變量稱做非靜態(tài)變量,在對象被實例化時創(chuàng)建,通過對象進(jìn)行訪問

一個類的所有實例的同一靜態(tài)變量都是同一個值,同一個類的不同實例的同?非靜態(tài)變量可以是不同的值

靜態(tài)函數(shù)的實現(xiàn)里不能使用非靜態(tài)成員,如非靜態(tài)變量、非靜態(tài)函數(shù)等

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExampleOl

classProgram

(

classClassi

(

publicstaticStringstaticStr="Class”;

publicStringnotstaticStr="Obj";

)

staticvoidMain(string[]args)

(

〃靜態(tài)變量通過類進(jìn)行訪問,該類所有實例的同一靜態(tài)變量都是同一個值

Console.WriteLine(*ClassTsstaticStr:{0}”,Classi.staticStr);

ClassitrnpObj1=newClassi();

tmpObjl.notstaticStr="tmpObjl”;

Classitmp0bj2=newClassi();

tmp0bj2.notstaticStr二〃lmp0bj2";

〃非靜態(tài)變量通過對象進(jìn)行訪問,不同對象的同一非靜態(tài)變量可以有不同的值

Console.WriteLine(^trnpObjl,snotstaticStr:{0}”,tmpObjl.notstaticStr);

Console.WriteLine(/ztmpObj2,snotstaticStr:{0}”,tmp0bj2.notstaticStr);

Console.ReadLine();

)

)

結(jié)果:

Classi'sstaticStr:Class

tmpObjl'snotstaticStr:tmpObjl

tmpObj2*snotstaticStr:tmpObj2

Z.const和staticreadonly區(qū)別?

答:

const

用const修飾符聲明的成員叫常量,是在編譯期初始化并嵌入到客戶端程序

staticreadonly

用staticreadonly修飾符聲明的成員依然是變量,只不過具有和常量類似的使用方法:通過類進(jìn)行訪問、

初始化后不可以修改。但與常量不同的是這種變量是在運行期初始化

示例:

測試類:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExampleO2Lib

publicclassClassi

publicconstStringstrConst="Const”;

publicstaticreadonlyStringstrStaticReadonly=

nStaticReadonlyn;

//publicconstStringstrConst="ConstChanged0;

//publicstaticreadonlyStringstrStaticReadonly

nStaticReadonlyChangedn;

)

)

客戶端代碼:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingExample02Lib;

namespaceExamp]一02

(

classProgram

staticvoidMain(string[]args)

//修改Example02中Classi的strConst初始值后,只編譯

ExampleO2Lib項目

//然后到資源管理器里把新編譯的ExampleO2Lib.dll拷貝

Example02.exe所在的目錄,擬I彳亍Exampl一02.exe

//切不可在IDE里直接調(diào)試運行因為這會重新編譯整個解決方

案??!

//可以看至IIstrConst的輸出沒有改變,而

strStaticReadonly的輸出已經(jīng)改變

//表明Const變量是在編譯期初始化并嵌入到客戶端程序,而

StaticReadonly是在運行時初始化的

Console.WriteLine("strConst:{0}n,

Classi.strConst);

Console.WriteLine(nstrStaticReadonly:{0}",

Classi.strStaticReadonly);

Console.ReadLine();

)

)

)

結(jié)果:

strConst:Const

strStaticReadonly:StaticReadonly

修改后的示例:

測試類:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExampleO2Lib

(

publicclassClassi

(

//publicconstStringstrConst="Const”;

//publicstaticreadonlyStringstrStaticReadonly=

nStaticReadonlyH;

publicconstStringstrConst="ConstChanged”;

publicstaticreadonlyStringstrStaticReadonly=

nStaticReadonlyChanged”;

}

}

結(jié)果

strConst:Const

strStaticReadonly:StaticReadonlyChanged

3.extern是什么意思?

答:

extern修飾符用于聲明由程序集外部實現(xiàn)的成員函數(shù)

經(jīng)常用于系統(tǒng)API函數(shù)的調(diào)用(通過Dlllmport)。注意,和Dlllmport一起使用時要加上static修

飾符

也可以用于對于同一程序集不同版本組件的調(diào)用(用extern聲明別名)

不能與abstract修飾符同時使用

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

usingSystem.Runtime.InteropServices;

namespaceExample03

(

classProgram

(

//注意Dlllmport是一個AttributeProperty,在

System.Runtime.InteropServices命名空間中定義

//extern與Dlllmport一起使用時必須再加上一個static修飾符

[Dlllmport("User32.dll")]

publicstaticexternintMessageBox(intHandle,string

Message,stringCaption,intType);

staticintMain()

stringmyString;

Console.Write("Enteryourmessage:n);

myString=Console.ReadLine();

returnMessageBox(0,myString,"MyMessageBox”,

0);

)

)

)

結(jié)果:

4.abstract是什么意思?

答:

abstract修飾符可以用于類、方法、屬性、事件和索引指示器(indexer),表示其為抽象成員

abstract不可以和static、virtual一起使用

聲明為abstract成員可以不包括實現(xiàn)代碼,但只要類中還有未實現(xiàn)的抽象成員(即抽象類),那么它的

對象就不能被實例化,通常用于強(qiáng)制繼承類必須實現(xiàn)某?成員

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExample04

(

#region基類,抽象類

publicabstractclassBaseClass

(

//抽象屬性,同時具有g(shù)et和set訪問器表示繼承類必須將該屬性實

現(xiàn)為可讀寫

publicabstractStringAttribute

(

get;

set;

)

//抽象方法,傳入一個字符串參數(shù)無返回值

publicabstractvoidFunction(Stringvalue);

//抽象事件,類型為系統(tǒng)預(yù)定義的代理(delegate):EventHandler

publicabstracteventEventHandlerEvent;

//抽象索引指示器,只具有g(shù)et訪問器表示繼承類必須將該索引指示

器實現(xiàn)為只讀

publicabstractCharthis[intIndex]

(

get;

)

)

#endregion

#region繼承類

publicclassDeriveClass:BaseClass

(

privateStringattribute;

publicoverrideStringAttribute

(

get

returnattribute;

}

set

attribute=value;

)

)

publicoverridevoidFunction(Stringvalue)

(

attribute=value;

if(Event!=null)

(

Event(this,newEventArgs());

)

)

publicoverrideeventEventHandlerEvent;

publicoverrideCharthis[intIndex]

(

get

(

returnattribute[Index];

)

)

)

#endregion

classProgram

(

staticvoidOnFunction(objectsender,EventArgse)

(

for(inti=0;i<

((DeriveClass)sender).Attribute.Length;i++)

(

Console.WriteLine(((DeriveClass)sender)[i]);

)

)

staticvoidMain(string[]args)

(

DeriveClasstmpObj=newDeriveClass();

tmpObj.Attribute="1234567”;

Console.WriteLine(tmpObj.Attribute);

//將靜態(tài)函數(shù)OnFunction與tmpObj對象的Event事件進(jìn)行

關(guān)聯(lián)

tmpObj.Event+=newEventHandler(OnFunction);

tmpObj.Function(”7654321”);

Console.ReadLine();

)

)

)

結(jié)果:

1234567

7

6

5

4

3

2

1

5.internal修飾符起什么作用?

答:

internal修飾符可以用于類型或成員,使用該修飾符聲明的類型或成員只能在同一程集內(nèi)訪問

接口的成員不能使用internal修飾符

值得注意的是,如果為internal成員加上了protected修飾符,這時的訪問級別為internal或

protectedo只是看字面意思容易弄錯,許多人認(rèn)為internalprotected應(yīng)該是''只有同一個程序集中的

子類可以訪問〃,但其實它表示''同一個程序集中的所有類,以及所有程序集中的子類都可以訪問〃

示例

ExampleO5Lib項目的Classi

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExampleO5Lib

(

publicclassClassi

{

internalStringstrinternal=null;

publicStringstrPublic;

internalprotectedStringstrInternalProtected=

null;

}

)

結(jié)果

ExampleO5Lib項目的Class2類可以訪問到Classi的strinternal成員,當(dāng)然也可以訪問到

strlnternalProtected成員,因為他們在同一個程序集里

Class2xs*Classl.cs*

襟Exan<)ieO5Ub,Class2v

Busin<System;

Iusin^System.CollectionsG?neric;

LusiySystem.Text;

BnwespactExampl?05Lib

E3classCltss2

(

privateStringt*pStr-newClassi0.|

'.}^Eouals

^GetHashCode

QGetType

承strInternal

口strlnternalProtected

QstrPublic

?ToString

ClarkZheng

Example05項目里的Class3類無法訪問到Classi的strinternal成員,因為它們不在同?個程序

集里。但卻可以訪問到strlnternalProtected成員,因為Class3是Classi的繼承類

Example05項目的Program類既無法訪問到Classi的strinternal成員,也無法訪問到

strlnternalProtected成員,因為它們既不在同一個程序集里也不存在繼承關(guān)系

6.sealed修飾符是干什么的?

答:

sealed修飾符表示密封

用于類時,表示該類不能再被繼承,不能和abstract同時使用,因為這兩個修飾符在含義上互相排斥

用于方法和屬性時,表示該方法或?qū)傩圆荒茉俦恢貙?,必須和override關(guān)鍵字一起使用,因為使用

sealed修飾符的方法或?qū)傩钥隙ㄊ腔愔邢鄳?yīng)的虛成員

通常用于實現(xiàn)第三方類庫時不想被客戶端繼承,或用于沒有必要再繼承的類以防止濫用繼承造成層次結(jié)構(gòu)

體系混亂

恰當(dāng)?shù)睦胹ealed修飾符也可以提高一定的運行效率,因為不用考慮繼承類會重寫該成員

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExample06

(

classProgram

(

classA

(

publicvirtualvoidF()

Console.WriteLine(nA.FH);

}

publicvirtualvoidG()

(

Console.WriteLine("A.G");

}

}

classB:A

(

publicsealedoverridevoidF()

(

Console.WriteLine("B.F");

)

publicoverridevoidG()

(

Console.WriteLine("B.G");

)

)

classC:B

(

publicoverridevoidG()

Console.WriteLine("C.G");

)

)

staticvoidMain(string[]args)

(

newA().F();

newA().G();

newB().F();

newB().G();

newC().F();

newC().G();

Console.ReadLine();

}

)

)

結(jié)果:

類B在繼承類A時可以重寫兩個虛函數(shù),如圖所示:

classA

(

publicvirtutlvoidF0

(

Console.tfriteLine(*A.F");

)

publicvirtualvoidGO

(

Console.WriteLine(-A.G");

classBA

(

publicsealedoverridevoid

RE。

C由應(yīng)heng

由于類B中對F方法進(jìn)行了密封,類C在繼承類B時只能重寫一個函數(shù),如圖所示:

bclassB:A

(

Bpublics??l?dov?rrid?voidF()

{

Console.WriteLine(*B.F");

}

BpublicoverridevoidGO

(

Console.WriteLine(*B.G");

}

)

BclassC:B

(

publicoverridevoid

iwol

ClarkZheng

控制臺輸出結(jié)果,類C的方法F只能是輸出類B中對該方法的實現(xiàn):

A.F

A.G

B.F

B.G

B.F

C.G

7.override和overload的區(qū)別?

答:

override表示重寫,用于繼承類對基類中虛成員的實現(xiàn)

overload表示重載,用于同一個類中同名方法不同參數(shù)(包括類型不同或個數(shù)不同)的實現(xiàn)

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExample07

(

classProgram

(

classBaseClass

(

publicvirtualvoidF()

(

Console.WriteLineC^BaseClass.F");

)

}

classDeriveClass:BaseClass

(

publicoveiTidevoidF()

(

base.F();

Console.WriteLineC'DeriveClass.F");

)

publicvoidAdd(intLeft,intRight)

(

Console.WriteLine(HAddforInt:{0}",Left+Right);

)

publicvoidAdd(doubleLeft,doubleRight)

(

Console.WriteLine(nAddforint:{0}u,Left+Right);

)

)

staticvoidMain(string[]args)

(

DeriveClasstmpObj=newDeriveClass();

tmpObj.F();

tmpObj.Add(l,2);

tmpObj.Add(1.1,2.2);

Console.ReadLine();

結(jié)果:

BaseClass.F

DeriveClass.F

AddforInt:3

Addforint:3.3

8.什么是索引指示能?

答:

實現(xiàn)索引指示器(indexer)的類可以象數(shù)組那樣使用其實例后的對象,但與數(shù)組不同的是索

引指示器的參數(shù)類型不僅限于int

簡單來說,其本質(zhì)就是一個含參數(shù)屬性

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExample08

(

publicclassPoint

(

privatedoublex,y;

publicPoint(doubleX,doubleY)

(

x=X;

y=Y;

)

//重寫ToString方法方便輸出

publicoverridestringToStringO

(

returnString.Format("X:{0},Y:{1}n,x,y);

)

)

publicclassPoints

(

Point[]points;

publicPoints(Point[]Points)

(

points=Points;

)

publicintPoinlNumber

(

get

returnpoints.Length;

〃實現(xiàn)索引訪問器

publicPointthis[intIndex]

(

get

(

returnpoints[Index];

)

}

)

〃索引指示器的實質(zhì)是含參屬性,參數(shù)并不只限于int

classWeatherOfWeek

(

publicstringthis[intIndex]

(

get

(

//注意case段使用return直接返回所以不需要break

switch(Index)

(

case0:

(

return"Todayiscloudy!";

)

case5:

(

return"Todayisthundershower!";

}

default:

(

return"Todayisfine!";

}

)

)

)

publicstringthis[stringDay]

(

get

(

stringTodayWeather=null;

//switch的標(biāo)準(zhǔn)寫法

switch(Day)

case"Sunday”:

(

TodayWeather="Todayiscloudy!,1;

break;

)

case"Friday1':

(

TodayWeather=*'Todayisthundershower!'1;

break;

)

default:

(

TodayWeather="Todayisfine!',;

break;

)

)

returnTodayWeather;

classProgram

(

staticvoidMain(string[]args)

(

Point[]tmpPoints=newPoint[10];

for(inti=0;i<tmpPoints.Length;i++)

(

tmpPointsliJ=newPoint(i,Math.Sin(i));

)

PointstmpObj=newPoints(tmpPoints);

for(inti=0;i<tmpObj.PointNumber;i++)

(

Console.WriteLine(tmpObj[iJ);

string[]Week=newstringf]{"Sunday","Monday","Tuesday",''Wednesday1',

"Thursday","Friday",nStaurdayn};

WeatherOfWeektmpWeatherOfWeek=newWeatherOfWeek();

for(inti=0;i<6;i++)

Console.WriteLine(tmpWeatherOf,Week[i]);

foreach(stringtmpDayinWeek)

(

Console.WriteLine(tmpWeatherOlWeek[tmpDay]);

)

Console.ReadLine();

結(jié)果:

X:0,Y:0

X:1,Y:0.841470984807897

X:2,Y:0.909297426825682

X:3,Y:0.141120008059867

X:4,Y:-0.756802495307928

X:5,Y:-0.958924274663138

X:6,Y:-0.279415498198926

X:7,Y:0.656986598718789

X:8,Y:0.989358246623382

X:9,Y:0.412118485241757

Todayiscloudy!

Todayisfine!

Todayisfine!

Todayisfine!

Todayisfine!

Todayisthundershower!

Todayiscloudy!

Todayisfine!

Todayisfine!

Todayisfine!

Todayisfine!

Todayisthundershower!

Todayisfine!

9.new修飾符是起什么作用?

答:

new修飾符與new操作符是兩個概念

new修飾符用于聲明類或類的成員,表示隱藏了基類中同名的成員。而new操作符用于實

例化一個類型

new修飾符只能用于繼承類,一般用于彌補(bǔ)基類設(shè)計的不足

new修飾符和override修飾符不可同時用在一個成員上,因為這兩個修飾符在含義上互相

排斥

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExample09

(

classBaseClass

(

〃基類設(shè)計者聲明了一個PI的公共變量,方便進(jìn)行運算

publicstaticdoublePI=3.1415;

}

classDervieClass:BaseClass

(

〃繼承類發(fā)現(xiàn)該變量的值不能滿足運算精度,于是可以通過new修飾符顯式隱藏基

類中的聲明

publicnewstaticdoublePI=3.1415926;

)

classProgram

(

staticvoidMain(string[]args)

(

Console.WriteLine(BaseClass.PI);

Console.WriteLine(DervieClass.PI);

Console.ReadLine();

結(jié)果:

3.1415

3.1415926

lO.this關(guān)鍵字的含義?

答:

this是一個保留字,僅限于構(gòu)造函數(shù)和方法成員中使用

在類的構(gòu)造函數(shù)中出現(xiàn)表示對正在構(gòu)造的對象本身的引用,在類的方法中出現(xiàn)表示對調(diào)用該

方法的對象的引用,在結(jié)構(gòu)的構(gòu)造上函數(shù)中出現(xiàn)表示對正在構(gòu)造的結(jié)構(gòu)的引用,在結(jié)構(gòu)的方

法中出現(xiàn)表示對調(diào)用該方法的結(jié)果的引用

this保留字不能用于靜態(tài)成員的實現(xiàn)里,因為這時對象或結(jié)構(gòu)并未實例化

在C#系統(tǒng)中,this實際上是一個常量,所以不能使用this++這樣的運算

this保留字一般用于限定同名的隱藏成員、將對象本身做為參數(shù)、聲明索引訪問器、判斷傳

入?yún)?shù)的對象是否為本身

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExample10

(

classClassi

(

privatedoublec;

privatestringvalue;

publicdoubleC

(

get

(

returnc;

)

}

publicClassi(doublec)

(

〃限定同名的隱臧成員

this.c=c;

)

publicClassi(Classivalue)

(

〃用對象本身實例化自己沒有意義

if(this!=value)

(

c=value.C;

)

)

publicoverridestringToStringO

(

〃將對象本身做為參數(shù)

returnstring.Format(n{0}Celsius={1}Fahrenheit",c,UnitTransClass.C2F(this));

)

〃由于好奇,在這做了一個效率測試,想看看到底哪種方式訪問成員變量更快,結(jié)

論:區(qū)別不大。。。

publicstringTest1()

(

longvTickCount=Environment.TickCount;

for(inti=0;i<10000000;i++)

this.value=i.ToString();

returnstring.Format("Havethis.:{0}MSEL",Environment.TickCount-

vTickCount);

)

publicstringTest2()

(

longvTickCount=Environment.TickCount;

for(inti=0;i<10000000;i++)

value=i.ToString();

returnstring.Format(nDon'thavethis.:{0}MSEL'\Environment.TickCount-

vTickCount);

)

}

classUnitTransClass

(

publicstaticdoubleC2F(Classlvalue)

(

〃攝氏到華氏的轉(zhuǎn)換公式

return1.8*value.C+32;

)

)

classProgram

(

staticvoidMain(string[]args)

{

ClassitmpObj=newClassl(37.5);

Console.WriteLine(tmpObj);

Console.WriteLine(tmpObj.Testi());

Console.WriteLine(tmpObj.Test2());

Console.ReadLine();

結(jié)果:

37.5Celsius=99.5Fahrenheit

Havethis.:4375MSEL

Don'thavethis.:4406MSEL

11.可以使用抽象函數(shù)重寫基類中的虛函數(shù)嗎?

答:

可以

需使用new修飾符顯式聲明,表示隱藏了基類中該函數(shù)的實現(xiàn)

或增加override修飾符,表示抽象重寫了基類中該函數(shù)的實現(xiàn)

示例:

classBaseClass

(

publicvirtualvoidF()

(

Console.WriteLine("BaseClass.F");

abstractclassDeriveClassl:BaseClass

(

publicabstractnewvoidF();

〃是他提醒了我還可以用這種方法抽象重寫基類的虛方法

abstractclassDeriveClass2:BaseClass

(

publicabstractoverridevoidF();

)

12.密封類可以有虛函數(shù)嗎?

答:

可以,基類中的虛函數(shù)將隱式的轉(zhuǎn)化為非虛函數(shù),但密封類本身不能再增加新的虛函數(shù)

示例:

classBaseClass

{

publicvirtualvoidF()

(

Console.WriteLine("BaseClass.F");

)

)

sealedclassDeriveClass:BaseClass

(

〃基類中的虛函數(shù)F被隱式的轉(zhuǎn)化為非虛函數(shù)

〃密封類中不能再聲明新的虛函數(shù)G

//publicvirtualvoidG()

//{

//Console.WriteLine("DeriveClass.G");

//)

13.什么是屬性訪問器?

答:

屬性訪問器(PropertyAccessor),包括get訪問器和set訪問器分別用于字段的讀寫操作

其設(shè)計目的主要是為了實現(xiàn)面向?qū)ο螅?0)中的封裝思想。根據(jù)該思想,字段最好設(shè)為

private,一個精巧的類最好不要直接把字段設(shè)為公有提供給客戶調(diào)用端直接訪問

另外要注意屬性本身并不一定和字段相聯(lián)系

14.abstract可以和virtual一起使用嗎?可以和override一起使用嗎?

答:

abstract修飾符不可以和static>virtual修飾符一起使用

abstract修飾符可以和override一起使用,參見第11點

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExample14

(

classBaseClass

(

publicvirtualvoidF()

(

Console.WriteLine("BaseClass.FH);

)

)

abstractclassDeriveClassl:BaseClass

(

〃在這里,abstract是可以和override一起使用的

publicabstractoverridevoidF();

)

classProgram

(

staticvoidMain(string[]args)

15.接口可以包含哪些成員?

答:

接口可以包含屬性、方法、索引指示器和事件,但不能包含常量、域、操作符、構(gòu)造函數(shù)和

析構(gòu)函數(shù),而且也不能包含任何靜態(tài)成員

16.類和結(jié)構(gòu)的區(qū)別?

答:

類:

類是引用類型在堆上分配,類的實例進(jìn)行賦值只是復(fù)制了引用,都指向同一段實際對象分配

的內(nèi)存

類有構(gòu)造和析構(gòu)函數(shù)

類可以繼承和被繼承

結(jié)構(gòu):

結(jié)構(gòu)是值類型在棧上分配(雖然棧的訪問速度比較堆要快,但棧的資源有限放),結(jié)構(gòu)的賦

值將分配產(chǎn)生一個新的對象。

結(jié)構(gòu)沒有構(gòu)造函數(shù),但可以添加。結(jié)構(gòu)沒有析構(gòu)函數(shù)

結(jié)構(gòu)不可以繼承自另一個結(jié)構(gòu)或被繼承,但和類一樣可以繼承自接口

示例:

根據(jù)以上比較,我們可以得出一些輕量級的對象最好使用結(jié)構(gòu),但數(shù)據(jù)量大或有復(fù)雜處理邏

輯對象最好使用類。

如:Geoemtry(GIS里的一個概論,在OGC標(biāo)準(zhǔn)里有定義)最好使用類,而Geometry中

點的成員最好使用結(jié)構(gòu)

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExample16

(

interfaceIPoint

(

doubleX

{

get;

set;

)

doubleY

(

get;

set;

}

doubleZ

(

get;

set;

)

)

〃結(jié)構(gòu)也可以從接口繼承

structPoint:IPoinl

privatedoublex,y,z;

〃結(jié)構(gòu)也可以增加構(gòu)造函數(shù)

publicPoint(doubleX,doubleY,doubleZ)

this.x=X;

this.y=Y;

this.z=Z;

)

publicdoubleX

(

get{returnx;}

set{x=value;}

)

publicdoubleY

(

get{returnx;}

set{x=value;)

)

publicdoubleZ

(

get{returnx;}

set{x=value;}

)

}

〃在此簡化了點狀Geometry的設(shè)計,實際產(chǎn)品中還包含Project(坐標(biāo)變換)等復(fù)雜操

classPointGeometry

(

privatePointvalue;

publicPointGeometry(doubleX,doubleY,doubleZ)

{

value=newPoint(X,Y,Z);

}

publicPointGeometry(Pointvalue)

(

〃結(jié)構(gòu)的賦值將分配新的內(nèi)存

this.value=value;

)

publicdoubleX

(

get{returnvalue.X;}

set{this.value.X=value;}

)

publicdoubleY

get{returnvalue.Y;}

set{this.value.Y=value;}

)

publicdoubleZ

(

get{returnvalue.Z;}

set{this.value.Z=value;}

)

publicstaticPointGeometryoperator+(PointGeometryLeft,PointGeometryRiglh)

(

returnnewPointGeometry(Left.X+Rigth.X,Left.Y+Rigth.Y,Left.Z+Rigth.Z);

)

publicoverridestringToStringO

(

returnstring.Format("X:{0},Y:{1},Z:{2}'\value.X,value.Y,value.Z);

)

)

classProgram

{

staticvoidMain(string[]args)

(

PointtmpPoint=newPoint(l,2,3);

PointGeometrytmpPG1=newPointGeometry(tmpPoint);

PointGeometrytmpPG2=newPointGeometry(tmpPoint);

tmpPG2.X=4;

tmpPG2.Y=5;

tmpPG2.Z=6;

//由于結(jié)構(gòu)是值類型,tmpPG1和tmpPG2的坐標(biāo)并不一樣

Console.WriteLine(tmpPG1);

Console.WriteLine(tmpPG2);

//由于類是引用類型,對tmpPG1坐標(biāo)修改后影響到了tmpPG3

PointGeometrytmpPG3=tmpPG1;

tmpPGl.X=7;

tmpPGl.Y=8;

tmpPG1.Z=9;

Console.WriteLine(tmpPG1);

Console.WriteLine(tmpPG3);

Console.ReadLine();

結(jié)果:

X:1,Y:2,Z:3

X:4,Y:5,Z:6

X:7,Y:8,Z:9

X:7,Y:8,Z:9

17.接口的多繼承會帶來哪些問題?

答:

C#中的接口與類不同,可以使用多繼承,即一個子接口可以有多個父接口。但如果兩個父成員具有同名

的成員,就產(chǎn)生了二義性(這也正是C#中類取消了多繼承的原因之一),這時在實現(xiàn)時最好使用顯式的

聲明

示例:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespaceExamplel7

(

classProgram

(

〃一個完整的接口聲明示例

interfaceIExample

(

〃屬性

stringP

get;

set;

}

〃方法

stringF(intValue);

〃事件

eventEventHandlerE;

〃索引指示器

stringthis[intIndex]

{

get;

set;

}

}

interfaceIA

(

intCount{get;set;}

I

interfaceIB

intCount();

//IC接口從IA和IB多重繼承

interfaceIC:1A,IB

(

}

classC:IC

(

privateintcount=100;

〃顯式聲明實現(xiàn)IA接口中的Count屬性

intIA.Count

{

get{return100;}

set{count=value;}

}

〃顯式聲明實現(xiàn)IB接口中的Count方法

intIB.Count()

(

returncount*count;

}

}

staticvoidMain(string[]args)

CtmpObj=newC();

〃調(diào)用時也要顯式轉(zhuǎn)換

Console.WriteLine(^Countproperty:{0}”,((IA)tmpObj).Count);

Console.WriteLine(*Countfunction:{0}”,((IB)tmpObj).Count());

Console.ReadLineO;

)

)

)

結(jié)果:

Countproperty:100

Countfunction:10000

18.抽象類和接口的區(qū)別?

答:

抽象類(abstractclass)可以包含功能定義和實現(xiàn),接口(interface)只能包含功能定義

抽象類是從一系列相關(guān)對象中抽象出來的概念,因此反映的是事物的內(nèi)部共性;接口是為了滿足外部調(diào)用

而定義的一個功能約定,因此反映的是事物的外部特性

分析對象,提煉內(nèi)部共性形成抽象類,用以表示對象本質(zhì),即''是什么〃

為外部提供調(diào)用或功能需要擴(kuò)充時優(yōu)先使用接口

19.別名指示符是什么?

答:

通過別名指示符我們可以為某個類型起一個別名

主要用于解決兩個命名空間內(nèi)有同名類型的沖突或避免使用冗余的命名空間

別名指示符在所有命名空間最外層定義,作用域為整個單元文件。如果定義在某個命名空間內(nèi),那么它只

在直接隸屬的命名空間內(nèi)起作用

示例:

Classi.cs:

usingSystem;

usingSystem.Collections.Generic;

usingSystem.Text;

namespace

com.nblogs.reonlyrun.CSharp25QExample.Example19.LibOl

(

classCla

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論