抽象方法和虚方法有什么区别?

1718

抽象方法和虚方法有什么区别?在哪些情况下建议使用抽象或虚方法?哪种方法是最佳的?

抽象方法是没有实现的方法,必须在子类中实现,而虚方法有默认实现但可以被覆盖。如果希望强制子类实现特定方法,则应该使用抽象方法,如果希望提供默认实现并允许子类覆盖它,则应该使用虚方法。选择哪种方法取决于你的具体需求,没有一种方法是最好的。

295
一个抽象函数必须被覆盖,而一个虚函数可以被覆盖。 - Jordan Parmer
17
虚函数可以在基类中具有默认/通用实现。 - Martin
7
关键词是“抽象”,它们并不存在,只是该函数的一个模糊概念(方法签名)。 - Cole Tobin
28个回答

1
如果一个类派生自这个抽象类,那么它就必须重写这个抽象成员。这与虚拟修饰符不同,后者指定该成员可以选择性地被重写。

1
答案已经提供了很多次,但是何时使用每个选项是设计时的决定。我认为将常见方法定义捆绑到不同的接口中,并在适当的抽象级别将它们拉入类中是一个好的实践。将一组通用的抽象和虚拟方法定义放入一个类中会使该类无法实例化,最好定义一个非抽象类来实现一组简洁的接口。像往常一样,这取决于最适合您的应用程序特定需求。

0

抽象函数或方法是类公开的“操作名称”,其目的与抽象类一样,主要是为了在对象设计中提供一种约束形式,以防止对象必须实现的结构。

事实上,继承自其抽象类的类必须对此方法进行实现,通常编译器在不这样做时会引发错误。

使用抽象类和方法的重要性主要在于避免在设计类时专注于实现细节,从而使类结构过于关联实现,从而在协作的类之间创建依赖和耦合。

虚函数或方法只是模拟类的公共行为的方法,但我们可以在继承链中自由修改它,因为我们认为子类可能需要为该行为实现某些特定的扩展。

它们都代表面向对象范例中的一种多态形式。

我们可以同时使用抽象方法和虚函数来支持良好的继承模型。

我们设计解决方案的主要对象的良好抽象结构,然后通过定位那些更容易进一步特化的基本实现来创建基本实现,并将这些实现作为虚拟实现,最后我们专门化我们的基本实现,最终“覆盖”继承的虚拟实现。


0

C# 中没有所谓的虚拟类。

对于函数:

  1. 抽象函数只有签名,派生类应该重写并添加功能。
  2. 虚函数将保留部分功能,派生类可以根据需要覆盖它或不覆盖它。

您可以根据自己的需求进行决定。


0

抽象方法没有实现,它在父类中声明。子类负责实现该方法。

虚方法应该在父类中有一个实现,并且它使得子类可以选择使用父类的实现或者在子类中为该方法拥有一个新的实现。


0

Traditional threefold classification of propositions

图。 — 传统三段论分类。

义务逻辑(义务和许可研究)中,每个命题都是 义务 (“必须” 运算符),可选(“可以或者不可以” 运算符),或者 不可允许(“必须不” 运算符),且没有任何一个命题同时属于这三类。

此外,可允许(“可以” 运算符)的命题是那些既是义务又是可选的,可省略(“不可以” 运算符)的命题是那些不可允许或可选的,而非可选(“必须或必须不” 运算符)的命题是那些既是义务又是不可允许的。

尤其是,一项义务性命题是可允许的,而一项不可允许的命题是可省略的。

将这些运算符应用于命题 “该方法已被覆盖” 可得到以下命题:

  • 抽象(纯虚)/具体方法:该方法必须被重写/不能被重写;
  • 虚拟/真实(最终)方法:该方法可以被重写/不能被重写。

特别地,抽象方法是虚拟的,而真实方法是具体的。


0

在这里,我写了一些示例代码,希望这可以作为一个相当具体的例子来展示接口、抽象类和普通类在非常基本的层面上的行为。如果您想将其用作演示,您也可以在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(){
    //
    //    }
    }
}

-4
据我理解:
抽象方法:
只有抽象类可以拥有抽象方法。派生类需要实现该方法,而且在类中不提供实现。
虚方法:
一个类可以声明这些方法并提供相应的实现。派生类需要实现该方法以覆盖它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接