- 北境漫步
-
不可以.两个的含义完全不同.
virtual 关键字用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象。例如,此方法可被任何继承它的类重写。
override 方法提供从基类继承的成员的新实现。 由 override 声明重写的方法称为重写基方法。 重写的基方法必须与 override 方法具有相同的签名。
不能重写非虚方法或静态方法。 重写的基方法必须是 virtual、abstract 或 override 的。
override 声明不能更改 virtual 方法的可访问性。 override 方法和 virtual 方法必须具有相同的访问级别修饰符。
您不能使用 new、static 或 virtual 修饰符来修改 override 方法。
重写属性声明必须指定与继承属性完全相同的访问修饰符、类型和名称,并且被重写的属性必须是 virtual、abstract 或 override 的。
- 小菜G
-
我敢肯定一楼自己对面向对象都不理解!
楼主所问的问题说明楼主对面向对象思想的一种误用,再去看也解决不了问题的,而动不动让人去看某某方面的思想或知识之前,先看一下看过后对方能否理解——我认为楼主再去看看也不能理解他的疑问的!
在面向象设计时,一般情况下会使用virtal修饰必性或方法表示子类对象中可以进行重写。我们要先搞清楚我们为什么会使用这个virtal来修饰。
先说一下面向对象的设计原则,面向对象设计有一个很重的步骤就是抽象!也就是说我们将同一类的对象抽象成一个基类(父类),但是设计原则说有一句话是很重要的,基类尽量使用抽象类而非具体类。换句话来说,我们经常把一些相同类的方法等提升为基类的方法或属性。而相同签名的方法而不同的具体实现提为基类的抽象方法。
换句话来说,相同的方法的签名而实现不同的,我们只提取的是方法的签名,而并非将方法体实现。如果相同方法实现签名不同时,我们可以提取为事件而且可以实现不同的事件实现,然后用事件去安排不同签名的实现。如果相同签名相同实现的话,直接提取该方法。
virtual的出现其实是一种折中的方法——子类有相同的签名,但大多数方法的实现相同,只有极少数不同,如果我们提取签名的情况下,很多子类需要写相同的代码实现抽象方法——这与面向对象的目的——提高代码复用率是相违背的。所以这里我们尊重了大多数子类的建议,提取了方法的实现,写成一个虚方法。意思是说,如果你不重这个方法,就按这个方法运行,否则按你重写的子类实现运行。当然为了标识子类实现,方法重写时必须在前边增加override修饰。当然属性也一样的。
由些可见——如果一个类允许某重写方法,那么重写方法的那个已经是一种特例了,因为基类使用virtual说明显方法是表示大多数子类要使用这个,只有极个别的特例子类使用不同的实现体。那么这些极个别的特例已经十分特殊了!
现在你的问题是,我想以这个极个别的特例做为基类,再做一个极个别的特例!你想一下,特例的子类下再实现个特例的子类,这个子类与源基类还有多大相关性?你能从一个极特别的子类去实现一个极特别的子类——这个不我们面向对象思想的原则!
为什么,我想问的是,你这样的问题,为何不让C直从A类继承呢?如果B子类下大多数是按B的属性的,那么为什么要坚持在B类中实现呢?也就是说,你为什么不考虑一个D类不重写A类的呢?然后让C去继承D类呢?可见你的继承路径是绝对有问题的。
当然,这个问题是我们自底向上分析时很容易看出来的,但看顶向下分析时却不容易看出。但不管怎么说还是优先考虑使用其他的继承路径,而不是让特殊更特殊。
你的问题是你对面向对象设计并不十分精通,只处于了解,所以选用了错误的路径。所以对你的问题十之八九没有必要解决的——因为在面向对象设计中几乎不存在!
你看到了,我用了几乎一词,而不是绝对,事实上它的存在的!虽然数量很少,但是却是真实存在的,尤其是重构系统中可能会出现——不要在新系统中出现就可以了!
实现子类与父类不同的方案有两种的,第一种大多数的编译器根本没有考虑。这种方案就是再对父类进行重写,当然virtual与override事时修饰一个方法的情况你就别考虑了,他不存在的。这种方法是虽然override重写了,但下级子类仍可再重写。我也说过,大多数编译器是不支持的,这要看你所使用的编译器了!编写代码时你若是对你的工具还是熟悉——这可不是什么好事,你自己测试一下你的编译器是否能重写通过,如果不能——我说过大多数编译器不支持。
第二种方法是截断重写。也就是说丢掉继承的方法写一个新的方法,你可能遇到过这样的问题,当继承下来的某个方法不合用时怎么办?就好象你B类方法不允许再重写的情况下,继承给了C类,但方法体不合用。或者是我想隐藏B类的某个方法,不想让他再执行!那么new这个词可就有大用处了!它专门处理这种情况!大多数的编译器中都支持!
在B类中有一个方法实现
class B
{
public void Method()
{
.........//方法实现
}
}
C类是从B类继承而来,但真真Method方法不合用,我不想要这个方法或者是根本不合用!
class C :B
{
public new void Method()
{
throw new Exception("this "Method()" is not found!");
}
}
在C类调用该方法时会抛出一个例外,它说这个方法没有找到!对于使用你程序的人肯定以为没有这个方法的!只不过有一点特殊的地方是,在有感知的编译器中可以查看到这个方法,如果想真正隐藏,改写编译后的xml可以使用之不出现这个方法的。如果不小心补调用了,那么他也会提示出这个错误的!
你可能相到了,在方法中写一些执行不就可以实现类似重写的功能了吗?事实上是这样,但是这个方法却是不继承而来的,而是他截断了继承,重新写了一个新的方法!多数事实我们还是称其为隐藏继承的。
当然,这里只是处理极特殊的情况的,本身它就违反了面向对象继承,所以一般极少使用或几乎不用!所以针对你的情况,建议你换一下继承路径,特殊中的特殊类——直接从源基类继承也写不了多少代码的!继承的目的是复用代码,但不能因为复用代码而使整个面向对象代码难以理解!当两者矛盾时,优先采用易于理解的方式进行!
你明白了以上道理,那么对地设计模式还是建议你着手看一下!一般我们会说不会用设计模式的,充其量也只是看懂了面向对象的理论,只有设计模式才是面向对象理论的一个实践机会。否则离面向对象还有很大的差距的!
不过在设计模式中有一句话会让你十分吃惊:尽可能少使用继承,而使用复合!因为设计的目的是松耦合设计,而继承会增加对象之间的耦合度!所以一般情况下,在大项目很少用到复杂的对象间的继承关系——象你这种复杂的继承,更是极其罕见!所以你的这个问题没有任何价值的!当你在面向对象中再进一阶时你就会明白!
- ardim
-
建议楼主去看下结构与面对对象的思想