Autor Zpráva
crossbone
Profil *
Ahoj,
nevím jestli jsem správně pochopil dědičnost, tzv. jestli to jde vůbec udělat tak jak chci... takže k problému:
dejme tomu, že mám dva objekty
class obj1
{
  public $neco;
  public function __construct($neco)
  {
     $this->neco=$neco;
  }
  function metoda($neco2)
  {
     $this->neco=$neco2;
  }
}

class obj2 extends obj1
{
  function zmen_neco_v_obj1($na)
  {
    if(nasledující kód proběhne jenom někdy, a já "nevím" kdy, proto se ptám na tento problém)
      parent::neco=$na;
  }
}

a pak nainstancuju první a druhý objekt
$obj1=new obj1("aha");
$obj2=new obj2();

a teď chci přes $obj2 změnit $neco v $obj1 ... ale to co je tam napsaný (parent::neco=$na) nezmění instanci toho objektu, nýbrž jen tu proměnou která se váže na tu třídu.......
snad jsem to vysvětlil dobře...
teď prosím: POMOC :)
crossbone
Profil *
zapoměl jsem dopsat, že pak volám tu metodu
$obj2->zmen_neco_v_obj1("tady");
echo $obj1->neco;
Alphard
Profil
$obj1 a $obj2 jsou dvě různé instance, takhle to nefunguje.
Dědičnost funguje tak, že rozšíří původní třídu, ale ve výsledku s ní pracujete jako s jednou třídou (jako byste zkopíroval původní kód a trochu ho přepsal). K cizí instanci svého předka nemá žádný vztah.
crossbone
Profil *
aha, díky... ještě dotaz, pomocí čeho bych mohl docílit toho abych se z druhého objektu dostal do prvního/jiného?
Alphard
Profil
Mně napadá pouze řešení s předáním ukazatele na instanci v parametru a ještě si nejsem jist, jestli by to fungovalo. Kdyžtak to zkusím napsat, ale ještě dám čas odborníkům na OOP, kteří se o něm rádi rozepisují, kde jsi, Timy? :-)
crossbone
Profil *
Rád se naučím něco nového :)
Chtěl bych mít nějakou hlavní třídu zvanou Core, kde bych měl určitý metody který bych chtěl zavolat z jakýho-koliv objektu. Myslel jsem že se to dělá tak, že se vytvoří nějak(jak??) podtřída této třídy, a pak se akorát odkážu vejš... ale vůbec nemám potuchu jak to udělat... těším se na radu :)
Timy
Profil
crossbone
ještě dotaz, pomocí čeho bych mohl docílit toho abych se z druhého objektu dostal do prvního/jiného?
Obecně pomocí ničeho, obecně tohle nijak nejde. Aby obj2 mohl měnit něco v obj1, musí na něj mít referenci/odkaz, což obecně (já vím, už potřetí totéž slovo) nemá. Takže pokud potřebuješ z jednoho objektu měnit ten druhý, přidej do obj2 další slot, kde si uchováš referenci na obj1. Něco takového:

<?php
class obj1
{
	public $neco;
	
	public function __construct($neco)
	{
		$this->neco=$neco;
	}
	function metoda($neco2)
	{
		$this->neco=$neco2;
	}
}

class obj2 extends obj1
{
	public $odkaz;
	
	function zmen_neco_v_obj1($na)
	{
		$this->odkaz->metoda($na);
	}
}

$obj1 = new obj1("aha");
$obj2 = new obj2("");
$obj2->odkaz = $obj1;
$obj2->zmen_neco_v_obj1("tady");
echo $obj1->neco;
?>


Tohle sice funguje, ale ta použitá dědičnost tam nemá žádný smysl :-). Dědičnost by se tam alespoň použila třeba v tomto případě:

$obj2->metoda("Metoda v obj2 není definovaná přesto ji můžu zavolat!");
echo $obj2->neco;


V obj2 není metoda „metoda“ definovaná a přesto ji můžu zavolat, protože se zdědí z obj1. Dědění se nepoužívá na to, na co ses to snažil použít. Dědění se používá v případě, kdy máš třídu A a potřebuješ udělat speciálnější případ třídy A. Pak uděláš třídu B a zdědíš ji z A. Můžeš mít třídu DopravniProstredek a specializovanější třídu Auto. Případně mezi to ještě můžeš strčit třeba PozemniDopravniProstredky. Pokud je tedy B speciální případ A, pak dědit. Pokud má B obsahovat A, ale není to speciální případ A (třeba auto má volant, ale volant není speciální typ auta), pak má objekt B obsahovat v nějakém slotu odkaz na objekt A — což se dělá přes nějakou vnitřní proměnnou.

Chtěl bych mít nějakou hlavní třídu zvanou Core, kde bych měl určitý metody který bych chtěl zavolat z jakýho-koliv objektu.
Na to se používají statické metody, což jsou metody, které jsou definovány na úrovni třídy, nikoli na úrovni objektu, takže není třeba vytvářet instance. Ale stejně mám pocit, že to spíš ani nepotřebuješ, že spíš nerozumíš OOP jako takovému a snažíš se v OOP programovat tak, jak jsi byl zvyklý doteď :-). Zkus si přečíst něco víc o teorii k OOP, jinak se budeš pořád ptát na podobné otázky, které v OOP nedávají moc smysl.

Alphard
kde jsi, Timy? :-)
Už už :-).
blizz_boz
Profil
aha, díky... ještě dotaz, pomocí čeho bych mohl docílit toho abych se z druhého objektu dostal do prvního/jiného?

v niektorych jazykoch napr.: c++ existuju spriatelene funkcie pouziva sa klucove slovo friend tieto dokazu pristupovat k privatnym clenom inych tried cim IMHO porusuju princip zapuzdrenia. taktiez si mozes v objekte jedna ulozit referenciu na objekt dva a naopak ale do privatnej alebo protected casti sa tak ci tak nedostanes. inak odporucam knihu:

http://diskuse.jakpsatweb.cz/index.php?action=vthread&forum=9&topic=91361#5
AM_
Profil
Zvaž, jestli není lepší třídu Core napsat jako statickou - pro třídy, kde se nepředpokládá, že by měly více instancí, je to lepší - od statické třídy se totiž netvoří instance, funguje jako samostatná instance. Třeba:
class myStatic{
  public static echoAhoj(){
    echo "ahoj";
  }
}

myStatic::echoAhoj();
Mastodont
Profil
Chtěl bych mít nějakou hlavní třídu zvanou Core, kde bych měl určitý metody který bych chtěl zavolat z jakýhokoliv objektu
U všech ostatních tříd bys musel napsat
extends Core

jako to je třeba v Nette. IMHO se to ale hodí jen u specifických pomocných metod.
AM_
Profil
Mastodont
Tady jde o to, co tím crossbone vlastně myslí. Myslím, že základní třídu pro všechny objekty (něco jako System.Object v Microsoft.NET) nechce, ale spíš prostě metody přístupné odkudkoli.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: