12.密封类可以有虚函数吗?
答:
可以,基类中的虚函数将隐式的转化为非虚函数,但密封类本身不能再增加新的虚函数
示例:
1
class BaseClass
2

{
3
public virtual void F()
4
{
5
Console.WriteLine("BaseClass.F");
6
}
7
}
8
sealed class DeriveClass : BaseClass
9

{
10
//基类中的虚函数F被隐式的转化为非虚函数
11
12
//密封类中不能再声明新的虚函数G
13
//public virtual void G()
14
//{
15
// Console.WriteLine("DeriveClass.G");
16
//}
17
}
13.什么是属性访问器?
答:
属性访问器(Property Accessor),包括 get 访问器和 set 访问器分别用于字段的读写操作
其设计目的主要是为了实现面向对象(OO)中的封装思想。根据该思想,字段最好设为private,一个精巧的类最好不要直接把字段设为公有提供给客户调用端直接访问
另外要注意属性本身并不一定和字段相联系
14.abstract 可以和 virtual 一起使用吗?可以和 override 一起使用吗?
答:
abstract 修饰符不可以和 static、virtual 修饰符一起使用
abstract 修饰符可以和 override 一起使用,参见第11点
示例:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace Example14
6

{
7
class BaseClass
8
{
9
public virtual void F()
10
{
11
Console.WriteLine("BaseClass.F");
12
}
13
}
14
abstract class DeriveClass1 : BaseClass
15
{
16
//在这里, abstract是可以和override一起使用的
17
public abstract override void F();
18
}
19
class Program
20
{
21
static void Main(string[] args)
22
{
23
}
24
}
25
}
15.接口可以包含哪些成员?
答:
接口可以包含属性、方法、索引指示器和事件,但不能包含常量、域、操作符、构造函数和析构函数,而且也不能包含任何静态成员
16.类和结构的区别?
答:
类:
类是引用类型在堆上分配,类的实例进行赋值只是复制了引用,都指向同一段实际对象分配的内存
类有构造和析构函数
类可以继承和被继承
结构:
结构是值类型在栈上分配(虽然栈的访问速度比较堆要快,但栈的资源有限放),结构的赋值将分配产生一个新的对象。
结构没有构造函数,但可以添加。结构没有析构函数
结构不可以继承自另一个结构或被继承,但和类一样可以继承自接口
示例:
根据以上比较,我们可以得出一些轻量级的对象最好使用结构,但数据量大或有复杂处理逻辑对象最好使用类。
如:Geoemtry(GIS 里的一个概论,在 OGC 标准里有定义) 最好使用类,而 Geometry 中点的成员最好使用结构
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace Example16
6

{
7
interface IPoint
8
{
9
double X
10
{
11
get;
12
set;
13
}
14
double Y
15
{
16
get;
17
set;
18
}
19
double Z
20
{
21
get;
22
set;
23
}
24
}
25
//结构也可以从接口继承
26
struct Point: IPoint
27
{
28
private double x, y, z;
29
//结构也可以增加构造函数
30
public Point(double X, double Y, double Z)
31
{
32
this.x = X;
33
this.y = Y;
34
this.z = Z;
35
}
36
public double X
37
{
38
get
{ return x; }
39
set
{ x = value; }
40
}
41
public double Y
42
{
43
get
{ return x; }
44
set
{ x = value; }
45
}
46
public double Z
47
{
48
get
{ return x; }
49
set
{ x = value; }
50
}
51
}
52
//在此简化了点状Geometry的设计,实际产品中还包含Project(坐标变换)等复杂操作
53
class PointGeometry
54
{
55
private Point value;
56
57
public PointGeometry(double X, double Y, double Z)
58
{
59
value = new Point(X, Y, Z);
60
}
61
public PointGeometry(Point value)
62
{
63
//结构的赋值将分配新的内存
64
this.value = value;
65
}
66
public double X
67
{
68
get
{ return value.X; }
69
set
{ this.value.X = value; }
70
}
71
public double Y
72
{
73
get
{ return value.Y; }
74
set
{ this.value.Y = value; }
75
}
76
public double Z
77
{
78
get
{ return value.Z; }
79
set
{ this.value.Z = value; }
80
}
81
public static PointGeometry operator +(PointGeometry Left, PointGeometry Rigth)
82
{
83
return new PointGeometry(Left.X + Rigth.X, Left.Y + Rigth.Y, Left.Z + Rigth.Z);
84
}
85
public override string ToString()
86
{
87
return string.Format("X: {0}, Y: {1}, Z: {2}", value.X, value.Y, value.Z);
88
}
89
}
90
class Program
91
{
92
static void Main(string[] args)
93
{
94
Point tmpPoint = new Point(1, 2, 3);
95
96
PointGeometry tmpPG1 = new PointGeometry(tmpPoint);
97
PointGeometry tmpPG2 = new PointGeometry(tmpPoint);
98
tmpPG2.X = 4;
99
tmpPG2.Y = 5;
100
tmpPG2.Z = 6;
101
102
//由于结构是值类型,tmpPG1 和 tmpPG2 的坐标并不一样
103
Console.WriteLine(tmpPG1);
104
Console.WriteLine(tmpPG2);
105
106
//由于类是引用类型,对tmpPG1坐标修改后影响到了tmpPG3
107
PointGeometry tmpPG3 = tmpPG1;
108
tmpPG1.X = 7;
109
tmpPG1.Y = 8;
110
tmpPG1.Z = 9;
111
Console.WriteLine(tmpPG1);
112
Console.WriteLine(tmpPG3);
113
114
Console.ReadLine();
115
}
116
}
117
}
结果:
X: 1, Y: 2, Z: 3
X: 4, Y: 5, Z: 6
X: 7, Y: 8, Z: 9
X: 7, Y: 8, Z: 9