What is the purpose of abstract classes?
我正在尝试用PHP学习OOP,我对接口和抽象类有些困惑。它们都不包含实现,只包含定义,应该通过子类实现。抽象类的哪一部分清楚地将它们与接口区分开来?而且,由于它们明显的相似性,基于什么原因,我应该决定使用一个而不是另一个?
可以创建包含具体成员的抽象类,如方法或属性。您仍然不能直接实例化抽象类,但是任何已实例化的子类都可以从抽象类中定义的已实现成员中受益。
相比之下,接口从不包含任何实现逻辑。由每个实现类来提供接口中定义的所有成员的实现。
就我如何看待这些差异而言,抽象的子类就是这种类型的类。例如,
一个
相关问题:https://stackoverflow.com/search?Q=抽象+vs+接口
除了其他答案中描述的OOP哲学之外,我认为抽象类的主要用途是某种框架。
它在设计应用程序或与团队合作时很有用,因为您有一个基本代码可以使用并扩展它接近接口,但使用更高级的工作流。
They both contain no implementations..
抽象类可以实现全部或部分方法。但主要的哲学是通过在子类中添加新方法(扩展基本功能)来扩展现有的抽象类。
在子类中,只能扩展一个类(抽象类)。抽象类定义了必须实现的功能,或者只是由子类中的其他方法扩展的功能。
接口用于定义类行为。您可以实现多个接口(并说我的子类必须做到这一点、这一点和这一点!),但只能扩展一个抽象类。
抽象类和接口之间的主要区别是接口定义了公共行为,其中抽象类是继承的基础类。换句话说,抽象类定义了子类可能共享的一些核心方法和属性集。考虑定义许可证的类。所有许可证都具有某种类型的ID号,并颁发给某些个人或组。许可证类别可以通过驾驶证类别、自行车许可证类别和狩猎许可证类别等进行扩展。将许可证类抽象化的主要原因是它定义了许可证的抽象概念。没有许可证这样的东西,所以通过声明类抽象,它不能被实例化。另一方面,接口根本不定义对象。它定义了方法签名。实现接口的任何非抽象类都必须为接口中的所有方法提供实现。这里的优点是,该方法提供了跨不同类型对象的公共接口,例如,当与字符串或任何其他对象一起使用时,compareto()看起来相同。
通常,接口用于定义契约,因此您可以进行类型检查。还有一种称为"针对接口编程"的编程风格,这是一个好主意。参见依赖倒置原理:
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."
因此,如果您定义函数和方法,而不是对类进行类型提示,那么您只需要对接口进行提示。
下面是一个例子。例如,您定义输入流和输出流的接口如下:
1 2 3 4 5 6 7 8 9 | 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. } |
现在,您可以创建
1 2 3 4 | // 50 is just chosen randomly. function copy(InputStream $input, OutputStream $output){ while(!$input->eof()){ $output->write($input->read(50));}} |
祝贺您,您的
另一方面,抽象类可以用来实现公共功能,而不必实现完全功能类。
再举一个例子。比如说,您希望有输出流。您需要一个方法
1 2 3 4 | abstract class AbstractOutputStream{ public function writeLine($s){ $this->write($s." ");}} |
具体的输出流现在可以从抽象的输出流继承,只实现
如果方法未定义为抽象的,则抽象类可以包含方法实现。如果方法被定义为抽象的,则它不包含实现,但需要由其继承者实现。抽象类不能实例化,但只能从继承者继承,以便继承者使用其行为。
接口只定义方法签名,继承它的任何类必须实现接口中包含的所有方法。