抽象类的目的是什么?

发布于 2024-08-22 05:02:46 字数 129 浏览 7 评论 0原文

我正在尝试用 PHP 学习 OOP,但我对接口和抽象类有一些困惑。它们都不包含任何实现,只包含定义,并且应该通过它们的子类来实现。抽象类的哪一部分将它们与接口明确区分开来?另外,由于它们明显相似,基于什么原因我应该决定使用其中一种而不是另一种?

I am trying to learn OOP in PHP, and I have some confusion about interfaces and abstract classes. They both contain no implementations, only definitions, and should be implemented through their sub-classes. What part of abstract classes clearly distinguishes them from interfaces? Also, due to their apparent similarities, based on what reasons should I decide to use one over the other?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(7

纵山崖 2024-08-29 05:02:46

可以创建包含具体成员(例如方法或属性)的抽象类。您仍然无法直接实例化抽象类,但任何实例化的子类都可以从抽象类中定义的实现成员中受益。

相比之下,接口从不包含任何实现逻辑。每个实现类负责提供接口中定义的所有成员的实现。

就我如何看待差异而言,抽象的子类是该类型的类。例如,Dog 是一种Animal。我将接口视为一种关系。例如,ICanDisplayImages 告诉我实现类可以显示图像,但没有告诉我该类实际代表什么。

It is possible to create abstract classes that contain concrete members, such as methods or properties. You still can't instantiate the abstract class directly, but any instantiated sub-classes can benefit from implemented members defined in the abstract class.

An interface, by comparison, never contains any implementation logic. It is down to each implementing class to provide the implementation of all members defined in the interface.

In terms of how I view the differences, a sub-class of an abstract is-a class of that type. e.g. Dog is an Animal. I see an interface as a does-a relationship. e.g. ICanDisplayImages tells me that the implementing class can display images, but tells me nothing about what the class actually represents.

凶凌 2024-08-29 05:02:46

一个 abstract 类形成一个自身与子类之间的is-a关系,而接口创建follows-a关系。因此,抽象类比接口更具体,它们也可能包含具体的实现(例如模板方法 )而接口定义了实现类必须遵循的一组契约方法。这是更高层次的抽象,因为实现类不一定是抽象类。用它来标准化您的 API。

相关问题:https://stackoverflow.com/search?q=abstract+vs+interface

An abstract class forms an is-a relationship between itself and the subclass, while an interface creates a follows-a relationship. As such, abstract classes are much more concrete than interfaces and they may also contain concrete implementations (e.g. Template methods) while an interface defines a contractual set of methods an implementing class must follow. This is a much higher level of abstraction as the implementing class must not necessarily be of the abstract class. Use it to standardize your API.

Related questions: https://stackoverflow.com/search?q=abstract+vs+interface

没企图 2024-08-29 05:02:46

除了其他答案中描述的 OOP 哲学之外,我认为抽象类的主要用途是一种骨架。

当您设计应用程序或与团队合作时,它非常有用,因为您有一个可以使用的基本代码,并可以扩展它以接近界面,但具有更高级的工作流程。

Beyond the OOP philosophy described in other answers, I think the major use of abstract class is kind of a skeleton.

It's usefull when you design an application, or work with a team, because you have a base code to work with and extends it's close to interface but with a more advanced workflow.

风启觞 2024-08-29 05:02:46

它们都不包含任何实现..

抽象类可以实现全部或仅部分方法。但主要理念是通过在子类中添加新方法(扩展基本功能)来扩展现有的抽象类。

在子类中,您只能扩展一个类(抽象类)。抽象类定义您必须实现或仅通过子类中的其他方法扩展的功能。

接口用于定义类行为。您可以实现多个接口(并且说我的子类必须执行此操作,此操作和此操作!),但您只能扩展一个抽象类。

They both contain no implementations..

Abstract class can implements all or only part of the methods. But the main philosophy - is extend existing abstract class by to add a new methods in child classes (that extend a basic functionality).

In a child class you can extend only one class (abstract class). Abstract class define functionality that you must implement or just extends by other methods in child classes.

Interfaces are use to define the class behaviors. You can implement more than one interface(and say my child-class must do this,this and this thigs!), but you can extend only one abstract class.

苏佲洛 2024-08-29 05:02:46

抽象类和接口之间的主要区别在于接口定义了常见的行为,而抽象类是继承的基础类。换句话说,抽象类定义了子类可能共享的一些核心方法和属性集。考虑一个定义许可证的类。所有许可证都有某种类型的 ID 号,并颁发给某些个人或团体。许可证类别可以通过驾驶执照类别、自行车许可证类别和狩猎许可证类别等进行扩展。将 License 类抽象化的主要原因是它定义了许可证的抽象概念。没有许可证这样的东西,因此通过声明类抽象,它无法被实例化。
另一方面,接口根本不定义对象。它定义了方法签名。任何实现接口的非抽象类都必须提供接口中所有方法的实现。这里的优点是该方法提供了跨不同类型对象的通用接口,例如,compareTo() 在与字符串或任何其他对象一起使用时看起来相同。

The main difference between an abstract class and an interface is that an interface defines common behaviors, where an abstract class is a foundation class for inheritance. In other words, an abstract class defines some core set of methods and properties that subclasses might share. Consider a class that defines a License. All licenses have an id number of some type and are issued to some individual or group. A license class might be extended by a Driver's License class, a Bicycle License class, and Hunting License class, and so on. The main reason one would make the License class abstract is because it defines an abstract idea of a license. There is no such thing as a license, so by declaring the class abstract, it cannot be instantiated.
An interface, on the other hand, does not define an object at all. It defines method signatures. Any non-abstract class that implements an interface must provide an implementation for all of the methods in the interface. The advantage here is the method provides a common interface across different types of objects, e.g. compareTo() looks the same when used with Strings or any other object.

黒涩兲箜 2024-08-29 05:02:46

如果方法未定义为抽象,则抽象类可以包含方法实现。如果该方法被定义为抽象方法,则它不包含实现,但需要由其继承者实现。抽象类不能被实例化,只能被继承,以便继承者允许它使用其行为。

接口仅定义方法签名,任何继承自该接口的类都必须实现该接口中包含的所有方法。

An abstract class can contain method implementations if the method is not defined as abstract. If the method is defined as abstract, it does not contain an implementation, but it needs to be implemented by its inheritors. An abstract class cannot be instantiated, but only inherited from, for the inheritor to allow it to use its behaviors.

An interface only defines method signatures and any class inheriting from it must implement all methods contained in the interface.

他是夢罘是命 2024-08-29 05:02:46

通常,接口用于定义契约,因此您可以进行类型检查。还有一种编程风格称为“针对接口编程”,这是一个好主意。请参阅依赖倒置原则

A.高层模块不应该依赖于低层模块。两者都应该依赖于抽象。

B.抽象不应该依赖于细节。细节应该取决于抽象。”

因此,如果您定义函数和方法,而不是 针对类进行提示,您只需针对接口进行提示。

下面是一个示例,您可以按如下方式定义输入流和输出流的接口:

interface OutputStream{
  write($string); // Writes a string to the output.
  close(); // Closes the output stream.
}

interface InputStream{
  read($length); // Reads at most $length characters.
  eof(); // TRUE, if the input stream is empty.
}

您现在可以创建 copy 函数。或方法,它将流的完整输出复制到输入,而不包含任何输入:

// 50 is just chosen randomly.
function copy(InputStream $input, OutputStream $output){
  while(!$input->eof()){
    $output->write($input->read(50));}}

恭喜,您的 copy 实现现在适用于输入和输出的每个组合 再举

另一方面,抽象类可以用来实现通用功能,而无需实现功能齐全的类。

一个例子,您想要一个方法。 write($s),它将字符串写入输出,并且您需要一个方法 writeLine($s),它将字符串和附加换行符写入输出。那么这将是合适的:

abstract class AbstractOutputStream{
  public function writeLine($s){
    $this->write($s."\n");}}

具体输出流现在可以从抽象输出流继承,仅实现 write 并免费获取 writeLine

Usually interfaces are used to define contracts, so you get type checking. There is also a programming style called "programming against interfaces", which is a good idea. See the Dependency Inversion Principle:

A. High-level modules should not depend on low-level modules. Both should depend on abstractions.

B. Abstractions should not depend upon details. Details should depend upon abstractions."

So if you define functions and methods, instead of type hinting against classes, you just hint against interfaces.

Here is an example. Let's say, you define interfaces for input streams and and output streams as follows:

interface OutputStream{
  write($string); // Writes a string to the output.
  close(); // Closes the output stream.
}

interface InputStream{
  read($length); // Reads at most $length characters.
  eof(); // TRUE, if the input stream is empty.
}

You could now create copy function or method, which copies the complete output of a stream to an input, without having any of them:

// 50 is just chosen randomly.
function copy(InputStream $input, OutputStream $output){
  while(!$input->eof()){
    $output->write($input->read(50));}}

Congratulations, your copy implementation now works for every combination of an input and output stream, without even implementing one.

Abstract classes, on the other hand, can be used to implement common functionality without having to implement a fully functional class.

Again, an example. Let's say, you want to have output streams. You want a method write($s), which writes a string to the output, and you want a method writeLine($s), which writes the string and an additional newline to the output. Then this would be appropriate:

abstract class AbstractOutputStream{
  public function writeLine($s){
    $this->write($s."\n");}}

Concrete output streams now could inherit from the abstract output stream, implement just write and get writeLine for free!

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