Чи може клас розширити і клас, і реалізувати інтерфейс


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, очікуючи '{' у * файлі * у рядку * рядок *

18
Як це занадто локалізовано ?! "Це питання навряд чи допоможе майбутнім відвідувачам". І все ж найкраща відповідь має 33 відгуки та питання 4 зірки!
подвійність_

Відповіді:


177

Спробуйте навпаки:

class database extends mysqli implements databaseInterface { ...}

Це має спрацювати.


Ах, дуже дякую Чому саме так вони повинні бути навпаки?
Пім Джагер

14
Оскільки ви можете успадковувати лише один клас і можете реалізовувати будь-яку кількість інтерфейсів, це, мабуть, було синтаксичним цукром. Також пам’ятайте, якщо ваш підклас реалізує будь-які інтерфейси, це також відображатиметься у списку реалізованих методів. Тож розміщення їх у такому порядку має певний сенс.
Дрю

Це погана практика?
Мухаммед Шамшид

21

Так, це може. Вам просто потрібно зберегти правильний порядок.

class database extends mysqli implements databaseInterface { ... }

Більше того, клас може реалізувати більше одного інтерфейсу. Просто розділіть їх комами.

Однак я хочу попередити вас, що розширення класу mysqli - це надзвичайно погана ідея . Спадщина сама по собі є, мабуть, найбільш завищеною та зловживаною концепцією в об'єктно-орієнтованому програмуванні.

Натомість я б радив робити речі, пов'язані з db, способом mysqli (або способом PDO).

Плюс, незначна річ, але називання конвенцій має значення. Ваш клас databaseздається більш загальним mysqli, тому він говорить про те, що останній успадковує відdatabase а не навпаки.


1
Чому розширення класу mysqli - погана ідея?
Пім Джагер

11
По-перше, тому що це не ваше. Коли хлопці mysqli вирішать щось змінити, поведінка підкласу також зміниться. По-друге, успадкування використовується для СПЕЦІАЛІЗАЦІЇ, а не ДУХАННЯ з додатковою функціональністю. Це найпорозуміліша річ в ООП. Як правило, я схильний розширювати лише абстрактні заняття.
Міхал Рудницький

Міхал - як зміна mysqli може відрізнятися для розробника, який використовує поліморфний підхід проти агрегованого / складеного? Вам потрібно буде оновити код, щоб вносити зміни.
Пітер Бейлі

2
Я знайомий із схемою адаптера. Я просто кажу, що якщо ім'я методу зміниться або застаріло, вам потрібно буде змінити код в обох сценаріях. Хоча я погоджуюся, що не поліморфний підхід у цьому сценарії кращий, я не купую поняття, що адаптер буде "несприйнятливий" до змін.
Пітер Бейлі

2
Вам потрібно буде лише змінити код адаптера, не у всіх місцях, що використовують цей код. За допомогою складу ви можете забезпечити шар сумісності незалежно від того, хоча при успадкуванні ви можете назвати його в кращому випадку хаком. І, я виправданий, адаптер забезпечить кращий імунітет до змін.
Michał Rudnicki

6

так, адже ви хочете реалізувати кілька інтерфейсів, ви можете зробити так:

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

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.