Rozšiřující metody pro rozhraní (extensionMethod)

- Tomáš Kuba
 - Člen | 15
 
Prosím nakopněte mě někdo jak použít Rozšiřujíci metody společně s rozhraním? Dokumentace je na toto téma torchu skoupá
Napsal jsem si toto, ale je to samozřejmě nesmysl:
// PHP 5.2
interface INestedSet {
}
INestedSet::extensionMethod('test',  callback('test'));
function test () {
    return "I am test";
}
class myClass extends Object implements INestedSet {
	//…
}
$obj = new myClass;
echo $obj->test;
					Editoval Tomáš Kuba (16. 9. 2011 11:23)

- norbe
 - Backer | 408
 
Mohl by Ti pomoci příspěvěk od Davida.
Jestli jsem správně pochopil princip, tak by to mělo pro tvůj příklad fungovat následovně:
interface INestedSet {
	function test();
}
// přidá do všech tříd (dědících od Nette\Object) implementujících INestedSet rozhraní metodu test
Nette\Object::extensionMethod('INestedSet::test',  callback('nejaka_funkce'));
				
- Tomáš Kuba
 - Člen | 15
 
Norbe, díky za bleskové nakopnutí – řešení je takto:
// PHP 5.2
interface INestedSet {
	//zde opravdu nic být nemusí
}
function test() {
	return "I am test";
}
Object::extensionMethod('INestedSet::test', callback('test'));
class myClass extends Object implements INestedSet {
	//…další metody
}
$obj = new myClass;
echo $obj->test();
					Editoval Tomáš Kuba (16. 9. 2011 12:11)

- Tomáš Kuba
 - Člen | 15
 
Pokud tam tu deklaraci metody test napíši tak jí PHP samozřejmě vyžaduje v myClass také imlementovat. To není v tento moment žádoucí. Naopak interface je v příkladu zneužit jako nástroj pro přidání tzv. behaviors – čili chování.
Dovedu si však představit, že interface bude deklarovat metodu např. getDatabaseConnection() nebo getTableName(), které budou muset být implementovány proto, aby „NestedSet chování“ vědělo jak a kam se napojit.

- Tomáš Kuba
 - Člen | 15
 
Rád si nechám poradit. Klasická dědičnost mi přišla neohrabaná (to není z mé hlavy samozřejmě – na takové napady přicházejí větší mozky než já :) To že je Model obohacen o vlastnosti/chování NestedSetu (getParentNode, addBeforeNode apod.) mi prijde jako hezký přístup. Modelu pak stačí napsat …implements INestedSet a mám k dispozici vše co potřebuju pro traverzování kolem stromu.
HosipLan, můžeš malinko rozvést návrh s abstract třídami prosím?

- Tomáš Kuba
 - Člen | 15
 
Pro doplnění: Pokud implementujete uvedený přístup rozšířeného
rozhranní tak metodě test jsou předány všechny public paramtery
myClass. Ostatně tak jak je psáno v dokumentaci :)
…tak ještě lépe (opět smekám před Davidem Grudlem a spoluautory Nette) funkce test dostane jako argument samozřejmě referenci na instanci celého objektu = v tomto případě tedy myClass:
// PHP 5.2
interface INestedSet {
        //zde opravdu nic být nemusí
}
function test($that) {
        return "I am test function of " . $that->getReflection()->getName();
}
Object::extensionMethod('INestedSet::test', callback('test'));
class myClass extends Object implements INestedSet {
        //…další metody
}
$obj = new myClass;
echo $obj->test();
					Editoval Tomáš Kuba (16. 9. 2011 15:07)

- Filip Procházka
 - Moderator | 4668
 
Co takto?
abstract class NestedSet extends Nette\Object
{
	abstract public function test();
}
class myClass extends NestedSet
{
}
$node = new myClass();
$node->test();
Čtení na dobrou noc:
http://martinfowler.com/…ritance.html
http://martinfowler.com/…ritance.html
http://martinfowler.com/…ritance.html