Возможно ли в PHP наследование сразу от двух классов (как C++).

klava

Новичок
Возможно ли в PHP наследование сразу от двух классов (как C++).

Раньше писал на старушке C++, там можно наследовать классы от скольки хочешь других. Теперь столкнулся с проблемой, когда нужно в одном объекте совмещать принципы сразу двух базовых. Возможен ли такой вариант в PHP?:confused:
 

voituk

прозревший
Нет.

Чаще всего такое и не надо.
Лично мне ни разу не удалось столкнуться со случаем когда без этого "никак".
 

demongloom

Новичок
может создать отдельный класс, куда через copy-paste вставить необходимые методы?
 

moxnatiy

Новичок
demongloom
точно! без этого просто никак.

klava
Слушай 440hz. Истину глаголит.
 

Franzusow

Новичок
http://de2.php.net/manual/en/language.oop5.reflection.php
http://de2.php.net/manual/de/language.oop5.interfaces.php
 

PILOT

Новичок
Автор оригинала: demongloom
может создать отдельный класс, куда через copy-paste вставить необходимые методы?
moxnatiy

я всё время только так и делаю ... я не прав ?
 

Sender

Новичок
PILOT

copy - paste это дублирование кода, дублирование кода - зло
 

Alexandre

PHPПенсионер
440hz мне кажется, что klava всетаки хотел именно наследование, т.е. использовать определенные методы в родителях.

Как выход, определить наследование от одного класса, а второй класс имплементировать и присвоить ссылку на экземпляр. Правда получится уродский код, который многим не нравиться:
Код:
class Aclass {
  function a1(){...}
  function a2(){...}
}
class Bclass {
  function b1(){...}
  function b2(){...}
}
class C extends A{
  var $b=null;
  function  __construct( ){
      $b= new Bclass();
  }
...
  function c1(){...
    [b] $dd = $this->b->b1();[/b]
    ...
  }
}
При общении с некоторыми программистами, есть мнение, что выделенная жирным констукция многих не устраивает...
Но это, как говорится - стиль кодинга, каждый привыкает к своему стилю.
 

dr-sm

Новичок
klava, что значит совмещать принципы?
Есть два типа наследования:
1. наследование интерфейса
2. наследование реализации
Вот тебе высосaный из пальца пример "множественного" наследования на PHP:
PHP:
interface flyingStuff {
	public function fly($destinaton);
}

abstract class flyer {
	// pattern template method
	protected final function doFly() {
		try {
			$this->onTakeOff();		
			$this->onLand();
		} catch (Exception $e) {
			$this->onCrash();		
		}
	}
	protected abstract function onTakeOff();
	protected abstract function onLand();
	protected abstract function onCrash();
}

class someClass extends flyer implements flyingStuff {
	private $destinaton;
	public function fly($destinaton) {
		$this->destinaton = $destinaton;
		$this->doFly();		
	}
	protected function onTakeOff() {
		echo "Taking Off...\n";
		//throw new Exception();
	}
	protected function onLand() {
		echo "Landing...\n";
	}
	protected function onCrash() {
		echo "Congratulations, you are dead.\n";
	}
}

function flyToMoscow(flyingStuff $fs) {
	$fs->fly("Moscow");
}

$x = new someClass();
flyToMoscow($x);
Alexandre, мне кажется, основной минус твоего подхода в том, что Type Hinting не будет работать.
 

Alexandre

PHPПенсионер
dr-sm Конечно пример замечательный, но мне что, для каждого нового class someClass1 , someClass2 реализующих flyingStuff переопределять методы onTakeOff, onLand, onCrash...? Дублирование кода? Если я понял, именно в этом гвоздь?
 

dr-sm

Новичок
да не, просто привел template method, как один из классических случаев наследования реализации. тем более никто ж не мешает опеределить default implementation для onTakeOff, onLand, onCrash и тп :).
 

demongloom

Новичок
имелось в виду что требуется совместить методы 2х разных классов в одном.

class a {
function hello() {}
}

class b {
function goodbye() {}
}

class c extends a, b {
}

$c = new c;
$c->hello();
$c->goodbye();

так бы выглядело в идеале, но пхп не поддерживает множественное наследование, приходится извращаться.

class c {
var $objects = array();
function __construct() {
$this->objects[] = &this;
$this->objects[] = new a;
$this->objects[] = new b;
}
function __call($a, $args)
foreach($this->objects as $vObject) {
if(method_exists($vObject, $a) {
return call_user_method_array($a, $vObject, $args); }
}
}
function __get() {
//реализовываем наподобие __call
}
function __set() {
//реализовываем наподобие __call
}
}
 

texrdcom

Новичок
в pecl есть библиотека которая дает возможность множественного наследования я не помню названия но межеш
посмотреть сам http://pecl.php.net/
 

demongloom

Новичок
у меня подход несколько другой.

впрочем эти решения достаточно кривые и уж тем более не решают проблему private методов и атрибутов
 

dr-sm

Новичок
Автор оригинала: demongloom
имелось в виду что требуется совместить методы 2х разных классов в одном.
Тогда, мне кажется лучше поступить как предложил Alexandre, только
чтоб хинты работали, разбиваем один из классов на interface + default interface implementation:
PHP:
class Aclass {
  function a1(){...}
  function a2(){...}
}
interface Biface {
  function b1();
  function b2();
}
class Bclass implements Biface {
  function b1(){...}
  function b2(){...}
}
class C extends Aclass, implements Biface {
  var $b=null;
  function  __construct( ){
      $b= new Bclass();
  }

  function b1(){ // delegate
     return $this->b->b1();
  }
  function b2(){ // override
  ....
  }
}
 

Alexandre

PHPПенсионер
и уж тем более не решают проблему private методов и атрибутов
Это да, но придется написать враппер для этих функций. Вообще-то все зависит от задачи, на сколько потребуются сами классы А и В для наследования других классов, а не только в классе С. Где-то лучше применить и интерфейсы. А может лучше создать классы А, В и интерфейс С, промежуточный класс D и уже от него осуществлять наследование.
 

xpgeek

Новичок
klava опиши задачу, почему тебе понадобилось множественное наследование?
Как насчет композиции вместо наследования?
 

klava

Новичок
Автор оригинала: 440hz
интерфейсы?
:eek: Интерфейсы здесь ни коим боком не стоят. Когда создаёшь огромную библиотеку классов,
и на второй месяц, замечаешь, что в неком классе требуется совместить особенности сразу
двух ранее созданных ФУНДАМЕНТАЛЬНЫХ ДЛЯ ЭТОЙ СИСТЕМЫ классов, а переделать систему
уже = Повесится(), то интерфейсы явно не выход...

Кстати, спасибо всем за ответы. Проблему решил (точнее обошёл).
 
Сверху