类可以扩展类并实现接口吗


100

一个类可以在PHP中同时扩展接口和另一个类吗?
基本上我想这样做:

interface databaseInterface{
 public function query($q);
 public function escape($s);
 //more methods
}

class database{ //extends both mysqli and implements databaseInterface
 //etc.
}

只需执行以下操作即可做到这一点:

class database implements databaseInterface extends mysqli{ 

导致致命错误:

解析错误:语法错误,意外的T_EXTENDS,在* file *行* line *上预期为“ {”

18
这怎么太本地化了?“这个问题不太可能帮助将来的访客”。最佳答案是33票赞成,而问题4星!
duality_

Answers:


177

尝试另一种方法:

class database extends mysqli implements databaseInterface { ...}

这应该工作。


啊,非常感谢。为什么它们应该相反呢?
Pim Jager

14
由于您只能继承一个类,并且可以实现任意数量的接口,因此这可能是语法上的麻烦。另外,请记住,如果您的子类实现了任何接口,那么它们也将显示在已实现方法的列表中。因此,按顺序排列它们是有一定意义的。
德鲁

这是不好的做法吗?
Mohammed Shamshid

21

是的,它可以。您只需要保留正确的顺序。

class database extends mysqli implements databaseInterface { ... }

而且,一个类可以实现多个接口。只需用逗号分隔它们即可。

但是,我有义务警告您,扩展mysqli类是一个非常糟糕的主意。继承本身可能是面向对象编程中最被高估和滥用的概念。

相反,我建议以mysqli方式(或PDO方式)进行与数据库相关的工作。

另外,这是一件小事,但是命名约定确实很重要。您的课程database似乎比那时更笼统mysqli,因此它表明后者是继承database而不是继承。


1
为什么扩展mysqli类是一个坏主意?
Pim Jager

11
首先,因为它不是您的。当mysqli家伙决定更改某些内容时,子类的行为也会更改。其次,继承用于特殊功能,而不用于扩展功能。这是OOP中最容易理解的事情。根据经验,我倾向于只扩展抽象类。
米哈尔鲁德尼茨基

Michal-对于使用多态方法与聚合/组合方法的开发人员,对mysqli的更改会有什么不同?您仍然必须更新代码以处理更改。
彼得·贝利

2
我熟悉适配器模式。我只是说,如果方法名称更改或不建议使用,则在两种情况下您仍然需要更改代码。尽管我同意在这种情况下使用非多态方法会更好,但是我不认为适配器会“免疫”更改。
彼得·贝利

2
您只需要更改适配器代码,而不必更改使用该代码的所有位置。使用合成,无论如何您都可以提供兼容性层,而通过继承,您最多可以称其为hack。而且,经纠正,适配器可以更好地抵抗变化。
米哈尔鲁德尼茨基

6

是的,实际上,如果您想实现多个接口,可以执行以下操作:

public class MyClass extends BaseClass implements myInterface1, myInterface2, myInterface3{ 

}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.