抽象方法和虚拟方法有什么区别?在哪些情况下,建议使用抽象方法或虚拟方法?哪一种是最好的方法?
当前回答
抽象方法没有实现。它在父类中声明。子类负责实现该方法。
虚拟方法应该在父类中有一个实现,它有助于子类选择是使用父类的该实现,还是为子类中的该方法自己有一个新的实现。
其他回答
从C++背景来看,C#虚拟对应于C++虚拟,而C#抽象方法对应于C++纯虚拟函数
抽象方法总是虚拟的。它们无法实现。
这是主要的区别。
基本上,如果您有一个虚拟方法的“默认”实现,并且希望允许后代更改其行为,那么您将使用该方法。
使用抽象方法,可以强制后代提供实现。
在这里,我写了一些示例代码,希望这可能是一个非常实际的例子,可以从非常基本的层面上看到接口、抽象类和普通类的行为。如果您想将其用作演示,也可以在github中找到此代码作为项目:https://github.com/usavas/JavaAbstractAndInterfaceDemo
public interface ExampleInterface {
// public void MethodBodyInInterfaceNotPossible(){
// }
void MethodInInterface();
}
public abstract class AbstractClass {
public abstract void AbstractMethod();
// public abstract void AbstractMethodWithBodyNotPossible(){
//
// };
//Standard Method CAN be declared in AbstractClass
public void StandardMethod(){
System.out.println("Standard Method in AbstractClass (super) runs");
}
}
public class ConcreteClass
extends AbstractClass
implements ExampleInterface{
//Abstract Method HAS TO be IMPLEMENTED in child class. Implemented by ConcreteClass
@Override
public void AbstractMethod() {
System.out.println("AbstractMethod overridden runs");
}
//Standard Method CAN be OVERRIDDEN.
@Override
public void StandardMethod() {
super.StandardMethod();
System.out.println("StandardMethod overridden in ConcreteClass runs");
}
public void ConcreteMethod(){
System.out.println("Concrete method runs");
}
//A method in interface HAS TO be IMPLEMENTED in implementer class.
@Override
public void MethodInInterface() {
System.out.println("MethodInInterface Implemented by ConcreteClass runs");
// Cannot declare abstract method in a concrete class
// public abstract void AbstractMethodDeclarationInConcreteClassNotPossible(){
//
// }
}
}
我在一些地方看到抽象方法的定义如下**
“必须在子类中实现抽象方法”
**我觉得是这样。
如果子类也是抽象的,则不必在子类中实现抽象方法。。
1) 抽象方法不能是私有方法。2) 抽象方法不能在同一抽象类中实现。
我会说。。如果我们要实现一个抽象类,您必须重写基础抽象类中的抽象方法。因为使用重写关键字实现抽象方法。类似于虚拟方法。
虚拟方法不必在继承类中实现。
----------CODE--------------
public abstract class BaseClass
{
public int MyProperty { get; set; }
protected abstract void MyAbstractMethod();
public virtual void MyVirtualMethod()
{
var x = 3 + 4;
}
}
public abstract class myClassA : BaseClass
{
public int MyProperty { get; set; }
//not necessary to implement an abstract method if the child class is also abstract.
protected override void MyAbstractMethod()
{
throw new NotImplementedException();
}
}
public class myClassB : BaseClass
{
public int MyProperty { get; set; }
//You must have to implement the abstract method since this class is not an abstract class.
protected override void MyAbstractMethod()
{
throw new NotImplementedException();
}
}
解释:用类比。希望这对你有帮助。
上下文
我在一栋楼的21层工作。我对火很偏执。时不时地,在世界的某个地方,一场大火正在烧毁一座摩天大楼。但幸运的是,我们在这里有一本指导手册,说明发生火灾时该怎么做:
FireEscape()
不要收集物品步行至消防通道走出大楼
这基本上是一个名为FireEscape()的虚拟方法
虚拟方法
这个计划对99%的情况都很好。这是一个可行的基本计划。但有1%的可能性是消防通道被堵塞或损坏,在这种情况下,你会彻底完蛋,除非你采取一些激烈的行动,否则你会被烤焦。使用虚拟方法,您可以做到这一点:您可以使用自己版本的计划覆盖基本的FireEscape()计划:
运行到窗口跳出窗口降落伞安全到达底部
换句话说,虚拟方法提供了一个基本的计划,如果需要的话可以重写。如果程序员认为合适,子类可以重写父类的虚拟方法。
抽象方法
并非所有组织都训练有素。一些组织不进行消防演习。他们没有全面的逃跑政策。每个人都是为了自己。管理层只对现有的这种政策感兴趣。
换句话说,每个人都被迫开发自己的FireEscape()方法。一个人会走出消防通道。另一个人会跳伞。另一个人将使用火箭推进技术飞离大楼。另一个人会用绳索离开。管理层不在乎你如何逃跑,只要你有一个基本的FireEscape()计划——如果他们不这样做,你可以保证OHS会像一吨砖头一样砸在组织身上。这就是抽象方法的含义。
这两者又有什么区别?
抽象方法:子类被迫实现自己的FireEscape方法。使用虚拟方法,你有一个基本的计划等着你,但如果不够好,你可以选择实施自己的计划。
现在这并不难,是吗?