一、类成员的其他主题
1 隐藏基类方法
2 调用重写或隐藏的基类方法
3 使用嵌套的类型定义
1)隐藏基类方法
当从基类继承一个(非抽象的)成员时,也就继承了其实现代码。如果继承的成员是虚拟的,就可以用override关键字重写这段实现代码。无论继承的成员是否为虚拟,都可以隐藏这些实现代码。当继承的公共成员不像预期的那样工作时,就可以隐藏它:
public class MyBaseClass
{
public void DoSomething
{
//Baseclass implementation.
}
}
public class MyDerivedClass:MyBaseClass
{
public void DoSomething
{
//MyDerivedClass implementation,hides base implementation.
}
}
尽管这段代码可以正常运行,但它会生成一个警告,说明隐藏了一个基类成员。如果时无意间隐藏了一个需要使用的成员,此时就可以改正错误。如果确实要隐藏该成员,就可以使用new关键字显式地表明意图:
public class BaseClass
{
public void DoSomething
{
//BaseClass implementation.
}
}
public class MyDerivedClass : BaseClass
{
new public void DoSomething
{
//MyDerivedClass implementation, hide BaseClass implementation.
}
}
重写方法和隐藏基类方法的区别在于:
重写方法要求基类是虚拟的,重写替换了基类中的实现代码,即使通过基类类型进行,情况也将如此;
隐藏基类方法并不要求基类类型为虚拟,但可以实现一样的结果,尽管隐藏了基类中的实现代码,但仍可以通过基类来访问它。
2)调用重写或隐藏的基类方法
无论是重写成员还是隐藏成员,都可以在派生类的内部访问基类成员。这在许多情况下都是很有用的,例如:
要对派生类的用户隐藏继承的公共成员,但仍能在类中访问其功能。
要给继承的虚拟成员添加实现代码,而不是简单地用重写的新实现代码替换它。
为此可以使用base关键字,它表示包含在派生类中的基类的实现代码(在控制构造函数时,其用法是类似的),例如:
public class MyBaseClass
{
public virtual void DoSomething()
{
//Base implementation.
}
}
public class MyDerivedClass : MyBaseClass
{
public override void DoSomething()
{
//Derived class implementation, extends base class implementation.
base.DoSomething();
//More derived class implementation
}
}
这段代码在MyDerivedClass包含的DoSomething()方法中,执行包含在MyBaseClass中的DoSomething()版本,MyBaseClass是MyDerivedClass的基类。因为base使用的是对象实例,所以在静态成员中使用它会产生错误。因为base使用的是对象实例,所以在静态成员中使用它会产生错误。
this关键字
除了使用base关键字以外,还可以使用this关键字。与base一样,this也可以在类成员的内部,且该关键字也引用对象实例。只是this引用的是当前的对象实例(即不能在静态成员中使用this关键字,因为静态成员不是对象实例的一部分)。
this关键字最常用的功能是吧当前对象实例的引用传递给一个方法:
public void doSomething()
{
MyTargetClass myObj = new MyTargetClass();
myObj.DoSomethingWith(this);
}
其中,被实例化的MyTargetClass实例(myObj)有一个DoSomethingWith()方法,该方法带有一个参数,其类型与包含上述方法的类兼容。这个参数类型可以是类的类型、由这个类继承的类类型,或者有这个System.Object实现的一个接口。
this关键字的另一个常见用法是限定局部类型的成员,例如:
public class MyClass
{
private int someData;
public int SomeData => this.someData
}
使用this可以便于分辨出引用的是成员而不是局部变量。
3)使用嵌套的类型定义
除了在名称空点中定义类型之外,还可以在其它类中定义他们,如果这么做,就可以在定义中使用各种访问修饰符,而不仅是public和internal,也可以使用new关键字来隐藏继承与基类的类型定义:
public class MyClass
{
public class MyNestedClass
{
public int NestedClassField;
}
}
如果要在MyClass的外部实例化myNestedClass,就必须对名称进行限定:
MyClass.MyNestedClass myObj = new MyClass.MyNestedClass();
但是,如果嵌套的类声明为私有,就不能这么做。这个功能主要用来定义对于其包含类来说是私有的类。这样,名称空间中的其他代码就不能访问它。使用该功能的另一个原因是嵌套类可以访问其包含类的私有和受保护成员。