yzx99

导航

 

修改或加强基类原有的方法,专业术语要“方法重写”。我老是把这三个概念混在一起:重载、重构、重写,现在区分一下:
重载是建立一个相同名称、不同参数的成员函数。
重构是“在不改变软件现有功能的基础上,通过调整程序代码改善软件的质量、性能,使其程序的
设计模式和架构更趋合理,提高软件的扩展性和维护性”。这与面对对象没有直接关联。
重写就是子类对父类的一个方法进行修改。
如,我们的rectpoint准备对父类的show方法进行重写,让其显示之前会先显示“rect:",然后再显
示"x=nn y=nn",要实现有两种方法,一种:完全重新写过,
public override void show()
{
 Console.WriteLine("rect: ");
 Console.WriteLine("x=" + m_x.ToString() + " y=" + m_y.ToString());
}
满怀信心地编译,结果给我错误提示:
p.cs(66,23): error CS0506: “rectpoint.show()”: 继承成员“point.show()”未被标记为 virtual、abstract 或 override,无法进行重写
p.cs(41,14): (与前一个错误相关的符号位置)

原来你想重写父类的某个成员函数,首先是父类要允许,即父类的成员函数要标为“什么什么的”
。我先把父类标为override看,结果:
p.cs(41,23): error CS0115: “point.show()”: 没有找到适合的方法来重写
原来父类如果标为override,即说明父类也是从更上一层的类继承下来的,而我的父类上面没人了
。所以用override行不通。
从另一个方面说,如果rectpoint下面还有子类继承它,则子类就完全可以重写show方法,因为
rectpoint的show方法标明了override了。
我再换为abstract,结果还是一堆错误:
p.cs(41,23): error CS0513: “point.show()”是抽象的,但它包含在非抽象类“point”中
p.cs(26,7): (与前一个错误相关的符号位置)
p.cs(41,23): error CS0500: “point.show()”无法声明主体,因为它被标记为 abstract

该方法是抽象的,导致它要求所在的类也是抽象的,这个,我没办法按它说的继续改下去。
再试virtual,这下倒可以了,还是virtual好,什么都不要改,就可以继承了。

实现的另外一种方法,只写自己特殊的一部分,然后再调用父类的方法,这时,就要使用base。
 public override void show()
 {
  Console.WriteLine("rect: ");
  base.show();
 }
这也是可以理解的,如果不使用base前缀的话,show()就是指向自己,与this做前缀的效果是一样
的,都是死循环的递归调用。在很多情况下,我们修改父类的只是很小的一部分,因此base应该还是用得挺广的。

对于特殊的构造函数,要重写,不知道理论上称之为什么,因为父类与子类名称不一样,因此不会出现同名问题,但性质上却极象重写的方式,后来查了文档得知:构造函数不能被继承!即父项声明再多构造函数,也不会被子类所继承。子类想要有构造函数,那就一个个地写吧。但是可以先执行一下父类的某个构造函数,写法如下:
 public rectpoint():base()
 {
  m_y=20;
 }
这样,构造rectpoint时,先执行一下base(),然后再执行后面的代码。

posted on 2008-05-28 22:46  yzx99  阅读(510)  评论(0编辑  收藏  举报