1 成员定义
这里的成员包括字段,属性,方法。字段类似于C++的成员变量;属性是一个很独特的成员,一般用于访问私有字段;方法与C++的成员函数类似。成员都提供四种访问 性。
pubilic--------------------成员可以由任何代码访问
private--------------------默认此关键字,成员只能由类中的代码访问
internal------------------成员由定义它的程序集(项目)内部的代码使用.
protected---------------成员只能由类和派生类来访问
protected internal----项目中的派生类使用
也可以使用static关键字来声明字段,方法和属性。
1.1 定义字段
(1)public int MyInt; 注意.NET Framework中的公共字段以PascalCasing形式来命名。私有字段使用camelCasing。
① 字段还可以使用readonly关键字,表示此字段只能在执行构造函数的过程中赋值,或者由初始化赋值语句赋值。
pubilic readonly int MyInt = 17;
② 可以用static关键字声明为静态:public static int MyInt;
1,2 定义方法
与公共字段一样,,NETFramework中的公共方法采用PascalCasing形式命名。
virtual------方法可以重写
abstract----方法必须在非抽象类的派生类中重写(只用于抽象类中)
override----方法重写了一个基类
extern------方法定义在其他地方
如果使用了override,也可以使用sealed指定在派生类中不能对这个方法做进一步的修改,即这个方法不能由派生类重写。
1.3 定义属性
属性定义方式与字段类似,但比字段的内容多。形式与方法类似,通过set块,get块来设置,修改属性。
2 类成员的其他常用方法
2.1 隐藏基类方法
不同于C++的一点在于,一般在派生类中使用new关键字显示表明意图。不管继承的成员是否为虚拟,都可以隐藏这些代码。
new public void DoSomething() {};
这里需要和之前的override区别来看。
对于:
MyDerivedClass myObj = new MyDerivedClass();
MyBaseClass myBase = myObj;
myObj.DoSomething();
myBase.DoSomething();
override中,基类必须是需要virtual声明,重写之后,不管是基类指针还是派生类指针调用都是override的方法。
public class MyBaseClass
{
public virtual void DoSomething()
{
Console.WriteLine("Base");
}
}
public class MyDerivedClass : MyBaseClass
{
public override void DoSomething()
{
Console.WriteLine("Derived");
}
}
输出:
Derived
Derived
new隐藏基类方法,不管基类是否virtual声明,派生类new之后效果都一样。派生类指针调用派生类方法,基类指针调用基类方法。
public class MyBaseClass
{
public virtual void DoSomething()
{
Console.WriteLine("Base");
}
}
public class MyDerivedClass : MyBaseClass
{
new public void DoSomething()
{
Console.WriteLine("Derived");
}
}
输出:
Derived
Base
2.2 base关键字
无论是重写成员还是隐藏成员,都可以在派生类的内部访问基类成员。使用base关键字,表示包含在派生类中的基类的实现代码。
注:因为base使用的是对象实例,所以在静态成员中使用会出现错误。
2.3 this关键字
this也可以用在类成员的内部,只是this引用的是,当前对象的实例,即不能在静态成员中使用this关键字。
3 接口的实现
接口成员的定义与类成员的定义相似,但有以下几个区别:
(1)不允许使用访问修饰符(public, private, protected, 或internal),所有接口成员都是公共的。
(2)接口成员不能包含代码体。
(3)接口不能定义字段成员。
(4)接口成员不能使用static, virtual, abstract, 或 sealed来定义。
(5)类型定义成员是禁止的。
(6)要隐藏继承了基接口的成员,可以用new关键字来定义它们
(7)在接口中定义的属性可以定义访问块get和set中的哪一个能用于该属性(或将它们同时用于该属性)
interface ImyInterface
{
intMyInt { get; set;}
}
(8)接口与类一样,可以定义为类的成员。
3.1 在基类中把接口的方法定义为虚拟的
在派生类中用new关键字隐藏一个基类成员,而不是重写它,则方法ImyInterface.DoSomething()就总是引用基类版本,即使通过接口访问派生类,也是这样。
interface IMyInterface
{
void DoSomethingElse();
}
public class MyBaseClass : IMyInterface
{
public virtual void DoSomethingElse()
{
Console.WriteLine("BaseSomethingElse");
}
}
public class MyDerivedClass : MyBaseClass
{
new public void DoSomethingElse()
{
Console.WriteLine("DerivedSomethingElse");
}
}
则,使用下面的方法:
IMyInterface inter = new MyBaseClass();
inter.DoSomethingElse();
IMyInterface inter2 = new MyDerivedClass();
inter2.DoSomethingElse();
则,输出:
BaseSomethingElse
BaseSomethingElse
而将派生类的方法定义为:
public override void DoSomethingElse()
{
Console.WriteLine("DerivedSomethingElse");
}
之后,则输出:
BaseSomethingElse
DerivedSomethingElse
3.2显示定义接口
如果,由类显示地实现接口成员,该成员就只能通过接口来访问,不能通过类的访问。
public class MyBaseClass : IMyInterface
{
void IMyInterface.DoSomething()
{
Console.WriteLine("xianshiBaseSomething");
}
}
3.3用非公共的可访问性添加属性存取器
如果在定义属性的接口中只包含set块,就可以给类中的属性添加get块,反之亦然。但是,只有所添加的存取器的可访问修饰符比接口中定义的存取器的可访问性更加严格时,才能这么做。