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

发布于 2024-07-17 22:17:00 字数 53 浏览 11 评论 0原文

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

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(27

此生挚爱伱 2024-07-24 22:17:00

抽象函数不能具有功能。您基本上是说,任何子类都必须提供自己的此方法的版本,但是它太笼统,甚至无法尝试在父类中实现。

虚函数,基本上是说看,这里的功能对于子类来说可能足够好,也可能不够好。 因此,如果它足够好,请使用此方法,如果不是,则覆盖我,并提供您自己的功能。

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.

秋意浓 2024-07-24 22:17:00

抽象函数没有实现,只能在抽象类上声明。 这迫使派生类提供实现。

虚函数提供默认实现,它可以存在于抽象类或非抽象类中。

例如:

public abstract class myBase
{
    //If you derive from this class you must implement this method. notice we have no method body here either
    public abstract void YouMustImplement();

    //If you derive from this class you can change the behavior but are not required to
    public virtual void YouCanOverride()
    { 
    }
}

public class MyBase
{
   //This will not compile because you cannot have an abstract method in a non-abstract class
    public abstract void YouMustImplement();
}

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:

public abstract class myBase
{
    //If you derive from this class you must implement this method. notice we have no method body here either
    public abstract void YouMustImplement();

    //If you derive from this class you can change the behavior but are not required to
    public virtual void YouCanOverride()
    { 
    }
}

public class MyBase
{
   //This will not compile because you cannot have an abstract method in a non-abstract class
    public abstract void YouMustImplement();
}
因为看清所以看轻 2024-07-24 22:17:00
  1. 只有abstract 类可以拥有abstract 成员。
  2. abstract 类继承的非abstract必须覆盖abstract成员。
  3. abstract 成员隐式是virtual
  4. abstract 成员无法提供任何实现(abstract 在某些语言中称为 pure virtual)。
  1. Only abstract classes can have abstract members.
  2. A non-abstract class that inherits from an abstract class must override its abstract members.
  3. An abstract member is implicitly virtual.
  4. An abstract member cannot provide any implementation (abstract is called pure virtual in some languages).
羁拥 2024-07-24 22:17:00

您必须始终重写抽象函数。

因此:

  • 抽象函数 - 当继承者必须提供自己的实现
  • 虚拟 - 当由继承者决定时强>

You must always override an abstract function.

Thus:

  • Abstract functions - when the inheritor must provide its own implementation
  • Virtual - when it is up to the inheritor to decide
请帮我爱他 2024-07-24 22:17:00

抽象函数:

  1. 只能在抽象类中声明。
  2. 它仅包含
    方法声明而不是抽象类中的实现。
  3. 必须在派生类中重写它。

虚函数:

  1. 可以在抽象类和非抽象类中声明。
  2. 它包含方法实现。
  3. 它可能会被覆盖。

Abstract Function:

  1. It can be declared only inside abstract class.
  2. It contains only
    method declaration not the implementation in abstract class.
  3. It must be overridden in derived class.

Virtual Function:

  1. It can be declared inside abstract as well as non abstract class.
  2. It contains method implementation.
  3. It may be overridden.
a√萤火虫的光℡ 2024-07-24 22:17:00

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

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

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

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

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.

黑寡妇 2024-07-24 22:17:00

抽象方法是必须实现才能形成具体类的方法。 声明位于抽象类中(任何具有抽象方法的类都必须是抽象类)并且必须在具体类中实现。

虚拟方法是可以使用重写在派生类中重写的方法,替换超类中的行为。 如果您不覆盖,您将获得原始行为。 如果这样做,您总是会得到新的行为。 这与非虚拟方法相反,非虚拟方法不能被覆盖但可以隐藏原始方法。 这是使用 new 修饰符完成的。

请参阅以下示例:

public class BaseClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello");
    }


    public virtual void SayGoodbye()
    {
        Console.WriteLine("Goodbye");
    }

    public void HelloGoodbye()
    {
        this.SayHello();
        this.SayGoodbye();
    }
}


public class DerivedClass : BaseClass
{
    public new void SayHello()
    {
        Console.WriteLine("Hi There");
    }


    public override void SayGoodbye()
    {
        Console.WriteLine("See you later");
    }
}

当我实例化 DerivedClass 并调用 SayHelloSayGoodbye 时,我得到“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:

public class BaseClass
{
    public void SayHello()
    {
        Console.WriteLine("Hello");
    }


    public virtual void SayGoodbye()
    {
        Console.WriteLine("Goodbye");
    }

    public void HelloGoodbye()
    {
        this.SayHello();
        this.SayGoodbye();
    }
}


public class DerivedClass : BaseClass
{
    public new void SayHello()
    {
        Console.WriteLine("Hi There");
    }


    public override void SayGoodbye()
    {
        Console.WriteLine("See you later");
    }
}

When I instantiate DerivedClass and call SayHello, or SayGoodbye, I get "Hi There" and "See you later". If I call HelloGoodbye, I get "Hello" and "See you later". This is because SayGoodbye 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.

纸伞微斜 2024-07-24 22:17:00

抽象方法始终是虚拟的。 他们无法实施。

这是主要的区别。

基本上,如果您有虚拟方法的“默认”实现并且希望允许后代更改其行为,您将使用虚拟方法。

使用抽象方法,您可以强制后代提供实现。

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.

赴月观长安 2024-07-24 22:17:00

我通过对以下类进行一些改进(来自其他答案)使这变得更简单:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestOO
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass _base = new BaseClass();
            Console.WriteLine("Calling virtual method directly");
            _base.SayHello();
            Console.WriteLine("Calling single method directly");
            _base.SayGoodbye();

            DerivedClass _derived = new DerivedClass();
            Console.WriteLine("Calling new method from derived class");
            _derived.SayHello();
            Console.WriteLine("Calling overrided method from derived class");
            _derived.SayGoodbye();

            DerivedClass2 _derived2 = new DerivedClass2();
            Console.WriteLine("Calling new method from derived2 class");
            _derived2.SayHello();
            Console.WriteLine("Calling overrided method from derived2 class");
            _derived2.SayGoodbye();
            Console.ReadLine();
        }
    }


    public class BaseClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }
        public virtual void SayGoodbye()
        {
            Console.WriteLine("Goodbye\n");
        }

        public void HelloGoodbye()
        {
            this.SayHello();
            this.SayGoodbye();
        }
    }


    public abstract class AbstractClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }


        //public virtual void SayGoodbye()
        //{
        //    Console.WriteLine("Goodbye\n");
        //}
        public abstract void SayGoodbye();
    }


    public class DerivedClass : BaseClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }

        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }

    public class DerivedClass2 : AbstractClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }
        // We should use the override keyword with abstract types
        //public new void SayGoodbye()
        //{
        //    Console.WriteLine("See you later2");
        //}
        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }
}

I made this simpler by making some improvements on the following classes (from other answers):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestOO
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass _base = new BaseClass();
            Console.WriteLine("Calling virtual method directly");
            _base.SayHello();
            Console.WriteLine("Calling single method directly");
            _base.SayGoodbye();

            DerivedClass _derived = new DerivedClass();
            Console.WriteLine("Calling new method from derived class");
            _derived.SayHello();
            Console.WriteLine("Calling overrided method from derived class");
            _derived.SayGoodbye();

            DerivedClass2 _derived2 = new DerivedClass2();
            Console.WriteLine("Calling new method from derived2 class");
            _derived2.SayHello();
            Console.WriteLine("Calling overrided method from derived2 class");
            _derived2.SayGoodbye();
            Console.ReadLine();
        }
    }


    public class BaseClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }
        public virtual void SayGoodbye()
        {
            Console.WriteLine("Goodbye\n");
        }

        public void HelloGoodbye()
        {
            this.SayHello();
            this.SayGoodbye();
        }
    }


    public abstract class AbstractClass
    {
        public void SayHello()
        {
            Console.WriteLine("Hello\n");
        }


        //public virtual void SayGoodbye()
        //{
        //    Console.WriteLine("Goodbye\n");
        //}
        public abstract void SayGoodbye();
    }


    public class DerivedClass : BaseClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }

        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }

    public class DerivedClass2 : AbstractClass
    {
        public new void SayHello()
        {
            Console.WriteLine("Hi There");
        }
        // We should use the override keyword with abstract types
        //public new void SayGoodbye()
        //{
        //    Console.WriteLine("See you later2");
        //}
        public override void SayGoodbye()
        {
            Console.WriteLine("See you later");
        }
    }
}
梦忆晨望 2024-07-24 22:17:00

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

后期绑定意味着我们使用名称,但推迟映射。 换句话说,我们首先创建/提及名称,然后让某些后续进程处理代码到该名称的映射。

现在考虑一下:

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

所以,简短的答案是: 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:

  • Compared to humans, machines are really good at searching and sorting
  • Compared to machines, humans are really good at invention and innovation

So, the short answer is: virtual is a late binding instruction for the machine (runtime) whereas abstract 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”.

我的影子我的梦 2024-07-24 22:17:00

当您希望继承者根据需要扩展功能时,您基本上可以使用虚拟方法。

当您希望继承者实现功能时,您可以使用抽象方法(在这种情况下他们别无选择)

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)

碍人泪离人颜 2024-07-24 22:17:00

虚拟方法

  • 虚拟意味着我们可以覆盖它。

  • 虚拟函数有一个实现。 当我们继承该类时
    可以重写虚函数并提供我们自己的逻辑。

  • 我们可以在实现时更改虚函数的返回类型
    子类中的函数(可以说是一个概念
    阴影)。

抽象方法

  • 抽象意味着我们必须重写它。

  • 抽象函数没有实现,必须位于抽象类中。

  • 只能声明。 这迫使派生类提供它的实现。

  • 抽象成员是隐式虚拟的。 抽象在某些语言中可以称为纯虚拟。

    公共抽象类BaseClass 
      {  
          受保护的抽象无效 xAbstractMethod(); 
    
          公共虚拟无效xVirtualMethod() 
          { 
              var x = 3 + 4; 
          } 
      }  
      

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.

  • We can change the return type of Virtual function while implementing the
    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.

    public abstract class BaseClass
    { 
        protected abstract void xAbstractMethod();
    
        public virtual void xVirtualMethod()
        {
            var x = 3 + 4;
        }
    } 
    
冰魂雪魄 2024-07-24 22:17:00

我在某些地方看到抽象方法的定义如下。 **

“抽象方法必须在子类中实现”

**
我感觉就像是。

抽象方法不一定要在子类中实现,如果子类也是抽象的 ..

1) 抽象方法不能是私有方法。
2)抽象方法不能在同一个抽象类中实现。

我想说..如果我们要实现一个抽象类,您必须重写抽象基类中的抽象方法。
因为.. 实现抽象方法是用override关键字。类似于Virtual方法。

没有必要在继承类中实现虚方法。

                                 ----------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();
    }
}

I have seen in some places the abstract method is defined as below. **

"An Abstract Method must have to implement in the child class"

**
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.

                                 ----------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();
    }
}
潜移默化 2024-07-24 22:17:00

上面的大多数示例都使用代码 - 而且它们非常非常好。 我不需要补充他们所说的内容,但以下是使用类比而不是代码/技术术语的简单解释。

简单解释 - 使用类比进行解释

抽象方法

想想乔治·W·布什。 他对他的士兵说:“去伊拉克战斗吧”。 就是这样。 他所指定的只是必须进行战斗。 他没有具体说明这将如何发生。 但我的意思是,你不能只是出去“战斗”:这到底意味着什么? 我该用 B-52 作战还是用我的德林格战机作战? 这些具体细节留给其他人。 这是一个抽象方法。

虚拟方法

大卫·彼得雷乌斯 (David Petraeus) 在军队中身居高位。 他定义了战斗的含义:

  1. 找到敌人
  2. 并压制他。
  3. 之后喝杯啤酒

问题是这是一个非常通用的方法。 这是一个有效的好方法,但有时不够具体。 对彼得雷乌斯来说,好处是他的命令有回旋余地和范围——他允许其他人根据他们的具体要求改变他对“战斗”的定义。

私人工作博客阅读了彼得雷乌斯的命令,并被允许根据他的特殊要求实施他自己的战斗版本:

  1. 找到敌人。
  2. 朝他的头开枪。
  3. 回家
  4. 喝啤酒吧

努里·马利基也收到了彼得雷乌斯的同样命令。 他也要战斗。 但他是一名政治家,而不是一名步兵。 显然,他不能四处射击他的政敌。 因为彼得雷乌斯给了他一个虚拟方法,那么马利基就可以根据他的具体情况实现他自己版本的战斗方法:

  1. 找到敌人。
  2. 用一些胡言乱语捏造的罪名逮捕他。
  3. 回家
  4. 喝啤酒吧

换句话说,虚拟方法提供了样板指令 - 但这些是一般指令,可以由军队等级制度下的人们根据他们的具体情况制定更具体的指令。

两者的区别

  • 乔治·布什没有证明任何实现细节。 这必须由其他人提供。 这是一个抽象方法。

  • 另一方面,彼得雷乌斯确实提供了实施细节,但他允许他的下属用他们自己的版本覆盖他的命令,如果他们能想出更好的东西的话。

希望有帮助。

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:

  1. Find the enemy
  2. Neutralise him.
  3. Have a beer afterwards

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:

  1. Find enemy.
  2. Shoot him in the head.
  3. Go Home
  4. Have beer.

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:

  1. Find enemy.
  2. Have him arrested with some BS trumped up charges.
  3. Go Home
  4. Have beer.

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.

雨后咖啡店 2024-07-24 22:17:00

抽象函数(方法):

● 抽象方法是用关键字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.

守望孤独 2024-07-24 22:17:00

答案已经提供了多次,但何时使用每个答案的问题是设计时的决定。 我认为尝试将通用方法定义捆绑到不同的接口中并将它们拉入适当抽象级别的类中是一种很好的做法。 当最好定义一个实现一组简洁接口的非抽象类时,将一组通用的抽象和虚拟方法定义转储到一个类中会使该类变得不可实例化。 与往常一样,这取决于最适合您应用程序特定需求的方式。

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.

盗琴音 2024-07-24 22:17:00

抽象函数不能有主体,并且必须被子类重写

虚拟函数将有主体,并且可能会也可能不会被子类重写

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

那请放手 2024-07-24 22:17:00

从一般面向对象的角度来看:

关于抽象方法:当你在父类中放置一个抽象方法时,你实际上是在对子类说:嘿,请注意,你有一个像这样的方法签名。 如果你想使用它,你应该实现你自己的!

关于虚函数:当您将虚方法放入父类中时,您就是在对派生类说:嘿,这里有一个功能可以为您做一些事情。 如果这对您有用,请使用它。 如果没有,请覆盖它并实现您的代码,甚至您可以在您的代码中使用我的实现!

这是关于通用 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

自此以后,行同陌路 2024-07-24 22:17:00

抽象函数“只是”一个签名,没有实现。
它在接口中用于声明如何使用该类。
它必须在派生类之一中实现。

虚函数(实际上是方法)也是您声明的函数,并且应该在继承层次结构类之一中实现。

此类的继承实例也会继承实现,除非您在较低层次结构的类中实现它。

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.

樱花细雨 2024-07-24 22:17:00

从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

风柔一江水 2024-07-24 22:17:00

如果一个类派生自该抽象类,则它必须重写该抽象成员。 这与 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.

总攻大人 2024-07-24 22:17:00

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

对于

  1. 只有签名的抽象函数,驱动类应该用功能重写。
  2. 虚拟功能将保留驱动器类可能会或可能不会根据要求覆盖它的部分功能,

您可以根据您的要求决定。

There are nothing call virtual class in C#.

For functions

  1. Abstract function only have signature only,the drive class should override with functionality.
  2. Virtual function will hold the part of functionality the drive class may or may not override it according to the requirement

You can decide with your requirement.

假面具 2024-07-24 22:17:00

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

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

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.

泼猴你往哪里跑 2024-07-24 22:17:00

抽象函数或方法是类公开的公共“操作名称”,其目的与抽象类一起,主要是在对象设计中针对对象必须遵循的结构提供一种约束形式实施。

事实上,从其抽象类继承的类必须提供此方法的实现,通常编译器在不实现时会引发错误。

使用抽象类和方法很重要,主要是为了避免在设计类时关注实现细节,类结构与实现过于相关,从而在相互协作的类之间创建依赖关系和耦合。

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

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

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

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

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.

我最亲爱的 2024-07-24 22:17:00

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

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

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(){
    //
    //    }
    }
}
§普罗旺斯的薰衣草 2024-07-24 22:17:00

传统三重命题分类

——传统的三重命题分类。

道义逻辑(对义务和许可的研究)中,每个命题都是强制(“必须”运算符)、可选(“可能和可能不”运算符)或不允许(“不得”运算符),并且没有一个命题属于这三个类别中的一个以上。

此外,允许(“可以”运算符)命题是那些强制性或可选的命题,可忽略(“可能不”运算符)命题是那些不允许或可选的命题,以及非可选(“必须或不能”运算符)命题是那些强制或不允许的命题。

特别是,强制性命题是允许的,而不允许的命题是可省略的。

将这些运算符应用于命题“该方法被重写”会产生以下命题:

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

具体来说,抽象方法是虚拟的,而真实方法是具体的。

Traditional threefold classification of propositions

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:

  • abstract (pure)/concrete method: the method must be overridden/may not be overridden;
  • virtual/real (final) method: the method may be overridden/must not be overridden.

In particular, an abstract method is virtual, and a real method is concrete.

仲春光 2024-07-24 22:17:00

据我的理解:

抽象方法:

只有抽象类才能保存抽象方法。 派生类也需要实现该方法,并且类中没有提供实现。

虚拟方法:

类可以声明这些方法并提供它们的实现。 派生类还需要实现该方法来重写它。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文