请解释一下什么时候我应该使用PHP接口,什么时候我应该使用抽象类?
我如何能改变我的抽象类在一个接口?
请解释一下什么时候我应该使用PHP接口,什么时候我应该使用抽象类?
我如何能改变我的抽象类在一个接口?
当前回答
最佳实践是使用接口来指定契约,并将抽象类作为契约的一个实现。该抽象类可以填充大量样板文件,因此您可以通过重写需要或想要的内容来创建实现,而不必强制使用特定的实现。
其他回答
主要的区别是抽象类可以包含默认实现,而接口不能。
接口是没有任何实现的行为契约。
最佳实践是使用接口来指定契约,并将抽象类作为契约的一个实现。该抽象类可以填充大量样板文件,因此您可以通过重写需要或想要的内容来创建实现,而不必强制使用特定的实现。
为什么要使用抽象类?下面是一个简单的例子。假设我们有以下代码:
<?php
class Fruit {
private $color;
public function eat() {
// chew
}
public function setColor($c) {
$this->color = $c;
}
}
class Apple extends Fruit {
public function eat() {
// chew until core
}
}
class Orange extends Fruit {
public function eat() {
// peeling
// chew
}
}
现在我给你一个苹果,你吃了它。 它尝起来像什么?它尝起来像苹果。
<?php
$apple = new Apple();
$apple->eat();
// Now I give you a fruit.
$fruit = new Fruit();
$fruit->eat();
那是什么味道?这没什么意义,所以你不能这么做。这是通过使Fruit类抽象以及其中的eat方法来实现的。
<?php
abstract class Fruit {
private $color;
abstract public function eat(){}
public function setColor($c) {
$this->color = $c;
}
}
?>
一个抽象类就像一个接口,但是你可以在一个抽象类中定义方法,而在一个接口中它们都是抽象的。抽象类可以有空方法和工作/具体方法。在接口中,定义的函数不能有主体。在抽象类中,它们可以。
一个真实的例子:
<?php
abstract class person {
public $LastName;
public $FirstName;
public $BirthDate;
abstract protected function write_info();
}
final class employee extends person{
public $EmployeeNumber;
public $DateHired;
public function write_info(){
//sql codes here
echo "Writing ". $this->LastName . "'s info to emloyee dbase table <br>";
}
}
final class student extends person{
public $StudentNumber;
public $CourseName;
public function write_info(){
//sql codes here
echo "Writing ". $this->LastName . "'s info to student dbase table <br>";
}
}
///----------
$personA = new employee;
$personB = new student;
$personA->FirstName="Joe";
$personA->LastName="Sbody";
$personB->FirstName="Ben";
$personB->LastName="Dover";
$personA->write_info();
// Writing Sbody's info to emloyee dbase table
$personB->write_info();
// Writing Dover's info to student dbase table
抽象类和接口之间的技术差异已经在其他答案中列出了。为了面向对象编程,我想在编写代码时对类和接口之间的选择添加一个解释。
类应该代表实体,而接口应该代表行为。
让我们举个例子。计算机显示器是一个实体,应该表示为一个类。
class Monitor{
private int monitorNo;
}
它的设计目的是为您提供一个显示界面,因此功能应该由接口定义。
interface Display{
void display();
}
正如其他答案中解释的那样,还有许多其他的事情需要考虑,但这是大多数人在编码时忽略的最基本的事情。
再加上一些已经很好的答案:
Abstract classes let you provide some degree of implementation, interfaces are pure templates. An interface can only define functionality, it can never implement it. Any class that implements the interface commits to implementing all the methods it defines or it must be declared abstract. Interfaces can help to manage the fact that, like Java, PHP does not support multiple inheritance. A PHP class can only extend a single parent. However, you can make a class promise to implement as many interfaces as you want. type: for each interface it implements, the class takes on the corresponding type. Because any class can implement an interface (or more interfaces), interfaces effectively join types that are otherwise unrelated. a class can both extend a superclass and implement any number of interfaces: class SubClass extends ParentClass implements Interface1, Interface2 { // ... }
请解释什么时候我应该使用接口,什么时候我应该使用抽象类?
当您只需要提供一个模板而不需要任何实现时,请使用接口,并且您希望确保实现该接口的任何类(至少)与实现该接口的任何其他类具有相同的方法。
当您想要为其他对象(部分构建的类)创建基础时,请使用抽象类。扩展抽象类的类将使用一些定义/实现的属性或方法:
<?php
// interface
class X implements Y { } // this is saying that "X" agrees to speak language "Y" with your code.
// abstract class
class X extends Y { } // this is saying that "X" is going to complete the partial class "Y".
?>
我如何能改变我的抽象类在一个接口?
这是一个简化的例子。去掉任何实现细节。例如,将你的抽象类更改为:
abstract class ClassToBuildUpon {
public function doSomething() {
echo 'Did something.';
}
}
to:
interface ClassToBuildUpon {
public function doSomething();
}