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


当前回答

抽象方法:当类包含抽象方法时,该类必须声明为抽象的。抽象方法没有实现,因此派生自该抽象类的类必须为该抽象方法提供实现。

虚拟方法:类可以具有虚拟方法。虚拟方法有一个实现。当从具有虚拟方法的类继承时,可以重写虚拟方法并提供额外的逻辑,或者用自己的实现替换逻辑。

何时使用什么:在某些情况下,您知道某些类型应该有一个特定的方法,但您不知道该方法应该有什么实现。在这种情况下,您可以创建包含具有此签名的方法的接口。然而,如果您有这样的情况,但您知道该接口的实现者也将有另一个通用方法(您已经可以为其提供实现),那么您可以创建一个抽象类。然后,这个抽象类包含抽象方法(必须重写)和另一个包含“公共”逻辑的方法。

如果您有一个可以直接使用的类,但您希望继承者能够更改某些行为,则应使用虚拟方法,尽管这不是强制性的。

其他回答

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

虚拟方法应该在父类中有一个实现,它有助于子类选择是使用父类的该实现,还是为子类中的该方法自己有一个新的实现。

解释:用类比。希望这对你有帮助。

上下文

我在一栋楼的21层工作。我对火很偏执。时不时地,在世界的某个地方,一场大火正在烧毁一座摩天大楼。但幸运的是,我们在这里有一本指导手册,说明发生火灾时该怎么做:

FireEscape()

不要收集物品步行至消防通道走出大楼

这基本上是一个名为FireEscape()的虚拟方法

虚拟方法

这个计划对99%的情况都很好。这是一个可行的基本计划。但有1%的可能性是消防通道被堵塞或损坏,在这种情况下,你会彻底完蛋,除非你采取一些激烈的行动,否则你会被烤焦。使用虚拟方法,您可以做到这一点:您可以使用自己版本的计划覆盖基本的FireEscape()计划:

运行到窗口跳出窗口降落伞安全到达底部

换句话说,虚拟方法提供了一个基本的计划,如果需要的话可以重写。如果程序员认为合适,子类可以重写父类的虚拟方法。

抽象方法

并非所有组织都训练有素。一些组织不进行消防演习。他们没有全面的逃跑政策。每个人都是为了自己。管理层只对现有的这种政策感兴趣。

换句话说,每个人都被迫开发自己的FireEscape()方法。一个人会走出消防通道。另一个人会跳伞。另一个人将使用火箭推进技术飞离大楼。另一个人会用绳索离开。管理层不在乎你如何逃跑,只要你有一个基本的FireEscape()计划——如果他们不这样做,你可以保证OHS会像一吨砖头一样砸在组织身上。这就是抽象方法的含义。

这两者又有什么区别?

抽象方法:子类被迫实现自己的FireEscape方法。使用虚拟方法,你有一个基本的计划等着你,但如果不够好,你可以选择实施自己的计划。

现在这并不难,是吗?

抽象函数(方法):

● 抽象方法是用关键字abstract声明的方法。

● 它没有身体。

● 它应该由派生类实现。

● 如果方法是抽象的,那么类应该是抽象的。

虚拟函数(方法):

● 虚方法是用关键字virtual声明的方法,它可以通过使用override关键字由派生类方法重写。

● 是否重写它取决于派生类。

只有抽象类才能有抽象成员。从抽象类继承的非抽象类必须重写其抽象成员。抽象成员是隐式虚拟的。抽象成员不能提供任何实现(抽象在某些语言中称为纯虚拟)。

绑定是将名称映射到代码单元的过程。

后期绑定意味着我们使用名称,但延迟映射。换言之,我们首先创建/提及名称,然后让后续流程处理代码到该名称的映射。

现在考虑:

与人类相比,机器确实擅长搜索和排序与机器相比,人类确实擅长发明和创新

因此,简单的答案是:virtual是机器(运行时)的后期绑定指令,而abstract是人类(程序员)的后期约束指令

换句话说,虚拟意味着:

亲爱的运行时,通过执行您最擅长的操作将适当的代码绑定到此名称:搜索

抽象意味着:

亲爱的程序员,请尽你所能将适当的代码绑定到这个名字上:发明

为完整起见,重载意味着:

“亲爱的编译器,通过做你最擅长的事情,将适当的代码绑定到这个名称:排序”。