版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
当时学C#时是找个人大概问了一下数据类型和分支语句就开始做项目
了。这两天又全面的看了一下有关的基础知识(学而时习之嘛),总结了
25个问题:
1.静态组员和非静态组员的区别?
2.const和staticreadonly区另U?
3.extern是什么意思?
4.abstract是什么意思?
5.internal修饰符起什么作用?
6.sealed修饰符是干什么的?
7.override和overload的区别?
8.什么是索引指示器?
9.new修饰符是起什么作用?
lO.this关键字的含义?
11.可以使用抽象函数重写基类中的虚函数吗?
12.密封类可以有虚函数吗?
13.什么是属性访问器?
14.abstract可以和virtual一起使用吗?可以和override一起使用
吗?
15.接口可以包括哪些组员?
16.类和构造的区别?
17.接口的多继承会带来哪些问题?
18.抽象类和接口的区别?
19.别名指示符是什么?
20.怎样手工释放资源?
21.P/Invoke是什么?
22.StringBuilder利String的区别?
23.explicit和implicit的含义?
24.params有什么用?
25.什么是反射?
如下是我做的一份参照答案(C#语言范围之内),假如有不精确、不全
面的,欢迎各位朋友指正!
1.静态组员和非静态组员的区别?
答:
静态变量使用static修饰符进行申明,在类被实例化时创立,通过类进
行访问
不带有static修饰符申明的变量称做非静态变量,在对象被实例化时创
立,通过对象进行访问
一种类的所有实例的同一静态变量都是同一种值,同一种类的不一样实例
的同一非静态变量可以是不一样的值
静态函数的实现里不能使用非静态组员,如非静态变量、非静态函数等
示例:
usingSystem;
usingSystem.Collectons.Generic;
usingSystem.Text;
namespaceExampleOl
{
classProgram
{
classClassi
{
publicstaticStringstaticStr="Class";
publicStringnotstaticStr="Obj";
}
staticvoidMain(string[]args)
{
〃静态变量通过类进行访问,该类所有实例的同一静态变量都是同一种值
Console.WriteLine("Classl'sstaticStr:{0}"7Classi.staticStr);
ClassitmpObjl=newClassl();
tmpObj1.notstaticStr="tmpObjl";
ClassitmpObj2=newClassl();
tmpObj2.notstaticStr="tmpObj2";
〃非静态变量通过对象进行访问,不一样对象的同一非静态变量可以有不
一样的值
Console.WriteLine("tmpObjl'snotstaticStr:{0}",
tmpObjl.notstaticStr);
Console.WriteLine("tmpObj2'snotstaticStr:{0}",
tmpObj2,notstaticStr);
Console.ReadLine();
}
}
}
成果;
Classi'sstaticStr:Class
tmpObjl'snotstaticStr:tmpObjl
tmpObj2'snotstaticStr:tmpObj2
2.const和staticreadonly区另U?
答:
const
用const修饰符申明的组员叫常量,是在编译期初始化并嵌入到客户端
程序
staticreadonly
用staticreadonly修饰符申明的组员仍然是变量,只不过具有和常量类
似的使用措施:通过类进行访问、初始化后不可以修改。但与常量不一样
的是这种变量是在运行期初始化
示例:
测试类:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample02Lib
{
publicclassClassi
(
publicconstStringstrConst="Const";
publicstaticreadonlyStringstrStaticReadonly=
'•StaticReadonly";
//publicconstStringstrConst="ConstChanged";
//publicstaticreadonlyStringstrStaticReadonly=
"StaticReadonlyChanged";
)
}
客户端代码:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingExample02Lib;
namespaceExample02
{
classProgram
{
staticvoidMain(string[]args)
{
〃修改Example02中Classi的strConst初始值后,只编译
Example02Lib项目
〃然后到资源管理器里把新编译的Example02Lib.dll拷贝
Example02.exe所在的目录,执行Example02.exe
〃切不可在TDF里直接调试运行由于这会重新编译整个处理方
案!!
〃可以看到strConst的输出没有变化,而strStaticReadonly
的输出已经变化
//表明Const变量是在编译期初始化并嵌入到客户端程序,而
StaticReadonly是在运行时初始化的
Console.WriteLine("strConst:{0}”,Classi.strConst);
Console.WriteLine("strStaticReadonly:{0}"?
Classi.strStaticReadonly);
Console.ReadLine();
}
)
}
成果,
strConst:Const
strStaticReadonly:StaticReadonly
修改后的示例:
测试类:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample02Lib
{
publicclassClassi
(
//publicconstStringstrConst="Const";
//publicstaticreadonlyStringstrStaticReadonly=
"StaticReadonly";
publicconstStringstrConst="ConstChanged";
publicstaticreadonlyStringstrStaticReadonly=
"StaticReadonlyChanged";
)
}
成果
strConst:Const
strStaticReadonly:StaticReadonlyChanged
3.extern是什么意思?
答:
extern修饰符用于申明由程序集外部实现的组员函数
常常用于系统API函数的调用(通过DHImport)。注意,和Dlllmport
一起使用时要加上static修饰符
也可以用于对于同一程序集不一样版本组件的调用(用extern申明别
名)
不能与abstract修饰符同步使用
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Runtime.InteropServices;
namespaceExample03
classProgram
〃注意Dlllmport是一种AttributeProperty,在
System.Runtime.InteropServices命名空间中定义
//extern与Dlllmport一起使用时必须再加上一种static修饰符
[Dlllmport(uUser32.dll")]
publicstaticexternintMessageBox(intHandle,string
Message,stringCaption,intType);
staticintMain()
{
stringmyString;
Console.Write("Enteryourmessage:");
myString=Console.ReadLinp();
returnMessageBox(0,myString,"MyMessageBox",0);
}
)
)
成果:
interyourmessage:HelloWorld,
MyMessageBoxX
HdoWorld!
确定
ClarkZheng
4.abstract是什么意思?
答:
abstract修饰符可以用于类、措施、属性、事件和索引指示器(indexer),
表达其为抽象组员
abstract不可以和static、virtual一起使用
申明为abstract组员可以不包括实现代码,但只要类中尚有未实现的抽
象组员(即抽象类),那么它的对象就不能被实例化,一般用于强制继承
类必须实现某一组员
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample04
{
#region基类,抽象类
publicabstractclassBaseClass
(
〃抽象属性,同步具有get和set访问器表达继承类必须将该属性实
现为可读写
publicabstractStringAttribute
get;
set;
}
〃抽象措施,传入一种字符串参数无返回值
publicabstractvoidFunction(Stringvalue);
〃抽象事件,类型为系统预定义的代理(delegate):EventHandler
publicabstracteventEventHandlerEvent;
〃抽象索引指示器,只具有get访问器表达继承类必须将该索引指示
器实现为只读
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);
〃将静态函数OnFunction与tmpObj对象的Event事件进行关
联
tmpObj.Event+=newEventHandler(OnFunction);
tmpObj.Function("7654321");
Console.ReadLine();
)
)
)
成果:
1234567
7
6
5
4
3
2
1
5.internal修饰符起什么作用?
答:
internal修饰符可以用于类型或组员,使用该修饰符申明的类型或组员只
能在同一程集内访问
接口的组员不能使用internal修饰符
值得注意的是,假如为internal组员加上了protected修饰符,这时
的访问级别为internal或protectedo只是看字面意思轻易弄错,许多
人认为internalprotected应当是''只有同一种程序集中的子类可以访
问〃,但其实它表达''同一种程序集中的所有类,以及所有程序集中的子类
都可以访问〃
示例
ExampleO5Lib项目的Classi
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample05Lib
{
publicclassClassi
(
internalStringstrinternal=null;
publicStringstrPublic;
internalprotectedStringstrlnternalProtected=null;
}
)
成果
ExampleO5Lib项目的Class2类可以访问到Classi的strinternal
组员,当然也可以访问到strinternalProtected组员,由于他们在同一
种程序集里
Class2.cs*Classi.cs*
v/tmpS
BusingSyst«m;
Iusin<System.Collections.Generic;
Lusin^SystemText:
SnwtspactEx^npl«05Lil
UclassClass2
(
privateStringtBpStr=newClassi0-1
\"I
。GetHashCode
QGetType
孑strInternal
:PstrlnternalProtected
QstrPublic
9ToString
ClarkZheng
Example05项目里的Class3类无法访问到Classi的
strlntemal组员,由于它们不在同一种程序集里。但却可以访问到
strlnternalProtected组员,由于Class3是Classi的继承类
Program.cs*Class2.csGassl.cs
出ExMn*05.Program.Clas$3
BusingSyit«m;
usin<System.Collections.Generic;
usin^System.Text;
usin^ExampleO5Lib;
BnMtesp&ceExample05
classProp*«n
classClass3:Classi
publicCltss30
base.
I9Equals
)
staticvo。GetHashCode
{GetType
Strin加HemberwiseClonestrPublic;
)strlnternalProtectedIstringClassl.$trlhternalPr(
}
QrtrPuWk
VToStrmg
Example05项目的Program类既无法访问到Classi
的strinternal组员,也无法访问到strlnternaIProtected组员,由于
它们既不在同一种程序集里也不存在继承关系
6.sealed修饰符是干什么的?
答:
sealed修饰符表达密封
用于类时,表达该类不能再被继承,不能和abstract同步使用,由于这
两个修饰符在含义上互相排斥
用于措施和属性时,表达该措施或属性不能再被重写,必须和override
关键字一起使用,由于使用sealed修饰符的措施或属性肯定是基类中对
应的虚组员
一般用于实现第三方类库时不想被客户端继承,或用于没有必要再继承的
类以防止滥用继承导致层次构造体系混乱
恰当的运用sealed修饰符也可以提高一定的运行效率,由于不用考虑继
承类会重写该组员
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample06
{
classProgram
{
classA
{
publicvirtualvoidF()
{
Console.WriteLine("A.F");
)
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();
}
)
}
成果,
类B在继承类A时可以重写两个虚函数,如图所示:
3classA
publicvirtualvoidF0
(
Console.WriteLine("A.F");
}
publicvirlutlvoidGO
(
Con^nl»Wri♦G"):
}
)
classB:A
(
publicsealedoverridevoid
而M―
,0G()
CI^FFZheng
由于类B中对F措施进行了密封,类C在继承类B时只能重写一种
函数,如图所示:
彳classB:A
publics««l«dovtrnd*voidF()
(
Console.WriteLine(-B.F");
}
publicovtrridtvoidGO
(
Console.WriteLine(*B.G");
}
}
classC:B
(
publicoverridevoid
ClarkZheng
控制台输出成果,类C的措施F只能是输出类B中对该措施的实现:
A.F
A.G
B.F
B.G
B.F
C.G
7.override和overload的区别?
答:
override表达重写,用于继承类对基类中虚组员的实现
overload表达重载,用于同一种类中同名措施不一样参数(包括类型不
一样或个数不一样)的实现
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample©7
{
classProgram
classBaseClass
publicvirtualvoidF()
(
Console.WriteLine("BaseClass.F");
)
}
classDeriveClass:BaseClass
{
publicoverridevoidF()
{
base.F();
Console.WriteLine("DeriveClass.F");
)
publicvoidAdd(intLeft,intRight)
{
Console.WriteLine("AddforInt:{0}”,Left+
Right);
)
publicvoidAdd(doubleLeft,doubleRight)
{
Console.WriteLine("Addforint:{0}”,Left+
Right);
)
}
staticvoidMain(string[]args)
DeriveClasstmpObj=newDeriveClass();
tmpObj.F();
tmpObj.Add(lJ2);
tmpObj.Add(l.l>2.2);
Console.ReadLine();
}
)
}
成果:
BaseClass.F
DeriveClass.F
AddforInt:3
Addforint:3.3
8.什么是索引指示器?
答:
实现索引指示器(indexer)的类可以象数组那样使用其实例后的对象,
但与数组不一样的是索引指示器的参数类型不仅限于mt
简朴来说,其本质就是一种含参数属性
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample08
{
publicclassPoint
{
privatedoublex,y;
publicPoint(doubleX,doubleY)
(
x=X;
y=丫;
)
//重写ToString措施以便输出
publicoverridestringToString()
{
returnString.Format("X:{0},Y:{1}",x,y);
)
)
publicclassPoints
{
Point[]points;
publicPoints(Point[]Points)
(
points=Points;
}
publicintPointNumber
{
get
(
returnpoints.Length;
)
)
〃实现索引访问器
publicPointthis[intIndex]
(
get
{
returnpoints[Index];
)
)
)
〃感谢watsonhua()的指点
//索引指示器的实质是含参属性,参数并不只限于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的原则写法
switch(Day)
(
case"Sunday":
{
TodayWeather="Todayiscloudy!
break;
}
case"Friday":
{
TodayWeather="Todayis
thundershower!
break;
}
default:
{
TodayWeather="Todayisfine!
break;
}
}
returnTodayWeather;
)
)
)
classProgram
staticvoidMain(string[]args)
Point[]tmpPoints=newPoint[10];
for(inti=0;i<tmpPoints.Length;i++)
(
tmpPointsfi]=newPoint(i,Math.Sin(i));
)
PointstmpObj=newPoints(tmpPoints);
for(inti=0;i<tmpObj.PointNumber;i++)
(
Console.WriteLine(tmpObj[i]);
)
string[]Week=newstring[]{"Sunday","Monday",
'•Tuesday","Wednesday","Thursday","Friday","Staurday"};
WeatherOfWeektmpWeatherOfWeek=newWeatherOfWeek();
for(inti=0;i<6;i++)
(
Console.WriteLine(tmpWeatherOfWeek[i]);
)
foreach(stringtmpDayinWeek)
(
Console.WriteLine(tmpWeatherOfWeek[tmpDay]);
}
Console.ReadLine();
)
)
}
成果:
X:0,Y:0
X:1,Y:0,8497
X:2,Y:0.682
X:3,Y:0.
X:4zY:-0.928
X:5,Y:-0.138
X:6,Y:-0.2794
X:7,Y:0.789
X:8,Y:0.382
X:9,Y:0.4121
Todayiscloudy!
Todayisfine!
Todayisfine!
Todayisfine!
Todayisfine!
Todayisthundershower!
Todayiscloudy!
Todayisfine!
Todayisfine!
Todayisfine!
Todayisfine!
Todayisthundershower!
Todayisfine!
9.new修饰符是起什么作用?
答:
new修饰符与new操作符是两个概念
new修饰符用于申明类或类的组员,表达隐藏了基类中同名的组员。而
new操作符用于实例化一种类型
new修饰符只能用于继承类,一般用于弥补基类设计的局限性
new修饰符和override修饰符不可同步用在一种组员上,由于这两个
修饰符在含义上互相排斥
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExample09
classBaseClass
{
〃基类设计者申明了一种PI的公共变量,以便进行运算
publicstaticdoublePI=3.1415;
)
classDervieClass:BaseClass
{
//继承类发现该变量的值不能满足运算精度,于是可以通过new修饰
符显式隐藏基类中的申明
publicnewstaticdoublePI=3.1415926;
)
classProgram
(
staticvoidMain(string[]args)
{
Console.WriteLine(BaseClass.PI);
Console.WriteLine(DervieClass.PI);
Console.ReadLine();
}
)
}
成果:
3.1415
3.1415926
10.this关键字的含义?
答:
this是一种保留字,仅限于构造函数和措施组员中使用
在类的构造函数中出现表达对正在构造的对象自身的引用,在类的措施中
出现表达对调用该措施的对象的引用,在构造的构造上函数中出现表达对
正在构造的构造的引用,在构造的措施中出现表达对调用该措施的成果的
引用
this保留字不能用于静态组员的实现里,由于这时对象或构造并未实例化
在C#系统中,this实际上是一种常量,因此不能使用this++这样的
运算
this保留字一般用于限定同名的隐藏组员、将对象自身做为参数、申明索
引访问器、判断传入参数的对象与否为自身
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExamplelO
classClassi
(
privatedoublec;
privatestringvalue;
publicdoubleC
{
get
{
returnc;
}
}
publicClassl(doublec)
{
〃限定同名的隐臧组员
this.c=c;
}
publicClassl(Classlvalue)
{
〃用对象自身实例化自己没故意义
if(this!=value)
{
c=value.C;
)
}
publicoverridestringToString()
{
〃将对象自身做为参数
returnstring.Format("{0}Celsius={1}Fahrenheit'^c,
UnitTransClass.C2F(this));
}
〃由于好奇,在这做了一种效率测试,想看看究竟哪种方式访问组员变
量更快,结论:区别不大。。。
publicstringTestl()
{
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("Don'thavethis.:{0}MSEL",
Environment.TickCount-vTickCount);
}
)
classUnitTransClass
(
publicstaticdoubleC2F(Classlvalue)
{
〃摄氏到华氏的转换公式
return1.8*value.C+32;
}
)
classProgram
{
staticvoidMain(string[]args)
{
ClassitmpObj=newClassl(37.5);
Console.WriteLine(tmpObj);
Console.WriteLine(tmpObj.Testl());
Console.WriteLine(tmpObj.Test2());
Console.ReadLine();
}
)
}
成果:
37.5Celsius=99.5Fahrenheit
Havethis.:4375MSEL
Don'thavethis.:4406MSEL
11,可以使用抽象函数重写基类中的虚函数吗?
答:
可以
需使用new修饰符显式申明,表达隐藏了基类中该函数的实现
或增长override修饰符,表达抽象重写了基类中该函数的实现
示例:
classBaseClass
{
publicvirtualvoidF()
(
Console.WriteLine("BaseClass.F");
)
)
abstractclassDeriveClassl:BaseClass
publicabstractnewvoidF();
}
〃感谢watsonhua()的指点
〃是他提醒了我还可以用这种措施抽象重写基类的虚措施
abstractclassDeriveClass2:BaseClass
(
publicabstractoverridevoidF();
)
12.密封类可以有虚函数吗?
答:
可以,基类中的虚函数将隐式的转化为非虚函数,但密封类自身不能再增
长新的虚函数
示例:
classBaseClass
{
publicvirtualvoidF()
(
Console.WriteLine("BaseClass.F");
}
)
sealedclassDeriveClass:BaseClass
//基类中的虚函数F被隐式的转化为非虚函数
//密封类中不能再申明新的虚函数G
//publicvirtualvoidG()
//{
//Console.WriteLine("DeriveClass・G");
//)
)
13.什么是属性访问器?
答:
属性访问器(PropertyAccessor),包括get访问器和Set访问器分别用
于字段的读写操作
其设计目的重要是为了实现面向对象(00)中的封装思想。根据该思想,
字段最佳设为private,一种精致的类最佳不要直接把字段设为公有提供
应客户调用端直接访问
此外要注意属性自身并不一定和字段相联络
14.abstract可以和virtual一起使用吗?可以和override一起
使用吗?
答:
abstract修饰符不可以和static、virtual修饰符一起使用
abstract修饰符可以和override一起使用,参见第11点
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExamplel4
{
classBaseClass
{
publicvirtualvoidF()
(
Console.WriteLine("BaseClass.F");
)
)
abstractclassDeriveClassl:BaseClass
{
〃在这里,abstract是可以和override一起使用的
publicabstractoverridevoidF();
}
classProgram
staticvoidMain(string[]args)
}
}
}
15.接口可以包括哪些组员?
答:
接口可以包括属性、措施、索引指示器和事件,但不能包括常量、域、操
作符、构造函数和析构函数,并且也不能包括任何静态组员
16•类和构造的区别?
答:
类:
类是引用类型在堆上分派,类的实例进行赋值只是复制了引用,都指向同
一段实际对象分派的内存
类有构造和析构函数
类可以继承和被继承
构造:
构造是值类型在栈上分派(虽然栈的访问速度比较堆要快,但栈的资源有
限放),构造的赋值将分派产生一种新的对象。
构造没有构造函数,但可以添加。构造没有析构函数
构造不可以继承自另一种构造或被继承,但和类同样可以继承自接口
示例:
根据以上比较,我们可以得出某些轻量级的对象最佳使用构造,但数据量
大或有复杂处理逻辑对象最佳使用类。
如:Geoemtry(GIS里的一种概论,在OGC原则里有定义)最佳使
用类,而Geometry中点的组员最佳使用构造
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExamplel6
{
interfaceIPoint
(
doubleX
{
get;
set;
}
doubleY
{
get;
set;
}
doubleZ
{
get;
set;
}
)
〃构造也可以从接口继承
structPoint:IPoint
(
privatedoublex,y,z;
//构造也可以增长构造函数
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的设计,实际产品中还包括Project(坐标变
换)等复杂操作
classPointGeometry
{
privatePointvalue;
publicPointGeometry(doubleX,doubleY,doubleZ)
{
value=newPoint(X,Y,Z);
)
publicPointGeometry(Pointvalue)
{
〃构造的赋值将分派新的内存
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,
PointGeometryRigth)
{
returnnewPointGeometry(Left.X+Rigth.Left.Y+
Rigth.Y,Left.Z+Rigth.Z);
}
publicoverridestringToString;)
{
returnstring.Format("X:{0})Y:{1},Z:{2}“,value.
value.Y,value.Z);
}
)
classProgram
(
staticvoidMain(string[]args)
{
PointtmpPoint=newPoint(l>2,3);
PointGeometrytmpPGl=newPointGeometry(tmpPoint);
PointGeometrytmpPG2=newPointGeometry(tmpPoint);
tmpPG2.X=4;
tmpPG2.Y=5;
tmpPG2.Z=6;
//由于构造是值类型,tmpPGl和tmpPG2的坐标并不一样样
Console.WriteLine(tmpPGl);
Console.WriteLine(tmpPG2);
//由于类是引用类型,对tmpPGl坐标修改后影响到了t叩PG3
PointGeometrytmpPG3=tmpPGl;
tmpPGl.X=7;
tmpPGl.Y=8;
tmpPGl.Z=9;
Console.WriteLine(tmpPGl);
Console.WriteLine(tmpPG3);
Console.ReadLine();
}
)
)
成果:
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#中的接口与类不一样,可以使用多继承,即一种子接口可以有多种父
接口。但假如两个父组员具有同名的组员,就产生了二义性(这也正是C#
中类取消了多继承的原因之一),这时在实现时最佳使用显式的申明
示例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceExamplel7
{
classProgram
//一种完整的接口申明示例
interfacelExample
{
//属性
stringP
{
get;
set;
}
〃措施
stringF(intValue);
〃事件
eventEventHandlerE;
〃索引指示器
stringthis[intIndex]
(
get;
set;
)
}
interfaceIA
(
intCount{get;set;}
}
interfaceIB
{
intCount();
}
〃工C接口从IA和IB多重继承
interfaceIC:IA,IB
{
}
classC:IC
{
privateintcount=100;
〃显式申明实现工A接口中的Count属性
intIA.Count
(
get{return100;}
set{count=value;}
)
//显式中明煲现工B接口中的Count措施
intIB.Count()
{
returncount*count;
}
}
staticvoidMain(string[]args)
CtmpObj=newC();
〃调用时也要显式转换
Console.WriteLine("Countproperty:{0}"?
((IA)tmpObj).Count);
Console.WriteLine("Countfunction:{0}”>
((IB)tmpObj).Count());
Console.ReadLine();
}
)
)
成果:
Countproperty:100
Countfunction:10000
18.抽象类和接口的区别?
答:
抽象类(abstractclass)可以包括功能定义和实现,接
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 生物标志物在药物临床试验中的精准医疗策略-1
- 生物打印技术在牙周组织再生中的细胞因子调控
- 生物制剂失应答后IBD的快速反应评估方法
- 生物3D打印墨水的细胞凋亡抑制策略
- 生活质量终点在慢性病药物早期研发中的预测价值
- 人力资源岗面试题集及答案详解
- 深度解析(2026)《GBT 19465-2004工业用异丁烷 (HC-600a)》
- 深度解析(2026)《GBT 19401-2003客运拖牵索道技术规范》
- 瓣膜病合并感染性心内膜炎治疗策略
- 电商行业运营经理面试技巧与题库
- 人际传播教程 课件 第6周 建构主义与信息生成理论
- DBJT15-101-2022 建筑结构荷载规范
- 四川佰思格新材料科技有限公司钠离子电池硬碳负极材料生产项目环评报告
- 2025冷冻食品运输合同(肉类)
- TLR2对角膜移植术后MDSC分化及DC成熟的调控机制研究
- 建筑设计防火规范-实施指南
- CJ/T 511-2017铸铁检查井盖
- 智能采血管理系统功能需求
- 【基于PLC的自动卷缆机结构控制的系统设计10000字(论文)】
- 资产移交使用协议书
- GB/T 45481-2025硅橡胶混炼胶医疗导管用
评论
0/150
提交评论