Может ли класс расширять как класс, так и реализовывать интерфейс


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 звезды!
duality_

Ответы:


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 решат что-то изменить, поведение подкласса также изменится. Во-вторых, наследование используется для СПЕЦИАЛИЗАЦИИ, а не для РАСШИРЕНИЯ дополнительной функциональностью. Это наиболее неправильно понимаемая вещь в ООП. Как правило, я стараюсь расширять только абстрактные классы.
Michał Rudnicki,

Михал - чем изменение 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.