抽象方法和虚方法有什么区别?
抽象方法和虚方法有什么区别? 在什么情况下建议使用抽象或虚拟方法? 哪一种是最好的方法?
What is the difference between an abstract method and a virtual method? In which cases is it recommended to use abstract or virtual methods? Which one is the best approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(27)
抽象函数不能具有功能。您基本上是说,任何子类都必须提供自己的此方法的版本,但是它太笼统,甚至无法尝试在父类中实现。
虚函数,基本上是说看,这里的功能对于子类来说可能足够好,也可能不够好。 因此,如果它足够好,请使用此方法,如果不是,则覆盖我,并提供您自己的功能。
An abstract function cannot have functionality. You're basically saying, any child class MUST give their own version of this method, however it's too general to even try to implement in the parent class.
A virtual function, is basically saying look, here's the functionality that may or may not be good enough for the child class. So if it is good enough, use this method, if not, then override me, and provide your own functionality.
抽象函数没有实现,只能在抽象类上声明。 这迫使派生类提供实现。
虚函数提供默认实现,它可以存在于抽象类或非抽象类中。
例如:
An abstract function has no implemention and it can only be declared on an abstract class. This forces the derived class to provide an implementation.
A virtual function provides a default implementation and it can exist on either an abstract class or a non-abstract class.
So for example:
abstract
类可以拥有abstract
成员。abstract
类继承的非abstract
类必须覆盖
其abstract
成员。abstract
成员隐式是virtual
。abstract
成员无法提供任何实现(abstract
在某些语言中称为pure virtual
)。abstract
classes can haveabstract
members.abstract
class that inherits from anabstract
class mustoverride
itsabstract
members.abstract
member is implicitlyvirtual
.abstract
member cannot provide any implementation (abstract
is calledpure virtual
in some languages).您必须始终重写抽象函数。
因此:
You must always override an abstract function.
Thus:
抽象函数:
方法声明而不是抽象类中的实现。
虚函数:
Abstract Function:
method declaration not the implementation in abstract class.
Virtual Function:
抽象方法:
当一个类包含抽象方法时,该类必须声明为抽象类。
抽象方法没有实现,因此从该抽象类派生的类必须提供该抽象方法的实现。
虚拟方法:
一个类可以有一个虚方法。 虚方法有一个实现。
当您从具有虚拟方法的类继承时,您可以重写该虚拟方法并提供额外的逻辑,或者用您自己的实现替换该逻辑。
何时使用什么:
在某些情况下,您知道某些类型应该有一个特定的方法,但是,您不知道这个方法应该有什么实现。
在这种情况下,您可以创建一个包含具有此签名的方法的接口。
但是,如果您有这种情况,但您知道该接口的实现者还将有另一个通用方法(您已经可以为其提供实现),则可以创建一个抽象类。
然后,该抽象类包含抽象方法(必须重写)和另一个包含“公共”逻辑的方法。
如果您有一个可以直接使用的类,但您希望继承者能够更改某些行为(尽管这不是强制性的),则应使用虚拟方法。
Abstract method:
When a class contains an abstract method, that class must be declared as abstract.
The abstract method has no implementation and thus, classes that derive from that abstract class, must provide an implementation for this abstract method.
Virtual method:
A class can have a virtual method. The virtual method has an implementation.
When you inherit from a class that has a virtual method, you can override the virtual method and provide additional logic, or replace the logic with your own implementation.
When to use what:
In some cases, you know that certain types should have a specific method, but, you don't know what implementation this method should have.
In such cases, you can create an interface which contains a method with this signature.
However, if you have such a case, but you know that implementors of that interface will also have another common method (for which you can already provide the implementation), you can create an abstract class.
This abstract class then contains the abstract method (which must be overriden), and another method which contains the 'common' logic.
A virtual method should be used if you have a class which can be used directly, but for which you want inheritors to be able to change certain behaviour, although it is not mandatory.
抽象方法是必须实现才能形成具体类的方法。 声明位于抽象类中(任何具有抽象方法的类都必须是抽象类)并且必须在具体类中实现。
虚拟方法是可以使用重写在派生类中重写的方法,替换超类中的行为。 如果您不覆盖,您将获得原始行为。 如果这样做,您总是会得到新的行为。 这与非虚拟方法相反,非虚拟方法不能被覆盖但可以隐藏原始方法。 这是使用
new
修饰符完成的。请参阅以下示例:
当我实例化
DerivedClass
并调用SayHello
或SayGoodbye
时,我得到“Hi There”和“See you later”。 如果我拨打HelloGoodbye
,我会收到“Hello”和“See you later”。 这是因为SayGoodbye
是虚拟的,可以用派生类替换。SayHello
只是隐藏的,所以当我从基类调用它时,我得到了原始方法。抽象方法是隐式虚拟的。 它们定义了必须存在的行为,更像是界面。
An abstract method is a method that must be implemented to make a concrete class. The declaration is in the abstract class (and any class with an abstract method must be an abstract class) and it must be implemented in a concrete class.
A virtual method is a method that can be overridden in a derived class using the override, replacing the behavior in the superclass. If you don't override, you get the original behavior. If you do, you always get the new behavior. This opposed to not virtual methods, that can not be overridden but can hide the original method. This is done using the
new
modifier.See the following example:
When I instantiate
DerivedClass
and callSayHello
, orSayGoodbye
, I get "Hi There" and "See you later". If I callHelloGoodbye
, I get "Hello" and "See you later". This is becauseSayGoodbye
is virtual, and can be replaced by derived classes.SayHello
is only hidden, so when I call that from my base class I get my original method.Abstract methods are implicitly virtual. They define behavior that must be present, more like an interface does.
抽象方法始终是虚拟的。 他们无法实施。
这是主要的区别。
基本上,如果您有虚拟方法的“默认”实现并且希望允许后代更改其行为,您将使用虚拟方法。
使用抽象方法,您可以强制后代提供实现。
Abstract methods are always virtual. They cannot have an implementation.
That's the main difference.
Basically, you would use a virtual method if you have the 'default' implementation of it and want to allow descendants to change its behaviour.
With an abstract method, you force descendants to provide an implementation.
我通过对以下类进行一些改进(来自其他答案)使这变得更简单:
I made this simpler by making some improvements on the following classes (from other answers):
绑定是将名称映射到代码单元的过程。
后期绑定意味着我们使用名称,但推迟映射。 换句话说,我们首先创建/提及名称,然后让某些后续进程处理代码到该名称的映射。
现在考虑一下:
所以,简短的答案是:
virtual
是机器的后期绑定指令(运行时)而abstract
是人类(程序员)的后期绑定指令。换句话说,
virtual
的意思是:“亲爱的运行时,绑定通过做你最擅长的事情来将适当的代码绑定到这个名字:搜索”
而
abstract
的意思是:“亲爱的程序员,请将适当的代码绑定到这个通过做你最擅长的事情来命名:发明”
为了完整起见,重载意味着:
“亲爱的编译器,将适当的代码绑定到此通过做你最擅长的事情来命名:排序”。
Binding is the process of mapping a name to a unit of code.
Late binding means that we use the name, but defer the mapping. In other words, we create/mention the name first, and let some subsequent process handle the mapping of code to that name.
Now consider:
So, the short answer is:
virtual
is a late binding instruction for the machine (runtime) whereasabstract
is the late binding instruction for the human (programmer)In other words,
virtual
means:“Dear runtime, bind the appropriate code to this name by doing what you do best: searching”
Whereas
abstract
means:“Dear programmer, please bind the appropriate code to this name by doing what you do best: inventing”
For the sake of completeness, overloading means:
“Dear compiler, bind the appropriate code to this name by doing what you do best: sorting”.
当您希望继承者根据需要扩展功能时,您基本上可以使用虚拟方法。
当您希望继承者实现功能时,您可以使用抽象方法(在这种情况下他们别无选择)
You basically use a virtual method when you want the inheritors to extend the functionality IF they want to.
You use abstract methods when you want the inheritors to implement the functionality (and in this case they have no choice)
虚拟方法:
虚拟意味着我们可以覆盖它。
虚拟函数有一个实现。 当我们继承该类时
可以重写虚函数并提供我们自己的逻辑。
子类中的函数(可以说是一个概念
阴影)。
抽象方法
抽象意味着我们必须重写它。
抽象函数没有实现,必须位于抽象类中。
只能声明。 这迫使派生类提供它的实现。
抽象成员是隐式虚拟的。 抽象在某些语言中可以称为纯虚拟。
Virtual Method:
Virtual means we CAN override it.
Virtual Function has an implementation. When we inherit the class we
can override the virtual function and provide our own logic.
function in the child class(which can be said as a concept of
Shadowing).
Abstract Method
Abstract means we MUST override it.
An abstract function has no implementation and must be in an abstract class.
It can only be declared. This forces the derived class to provide the implementation of it.
An abstract member is implicitly virtual. The abstract can be called as pure virtual in some of the languages.
我在某些地方看到抽象方法的定义如下。 **
**
我感觉就像是。
抽象方法不一定要在子类中实现,如果子类也是抽象的 ..
1) 抽象方法不能是私有方法。
2)抽象方法不能在同一个抽象类中实现。
我想说..如果我们要实现一个抽象类,您必须重写抽象基类中的抽象方法。
因为.. 实现抽象方法是用override关键字。类似于Virtual方法。
没有必要在继承类中实现虚方法。
I have seen in some places the abstract method is defined as below. **
**
I felt it is like .
It is not necessary that an abstract method has to be implemented in a child class, if the child class is also abstract ..
1)An abstract method cant be a private method.
2)An Abstract method cant be implemented in the same abstract class.
I would say ..if we are implementing an abstract class, you must have to override the abstract methods from the base abstract class.
Because.. Implementing the abstract method is with override key word .Similar to Virtual method.
It is not necessary for a virtual method to be implemented in an inherited class.
上面的大多数示例都使用代码 - 而且它们非常非常好。 我不需要补充他们所说的内容,但以下是使用类比而不是代码/技术术语的简单解释。
简单解释 - 使用类比进行解释
抽象方法
想想乔治·W·布什。 他对他的士兵说:“去伊拉克战斗吧”。 就是这样。 他所指定的只是必须进行战斗。 他没有具体说明这将如何发生。 但我的意思是,你不能只是出去“战斗”:这到底意味着什么? 我该用 B-52 作战还是用我的德林格战机作战? 这些具体细节留给其他人。 这是一个抽象方法。
虚拟方法
大卫·彼得雷乌斯 (David Petraeus) 在军队中身居高位。 他定义了战斗的含义:
问题是这是一个非常通用的方法。 这是一个有效的好方法,但有时不够具体。 对彼得雷乌斯来说,好处是他的命令有回旋余地和范围——他允许其他人根据他们的具体要求改变他对“战斗”的定义。
私人工作博客阅读了彼得雷乌斯的命令,并被允许根据他的特殊要求实施他自己的战斗版本:
努里·马利基也收到了彼得雷乌斯的同样命令。 他也要战斗。 但他是一名政治家,而不是一名步兵。 显然,他不能四处射击他的政敌。 因为彼得雷乌斯给了他一个虚拟方法,那么马利基就可以根据他的具体情况实现他自己版本的战斗方法:
换句话说,虚拟方法提供了样板指令 - 但这些是一般指令,可以由军队等级制度下的人们根据他们的具体情况制定更具体的指令。
两者的区别
乔治·布什没有证明任何实现细节。 这必须由其他人提供。 这是一个抽象方法。
另一方面,彼得雷乌斯确实提供了实施细节,但他允许他的下属用他们自己的版本覆盖他的命令,如果他们能想出更好的东西的话。
希望有帮助。
Most of the above examples use code - and they are very very good. I need not add to what they say, but the following is a simple explanation that makes use of analogies rather than code/technical terms.
Simple Explanation - Explanation using analogies
Abstract Method
Think George W Bush. He says to his soldiers: "Go fight in Iraq". And that's it. All he has specified is that fighting must be done. He does not specify how exactly that will happen. But I mean, you can't just go out and "fight": what does that mean exactly? do I fight with a B-52 or my derringer? Those specific details are left to someone else. This is an abstract method.
Virtual Method
David Petraeus is high up in the army. He has defined what fight means:
The problem is that it is a very general method. It's a good method that works, but sometimes is not specific enough. Good thing for Petraeus is that his orders have leeway and scope - he has allowed others to change his definition of "fight", according to their particular requirements.
Private Job Bloggs reads Petraeus' order and is given permission to implement his own version of fight, according to his particular requirements:
Nouri al Maliki also receives the same orders from Petraeus. He is to fight also. But he is a politician, not an infantry man. Obviously he cannot go around shooting his politican enemies in the head. Because Petraeus has given him a virtual method, then Maliki can implement his own version of the fight method, according to his particular circumstances:
IN other words, a virtual method provides boilerplate instructions - but these are general instructions, which can be made more specific by people down the army heirarchy, according to their particular circumstances.
The difference between the two
George Bush does not prove any implementation details. This must be provided by someone else. This is an abstract method.
Petraeus on the other hand does provide implementation details but he has given permission for his subordinates to override his orders with their own version, if they can come up with something better.
hope that helps.
抽象函数(方法):
● 抽象方法是用关键字abstract 声明的方法。
● 没有本体。
● 应由派生类实现。
● 如果方法是抽象的,则该类也应该是抽象的。
虚函数(方法):
● 虚方法是用关键字virtual 声明的方法,并且可以通过使用override 关键字被派生类方法覆盖。
● 是否覆盖它取决于派生类。
Abstract function(method) :
● An abstract method is a method which is declared with the keyword abstract.
● It does not have body.
● It should be implemented by the derived class.
● If a method is abstract then the class should abstract.
virtual function(method) :
● A virtual method is the method which is declared with the keyword virtual and it can be overridden by the derived class method by using override keyword.
● It's up to the derived class whether to override it or not.
答案已经提供了多次,但何时使用每个答案的问题是设计时的决定。 我认为尝试将通用方法定义捆绑到不同的接口中并将它们拉入适当抽象级别的类中是一种很好的做法。 当最好定义一个实现一组简洁接口的非抽象类时,将一组通用的抽象和虚拟方法定义转储到一个类中会使该类变得不可实例化。 与往常一样,这取决于最适合您应用程序特定需求的方式。
The answer has been provided a number of times but the the question about when to use each is a design-time decision. I would see it as good practice to try to bundle common method definitions into distinct interfaces and pull them into classes at appropriate abstraction levels. Dumping a common set of abstract and virtual method definitions into a class renders the class unistantiable when it may be best to define a non-abstract class that implements a set of concise interfaces. As always, it depends on what best suits your applications specific needs.
抽象函数不能有主体,并且必须被子类重写
虚拟函数将有主体,并且可能会也可能不会被子类重写
Abstract function cannot have a body and MUST be overridden by child classes
Virtual Function will have a body and may or may not be overridden by child classes
从一般面向对象的角度来看:
关于抽象方法:当你在父类中放置一个抽象方法时,你实际上是在对子类说:嘿,请注意,你有一个像这样的方法签名。 如果你想使用它,你应该实现你自己的!
关于虚函数:当您将虚方法放入父类中时,您就是在对派生类说:嘿,这里有一个功能可以为您做一些事情。 如果这对您有用,请使用它。 如果没有,请覆盖它并实现您的代码,甚至您可以在您的代码中使用我的实现!
这是关于通用 OO 中这两个概念之间差异的一些哲学
From general object oriented view:
Regarding abstract method: When you put an abstract method in the parent class actually your are saying to the child classes: Hey note that you have a method signature like this. And if you wanna to use it you should implement your own!
Regarding virtual function: When you put a virtual method in the parent class you are saying to the derived classes : Hey there is a functionality here that do something for you. If this is useful for you just use it. If not, override this and implement your code, even you can use my implementation in your code !
this is some philosophy about different between this two concept in General OO
抽象函数“只是”一个签名,没有实现。
它在接口中用于声明如何使用该类。
它必须在派生类之一中实现。
虚函数(实际上是方法)也是您声明的函数,并且应该在继承层次结构类之一中实现。
此类的继承实例也会继承实现,除非您在较低层次结构的类中实现它。
An abstract function is "just" a signature, without an implementation.
It is used in an interface to declare how the class can be used.
It must be implemented in one of the derived classes.
Virtual function (method actually), is a function you declare as well, and should implemented in one of the inheritance hierarchy classes.
The inherited instances of such class, inherit the implementation as well, unless you implement it, in a lower hierarchy class.
从C++背景来看,C#的虚函数对应于C++的虚函数,而C#的抽象方法则对应于C++的纯虚函数
From a C++ background, C# virtual corresponds to C++ virtual, while C# abstract methods corresponds to C++ pure virtual function
如果一个类派生自该抽象类,则它必须重写该抽象成员。 这与 virtual 修饰符不同,virtual 修饰符指定可以选择覆盖该成员。
If a class derives from this abstract class, it is then forced to override the abstract member. This is different from the virtual modifier, which specifies that the member may optionally be overridden.
C# 中没有所谓的虚拟类。
对于
您可以根据您的要求决定。
There are nothing call virtual class in C#.
For functions
You can decide with your requirement.
抽象方法没有实现。它在父类中声明。 子类负责实现该方法。
虚方法应该在父类中有一个实现,它方便子类选择是使用父类的该实现还是在子类中为该方法自己拥有一个新的实现。
Abstract method doesnt have an implementation.It is declared in the parent class. The child class is resposible for implementing that method.
Virtual method should have an implementation in the parent class and it facilitates the child class to make the choice whether to use that implementation of the parent class or to have a new implementation for itself for that method in child class.
抽象函数或方法是类公开的公共“操作名称”,其目的与抽象类一起,主要是在对象设计中针对对象必须遵循的结构提供一种约束形式实施。
事实上,从其抽象类继承的类必须提供此方法的实现,通常编译器在不实现时会引发错误。
使用抽象类和方法很重要,主要是为了避免在设计类时关注实现细节,类结构与实现过于相关,从而在相互协作的类之间创建依赖关系和耦合。
虚函数或方法只是一个模拟类公共行为的方法,但我们可以在继承链中自由修改它,因为我们认为子类可能需要实现该行为的一些特定扩展。
它们都代表了面向对象范式中的一种多态形式。
我们可以结合使用抽象方法和虚函数来支持良好的继承模型。
我们为解决方案的主要对象设计了一个良好的抽象结构,然后通过定位那些更容易进一步专业化的对象来创建基本实现,并将这些实现作为虚拟实现,最后我们专门化我们的基本实现,最终“覆盖”继承的虚拟实现。
An abstract function or method is a public "operation's name" exposed by a class, its aim, along with abstract classes, is primarily provide a form of constraint in objects design against the structure that an object have to implement.
In fact the classes that inherit from its abstract class have to give an implementation to this method, generally compilers raise errors when they don't.
Using abstract classes and methods is important mostly to avoid that by focusing on implementation details when designing classes, the classes structure be too related to the implementations, so creating dependences and coupling between classes that collaborate among them.
A virtual function or method is simply a method that models a public behaviour of a class, but that we can leave free to modify it in the inheritance chain, because we think that child classes could have need to implement some specific extensions for that behaviour.
They both represent a form of polymorpfhism in object orientation paradigm.
We can use abstract methods and virtual functions together to support a good inheritance model.
We design a good abstract structure of main objects of our solution, then create basic implementations by locating those more prone to further specializations and we make these ones as virtuals, finally we specialize our basic implementations, eventyually "overriding" inherited virtual ones.
在这里,我编写了一些示例代码,希望这可能是一个相当具体的示例,可以在非常基本的层面上了解接口、抽象类和普通类的行为。 如果您想将其用作演示,您还可以在 github 中找到此代码作为项目: https://github .com/usavas/JavaAbstractAndInterfaceDemo
Here I am writing some sample code hoping this may be a rather tangible example to see the behaviors of the interfaces, abstract classes and ordinary classes on a very basic level. You can also find this code in github as a project if you want to use it as a demo: https://github.com/usavas/JavaAbstractAndInterfaceDemo
图——传统的三重命题分类。
在道义逻辑(对义务和许可的研究)中,每个命题都是强制(“必须”运算符)、可选(“可能和可能不”运算符)或不允许(“不得”运算符),并且没有一个命题属于这三个类别中的一个以上。
此外,允许(“可以”运算符)命题是那些强制性或可选的命题,可忽略(“可能不”运算符)命题是那些不允许或可选的命题,以及非可选(“必须或不能”运算符)命题是那些强制或不允许的命题。
特别是,强制性命题是允许的,而不允许的命题是可省略的。
将这些运算符应用于命题“该方法被重写”会产生以下命题:
具体来说,抽象方法是虚拟的,而真实方法是具体的。
Figure. — Traditional threefold classification of propositions.
In deontic logic (the study of obligation and permission), every proposition is obligatory (‘must’ operator), optional (‘may and may not’ operator), or impermissible (‘must not’ operator), and no proposition falls into more than one of these three categories.
Furthermore, the permissible (‘may’ operator) propositions are those that are obligatory or optional, the omissible (‘may not’ operator) propositions are those that are impermissible or optional, and the non-optional (‘must or must not’ operator) propositions are those that are obligatory or impermissible.
In particular, an obligatory proposition is permissible, and an impermissible proposition is omissible.
Applying those operators to the proposition ’the method is overridden’ yields the following propositions:
In particular, an abstract method is virtual, and a real method is concrete.
据我的理解:
抽象方法:
只有抽象类才能保存抽象方法。 派生类也需要实现该方法,并且类中没有提供实现。
虚拟方法:
类可以声明这些方法并提供它们的实现。 派生类还需要实现该方法来重写它。
To my understanding:
Abstract Methods:
Only the abstract class can hold abstract methods. Also the derived class need to implement the method and no implementation is provided in the class.
Virtual Methods:
A class can declare these and also provide the implementation of the same. Also the derived class need to implement of the method to override it.