[php5]Обращение к методу потомка через родителя

Profic

just Profic (PHP5 BetaTeam)
[php5]Обращение к методу потомка через родителя

Можно ли хотеть от PHP5 (RC3) возможности обращения к protected методу потомка через метод родителя, наследованный потомком? Т.е. что-то типа такого:
PHP:
<?
class A {
	private $a = NULL;
	public function a () {
		echo 'A::a called';
		self::$a ();
	}
}

class B extends A {
	public function __contruct () {
		$this->a = 'b';
	}
	protected function b () {
		echo 'B::b called';
	}
}

$b = new B;
$b->a ();
?>
На это php ругается:
Fatal error: Call to protected B::b() from context '' in C:\***\test.parser.php on line 19
Call Stack
# Function Location
1 {main}() C:\***\test.parser.php:0

Это вообще идеологически правильно или я такого не должен хотеть?

-~{}~ 14.06.04 21:45:

ЗЫ. Я конечно могу сделать funtion b не protected, а public, но это уж точно неправильно, т.к. эта функция нужна только внутри этих классов, но не снаружи.

-~{}~ 15.06.04 00:44:

ЗЫЫ. Все-таки мне кажется, что это баг. И его соответственно нужно запостить в базу багов.
tony2k1
Как считаешь? (Ты вроде спец по внутренностям PHP :))
 

.des.

Поставил пиво кому надо ;-)
__contruct
&#1082;&#1086;&#1085;&#1089;&#1090;&#1088;&#1091;&#1082;&#1090;&#1086;&#1088;&#1086;&#1084; &#1091; &#1042;&#1072;&#1089; &#1103;&#1074;&#1083;&#1103;&#1077;&#1090;&#1089;&#1103; protected function b()
&#1087;&#1086;&#1101;&#1090;&#1086;&#1084;&#1091; &#1086;&#1073;&#1098;&#1077;&#1082;&#1090; &#1085;&#1077; &#1084;&#1086;&#1078;&#1077;&#1090; &#1073;&#1099;&#1090;&#1100; &#1089;&#1086;&#1079;&#1076;&#1072;&#1085;.

-~{}~ 15.06.04 01:55:

Да и вообще пример какой то странный.
Что вы пытаетесь сделать?
$this->a = 'b';
Это обращение к необъявленному члену a класса B? или таким образом пытаемся обратиться к private члену родительского класса? Если второе, то думаю коментарии излишни - на то он и private.

-~{}~ 15.06.04 02:04:

И еще. Что именно Вы пытаетесь сделать вот этой строчкой:
self::$a ();
?
 

Profic

just Profic (PHP5 BetaTeam)
.des.
Спасибо за наводку... этот код был написан по мотивам реального класса, но как-то я промахнулся с ним :(
Я просто пытался применить статический вызов, там где он совершенно не нужен (хотя и возможен). Вот этот код делает именно, то что мне нужно.
PHP:
<?
class base {
	private $func = NULL;
	public function __construct ($funcLoc) {
		$this->func = $funcLoc;
	}
	public function caller () {
		echo 'base::call caller<br/>';
		$funcLoc = $this->func;
		$this->$funcLoc ();
	}
}

class child extends base {
	public function __construct () {
		parent::__construct ('called');
	}
	protected function called () {
		echo 'child::called called<br/>';
	}
}

$b = new child;
$b->caller ();
?>
В общем виде проблема была в том, что self - определеляется в классе и не "переопределяется" для родительского класса. Это для моего способа вызова определенным переменной названием метода класса было существенно.
PHP:
$func = $this->a;
self::$func ();
Как оказалось просто копал не там. Документации не хватает по новой модели все же. Полной я имею ввиду. Со всеми подводными камнями и т.п. :)

Но главное, я понял, как работают self и parent :) Это "константы" типа __LINE__ и __FILE__. Они просто "раскрываются" в имя искомого класса.
 

Ямерт

The Old One
В первом примере всё ясно: protected-метод для того предназначен, чтобы он был доступен только потомкам. Никакой ошибки тут нет.
 

tony2001

TeaM PHPClub
E_STRICT включи - тебе бы сразу нотайсы выдало про old-style конструкторы.
 

Profic

just Profic (PHP5 BetaTeam)
tony2001
E_STRICT уже включил :)
У себя я зачем-то (сам не знаю зачем) пытался вначале использовать self::$array[$ind](), на что php говорил: "Internal compiler error. Please report!" (Ошибка блин, у него неизвестная :)).
Потом решил попробовать self::$func(), на что php вначале говорил, что-то про невозможность вызова данного метода (это я так понимаю, из-за того, что где-то промазал с определением private/protected), а потом что не знает такого метода (что понятно, т.к. self относится к классу, а не объекту).
В результате код вида $this->$array[$ind] () заработал как нужно :).
И зачем я привизался к статическому вызову. Видимо self::CONSTANT понравился :)

ЗЫ. Кстати, а не знаешь ли ты все ошибки, о которых сообщает E_STRICT? Я пока понял, что:
1) про var он сообщает, (кстати про просто function func_name нет)
2) про $var =& new Object;
3) про конструкторы старого вида
 

tony2001

TeaM PHPClub
>Кстати, а не знаешь ли ты все ошибки, о которых сообщает E_STRICT?

все, что нашел `grep -r "\<E_STRICT\>" * | grep "_error"`:

mysql_list_tables() is deprecated
dl() is deprecated - use extension=%s in your php.ini
is_a(): Deprecated. Please use the instanceof operator
Redefining already defined constructor for class %s
Declaration of %s::%s() should be compatible with that of %s::%s()
Creating default object from empty value
Implicit cloning object of class '%s' because of 'zend.ze1_compatibility_mode'
Only variable references should be returned by reference
Non-static method %s::%s() cannot be called statically
var: Deprecated. Please use the public/private/protected modifiers
Assigning the return value of new by reference is deprecated
 
Сверху