Если у меня есть несколько классов с функциями, которые мне нужны, но я хочу хранить их отдельно для организации, могу ли я расширить класс, чтобы иметь оба?
т.е. class a extends b extends c
редактировать: я знаю, как расширять классы по одному, но я ищу способ мгновенного расширения класса, используя несколько базовых классов - AFAIK, вы не можете сделать это в PHP, но должны быть способы обойти это, не прибегая к class c extends b
,class b extends a
Ответы:
Отвечая на ваши изменения:
Если вы действительно хотите подделать множественное наследование, вы можете использовать магическую функцию __call ().
Это некрасиво, хотя работает с точки зрения пользователя класса А:
Отпечатки "abcdef"
источник
У вас не может быть класса, расширяющего два базовых класса. Вы не могли бы иметь.
Вы могли бы, однако, иметь иерархию следующим образом ...
и так далее.
источник
Вы можете использовать черты, которые, надеюсь, будут доступны из PHP 5.4.
Черты - это механизм повторного использования кода в языках с одним наследованием, таких как PHP. Черта предназначена для уменьшения некоторых ограничений одиночного наследования, позволяя разработчику свободно повторно использовать наборы методов в нескольких независимых классах, находящихся в разных иерархиях классов. Семантика комбинации признаков и классов определяется таким образом, что уменьшает сложность и позволяет избежать типичных проблем, связанных с множественным наследованием и миксинами.
Они признаны за их потенциал в поддержке лучшей композиции и повторного использования, следовательно, их интеграция в более новые версии языков, таких как Perl 6, Squeak, Scala, Slate и Fortress. Черты также были портированы на Java и C #.
Дополнительная информация: https://wiki.php.net/rfc/traits
источник
Классы не должны быть просто коллекциями методов. Предполагается, что класс представляет абстрактную концепцию с состоянием (полями) и поведением (методами), которое изменяет состояние. Использование наследования просто для получения желаемого поведения звучит как плохой дизайн ОО, и именно поэтому многие языки запрещают множественное наследование: чтобы предотвратить «наследование спагетти», то есть расширение 3 классов, потому что у каждого есть метод, который вам нужен, и заканчивается класс, который наследует 100 методов и 20 полей, но использует только 5 из них.
источник
Я думаю, что в ближайшее время планируется добавить дополнения.
Но до тех пор, иди с принятым ответом. Вы можете немного абстрагироваться, чтобы создать «расширяемый» класс:
Обратите внимание, что в этой модели «OtherClass» узнает о $ foo. OtherClass должен иметь открытую функцию setExtendee, чтобы установить это отношение. Затем, если его методы вызываются из $ foo, он может получить внутренний доступ к $ foo. Однако он не получит доступ к каким-либо закрытым / защищенным методам / переменным, как настоящий расширенный класс.
источник
Используйте черты в качестве базовых классов. Затем используйте их в родительском классе. Продли это.
Увидеть сейчас бизнес-леди логически унаследовал бизнес и человека обоих;
источник
BusinessWoman
вместоBusinessPerson
? Тогда вы можете иметь фактическое множественное наследование.источник
Принятый в настоящее время ответ @Franck будет работать, но на самом деле это не множественное наследование, а дочерний экземпляр класса, определенный вне области, также есть
__call()
сокращение - рассмотрите возможность использования$this->childInstance->method(args)
любого метода класса ExternalClass в любом месте в «расширенном» классе.Точный ответ
Нет, вы не можете, соответственно, не совсем, как говорится в руководстве по
extends
ключевым словам:Реальный ответ
Однако, как правильно подсказал @adam, это НЕ запрещает вам использовать множественное иерархическое наследование.
Вы МОЖЕТЕ продлить один класс, с другим и другой с другим и так далее ...
Вот довольно простой пример:
Важная заметка
Как вы могли заметить, множественное (2+) интегрирование по иерархии можно выполнять только в том случае, если у вас есть контроль над всеми классами, включенными в процесс - это означает, что вы не можете применить это решение, например, со встроенными классами или с классами, которые вы используете. просто не можете редактировать - если вы хотите это сделать, у вас остается решение @Franck - дочерние экземпляры.
... И, наконец, пример с некоторым выводом:
Какие выводы
источник
Я прочитал несколько статей, не одобряющих наследование в проектах (в отличие от библиотек / фреймворков), и поощряющих программировать интерфейсы agaisnt, а не против реализаций.
Они также защищают ОО по составу: если вам нужны функции в классах А и В, сделайте, чтобы в c были элементы / поля этого типа:
источник
Множественное наследование работает на уровне интерфейса. Я сделал тест на php 5.6.1.
Вот рабочий код:
Я не думал, что это было возможно, но я наткнулся на исходный код SwiftMailer, в классе Swift_Transport_IoBuffer, который имеет следующее определение:
Я еще не играл с ним, но подумал, что было бы интересно поделиться.
источник
Я только что решил мою проблему «множественного наследования» с:
Таким образом, у меня есть возможность манипулировать сессией внутри SessionResponse, который расширяет MyServiceResponsetype, по-прежнему способный обрабатывать Session сам по себе.
источник
Если вы хотите проверить, является ли функция общедоступной, см. Эту тему: https://stackoverflow.com/a/4160928/2226755
И используйте метод call_user_func_array (...) для множества или не аргументов.
Как это :
источник
Вы можете сделать это, используя черты в PHP, объявленные в PHP 5.4
Вот краткое руководство для вас, http://culttt.com/2014/06/25/php-traits/
источник
PHP пока не поддерживает множественное наследование классов, однако поддерживает множественное наследование интерфейсов.
См. Http://www.hudzilla.org/php/6_17_0.php для некоторых примеров.
источник
PHP не допускает множественного наследования, но вы можете сделать это с помощью реализации нескольких интерфейсов. Если реализация "тяжелая", предоставьте скелетную реализацию для каждого интерфейса в отдельном классе. Затем вы можете делегировать весь интерфейсный класс этим реализациям скелета с помощью содержания объекта .
источник
Не зная точно, чего вы пытаетесь достичь, я бы посоветовал изучить возможность изменения дизайна вашего приложения, чтобы использовать композицию, а не наследование в этом случае.
источник
Всегда хорошая идея сделать родительский класс с функциями ... т.е. добавить всю эту функциональность в родительский.
И «переместить» все классы, которые используют это иерархически вниз. Мне нужно - переписать функции, которые являются конкретными.
источник
Одна из проблем PHP как языка программирования заключается в том, что вы можете иметь только одно наследование. Это означает, что класс может наследоваться только от одного другого класса.
Однако большую часть времени было бы полезно наследовать от нескольких классов. Например, может быть желательно наследовать методы от пары разных классов, чтобы предотвратить дублирование кода.
Эта проблема может привести к классу, у которого есть длинная семейная история наследования, которая часто не имеет смысла.
В PHP 5.4 была добавлена новая функция языка, известная как Черты. Черта похожа на Mixin в том, что она позволяет вам смешивать классы черт в существующий класс. Это означает, что вы можете уменьшить дублирование кода и получить преимущества, избегая проблем множественного наследования.
Черты
источник
Это не настоящий ответ, у нас есть дубликат класса
... но это работает :)
класс copy_B - это копия всего класса B
сейчас
источник
класс А расширяет B {}
класс B расширяет C {}
Тогда А расширил и В, и С
источник
B
. Что мы хотим , чтобы большую часть времени, чтобы иметь два несвязанных классовB
иC
(вероятно , из различных библиотек) и получить одновременно наследуетсяA
, таким образом, чтоA
содержит все от обоихB
иC
, ноB
не содержит ничего отC
и наоборот.