从抽象类和非抽象类派生的差异

时间:2022-09-25 07:41:41

In OOP, I see a lot of classes which derive from parent classes, but the parent classes are not marked as abstract. When the class IS marked as abstract, what advantage does this provide?

在OOP中,我看到很多类派生自父类,但父类没有标记为抽象类。当类IS标记为抽象时,它提供了什么优势?

Thanks

6 个解决方案

#1


The difference is really pretty pragmatic: an abstract base class is one that is never intended to be instantiated, and so needn't necessarily provide complete implementations. This means the ABC can define a contract for derived classes without implementing the class.

差异非常实用:抽象基类是一个从不打算实例化的基类,因此不必提供完整的实现。这意味着ABC可以在不实现类的情况下为派生类定义合约。

This is convenient in two ways:

这有两种方便:

  • you can define abstract objects that don't have the full implementation but make assertions about the whole class. One example of this is to have a DrawItem class with a draw() method that's the base class for Circle, Rectangle, and so on. DrawItem can't know how to draw itself, because it doesn't know what it is.

    您可以定义没有完整实现但是对整个类进行断言的抽象对象。这方面的一个例子是让DrawItem类具有draw()方法,该方法是Circle,Rectangle等的基类。 DrawItem不知道如何绘制自己,因为它不知道它是什么。

  • you can define classes for which you can have two concrete implementations. This shows up in the Proxy pattern, and can also be used to build, for example, mock objects for testing.

    您可以定义可以具有两个具体实现的类。这显示在代理模式中,也可用于构建例如用于测试的模拟对象。

It's more common these days for new languages to define interfaces or modules or mixins for these things; it turns out that using ABCs almost always fall into the use cases for those more intuitive concepts.

现在,新语言为这些东西定义接口或模块或混合更为常见;事实证明,使用ABC几乎总是属于那些更直观的概念的用例。

#2


Paul Haahr has interesting suggestions, such as:

Paul Haahr提出了有趣的建议,例如:

Don't subclass concrete classes

不要对具体类进行子类化

(read the original, I don't want to copy and paste everything;-).

(阅读原文,我不想复制和粘贴一切;-)。

Paul's writing about Java, but I found at least this part of his advice is applicable to most any OO design task (though pragmatically I still occasionally deviate from it in coding, it's alive and well in my design;-), even when I'm going to implement it in C++, Python, or whatever. If, after reading Paul's reasoning, you find yourself agreeing with him, you're going to be using a lot more abstract classes in the future (to allow subclassing;-).

Paul写了关于Java的文章,但我发现至少他的这部分建议适用于大多数OO设计任务(虽然实际上我仍然偶尔会在编码时偏离它,它在我的设计中很活跃;-),即使我在我将用C ++,Python或其他方式实现它。如果在阅读了保罗的推理之后,你发现自己同意他的意思,那么你将来会使用更多的抽象类(允许子类化;-)。

#3


To call a class "abstract" is essentially to communicate to your fellow programmers that it's incomplete: they're expected to write a bit more code to be able to make use of it.

调用类“抽象”本质上是为了向你的程序员传达它不完整的东西:他们需要编写更多代码才能使用它。

There's actually a parallel with partial application of functions in functional programming here...

实际上,在函数式编程中部分应用了函数并行...

#4


An abstract class cannot be instantiated by itself; it must be derived from to be instantiated. Essentially, the abstract definition on a class indicates that it was not intended to be instantiated as itself, and the only way to get an instance of it is to inherit from that class, and instantiate the inherited class.

抽象类不能自己实例化;它必须来源于实例化。本质上,类的抽象定义表明它不是要实例化为自身,获取它的实例的唯一方法是从该类继承,并实例化继承的类。

#5


The fact that the compiler will not allow you to instantiate it?

编译器不允许你实例化它的事实?

#6


to give an example of what I think is pertinent:

举一个我认为相关的例子:

public abstract class CustomSocket()
{
    CustomSocket()
    {
    }

    public abstract void PleaseOverideMe(CustomSocketConnection c)
    {

    }

}

#1


The difference is really pretty pragmatic: an abstract base class is one that is never intended to be instantiated, and so needn't necessarily provide complete implementations. This means the ABC can define a contract for derived classes without implementing the class.

差异非常实用:抽象基类是一个从不打算实例化的基类,因此不必提供完整的实现。这意味着ABC可以在不实现类的情况下为派生类定义合约。

This is convenient in two ways:

这有两种方便:

  • you can define abstract objects that don't have the full implementation but make assertions about the whole class. One example of this is to have a DrawItem class with a draw() method that's the base class for Circle, Rectangle, and so on. DrawItem can't know how to draw itself, because it doesn't know what it is.

    您可以定义没有完整实现但是对整个类进行断言的抽象对象。这方面的一个例子是让DrawItem类具有draw()方法,该方法是Circle,Rectangle等的基类。 DrawItem不知道如何绘制自己,因为它不知道它是什么。

  • you can define classes for which you can have two concrete implementations. This shows up in the Proxy pattern, and can also be used to build, for example, mock objects for testing.

    您可以定义可以具有两个具体实现的类。这显示在代理模式中,也可用于构建例如用于测试的模拟对象。

It's more common these days for new languages to define interfaces or modules or mixins for these things; it turns out that using ABCs almost always fall into the use cases for those more intuitive concepts.

现在,新语言为这些东西定义接口或模块或混合更为常见;事实证明,使用ABC几乎总是属于那些更直观的概念的用例。

#2


Paul Haahr has interesting suggestions, such as:

Paul Haahr提出了有趣的建议,例如:

Don't subclass concrete classes

不要对具体类进行子类化

(read the original, I don't want to copy and paste everything;-).

(阅读原文,我不想复制和粘贴一切;-)。

Paul's writing about Java, but I found at least this part of his advice is applicable to most any OO design task (though pragmatically I still occasionally deviate from it in coding, it's alive and well in my design;-), even when I'm going to implement it in C++, Python, or whatever. If, after reading Paul's reasoning, you find yourself agreeing with him, you're going to be using a lot more abstract classes in the future (to allow subclassing;-).

Paul写了关于Java的文章,但我发现至少他的这部分建议适用于大多数OO设计任务(虽然实际上我仍然偶尔会在编码时偏离它,它在我的设计中很活跃;-),即使我在我将用C ++,Python或其他方式实现它。如果在阅读了保罗的推理之后,你发现自己同意他的意思,那么你将来会使用更多的抽象类(允许子类化;-)。

#3


To call a class "abstract" is essentially to communicate to your fellow programmers that it's incomplete: they're expected to write a bit more code to be able to make use of it.

调用类“抽象”本质上是为了向你的程序员传达它不完整的东西:他们需要编写更多代码才能使用它。

There's actually a parallel with partial application of functions in functional programming here...

实际上,在函数式编程中部分应用了函数并行...

#4


An abstract class cannot be instantiated by itself; it must be derived from to be instantiated. Essentially, the abstract definition on a class indicates that it was not intended to be instantiated as itself, and the only way to get an instance of it is to inherit from that class, and instantiate the inherited class.

抽象类不能自己实例化;它必须来源于实例化。本质上,类的抽象定义表明它不是要实例化为自身,获取它的实例的唯一方法是从该类继承,并实例化继承的类。

#5


The fact that the compiler will not allow you to instantiate it?

编译器不允许你实例化它的事实?

#6


to give an example of what I think is pertinent:

举一个我认为相关的例子:

public abstract class CustomSocket()
{
    CustomSocket()
    {
    }

    public abstract void PleaseOverideMe(CustomSocketConnection c)
    {

    }

}