php Clases: Herencia

kas

Buenas, estoy empezando en esto del php y quiero hacerlo en clases, asi que una de las caracteristicas que mas me gusta usar es la de herencia. En este caso, estoy un poco perdido, porque quieoro saber como debo declarar una variable en una clase base para acceder desde la derivada, es decir

class.A.php

class A
{
	var $_cfg;
	
function __construct($cfg)
{
	$this->_cfg = $cfg;
}

function Display()
{
	echo $this->_cfg->a;
}
}

class.B.php

class B extends A
{
	function __construct($cfg)
	{
		parent::__construct($cfg);
	}
	
function Display2()
{
	echo parent::$_cfg->a . " 2";
}
}

index.php

<body>
<?php
$a = new A($cfg);
$b = new B($cfg);

$a->Display();
echo "< b r />";
$b->Display();
echo "< b r />";
$b->Display2();
echo "<br>";
?>
</body>

Me sale esto:


Hola Mundo!
Hola Mundo!

Fatal error: Access to undeclared static property: A::$_cfg in C:\xampp\htdocs\test\class.B.php on line 11

A ver si podeis hecharme un cable con el tema de las visibilidades en la OOP de php, gracias de antemano.

Fr4nk0

supongo que $cfg lo declaras antes de crear los objetos ¿no?.

Y respecto a q no puede acceder a los atributos del padre, lo mejor es que crees un metodo consultor en el padre que sea getCFG() { return $this->cfg;} y que uses parent::getCFG() para acceder al atributo (el metodo será publico o protected sino el hijo no podrá acceder).

Otra solución sin usar métodos es, en vez de declarar en el padre var $cfg, prueba "public $cfg" o más seguro "protected $cfg" (con esto nos aseguramos que solo la clase padre y sus clases hijas pueden acceder al atributo).

De todas formas, mi opinión es que te acostumbres a crear métodos get y set para cada atributo y asi no tocar a pelo los atributos que no es una buena técnica.

Ya dirás si con esto que te he dicho funciona (métodos o poner el tipo del atributo public o protected).

Puni

no tengo ni zorra de php pero imagino q por omision la variable sera privada, las cosas privadas lo normal es q no se hereden como ya te han dicho

si quieres hacer algo orientado a objetos empezar poniendo atributos publicos no es el mejor camino xD

BlisZ

no uses var para declarar variables, eso es de php4 con clases cutres

desde php5 puedes usar public, protected y private, mirate el tema de visibilidad en php.net http://www.php.net/manual/en/language.oop5.visibility.php

kas

Gracias tios ahora lo tenog claro, he empezado muy a saco.

En cuanto al tema de Get/Set es lo que iva a hacer en priemra instancia, per me interesaba conocer las visibilidades antes de merendarme el manual de php.

Tampoco se porque he puesto var, lo vi en un ejemplo el otro dia y copy&paste.

Le hechare un vistazo y edito, gracias :)

Vale funciona perfectamente ;)

Asi queda la cosa:

class.A.php

class A
{
	private $_cfg;
	
function __construct($cfg) { $this->_cfg = $cfg; }

function Display() { echo $this->_cfg->a; }

function GetCfg() { return $this->_cfg; }
}

class.B.php

class B extends A
{
	function __construct($cfg) { parent::__construct($cfg); }
	
function Display2()
{
	$cfg = $this->GetCfg();
	echo $cfg->a . " 2";
}
}

index.php

<?php
$a = new A($cfg);
$b = new B($cfg);

$a->Display();
echo "<br>";
$b->Display();
echo "<br>";
$b->Display2();
echo "<br>";
?>

</body>

Resultado:


Hola Mundo!
Hola Mundo!
Hola Mundo! 2

Y que buscando en google "herencia php" y cosas asi no haya encontrado ni un puto ejemplo de esto? Que es lo mas basico?

guner

No accedas a A::$_cfg por parent::, simplemente por $this. De todas formas en ningún momento le das valor. Inicias una instancia de los objetos con un parámetro sin definir ($cfg).

Anda que no llego tarde (y vago por la reply...)

kas

Bueno en mi docigo tengo un include del config.php donde declaro una variable $cfg, que inicializo asi:

<?php
$cfg->$version	= '2';
?>

que por cierto me da este error:


Fatal error: Cannot access empty property in C:\xampp\htdocs...\config.php on line 31

Si alguno puede echarme una manita, aprovecho el post.

BlisZ

q hay en la lina 31? $cfg es un objeto?

Fr4nk0

Tal como lo estas usando $cfg es un objeto. El fallo está en que tu pasas $cfg al objeto que creas y $cfg tiene una propiedad que es version que la inicializas a 2. El fallo está en que tu después cuando creas los objetos A y B, en la función display() intentas mostrar la propiedad a ($cfg->a) de $cfg y esa propiedad no la tiene. O cambias en el config.php $cfg->version = "2" a $cfg->a ="2", o cambias en las funciones Display de la clase A y B , el echo $this->cfg->a por $this->cfg->version (sólo uno de los 2 cambios, sino estarás en las mismas).

Ya dirás si con eso te funciona. Byes!

kas

Yep, ya esta arreglado, el fallo era el dollar:

MAL

<?php
$cfg->$version = '2';
?>

BIEN

<?php
$cfg->version = '2';
?>

Usuarios habituales

  • kas
  • Fr4nk0
  • BlisZ
  • guner
  • Puni