tipos poo metodos interfaces herencia ejemplos ejemplo clases clase abstractas abstracta php abstract-function

poo - php herencia



¿Cómo declarar el método abstracto en una clase no abstracta en PHP? (7)

class absclass { abstract public function fuc(); }

informes:

Error fatal de PHP: la clase absclass contiene 1 método abstracto y, por lo tanto, debe declararse abstracta o implementar los métodos restantes (absclass :: fuc)

Quiero saber qué significa implementar los métodos restantes , ¿cómo?


Las palabras clave abstractas se utilizan para etiquetar clases o métodos como patrones. Es similar a las interfaces pero puede contener variables e implementaciones de métodos.

Hay muchos malentendidos con respecto a las clases abstractas. Aquí hay un ejemplo de una clase abstracta de perros. Si un desarrollador quiere crear una clase de perro básica para otros desarrolladores o para que él mismo la extienda, declara que la clase es abstracta. No puede crear una instancia de la clase Dog directamente (nadie puede), pero puede extender Dog según su propia clase. SmartDog extiende perro etc.

Todos los métodos declarados como abstractos por la clase Dog deben implementarse manualmente en cada clase que extienda Dog.

Por ejemplo, la clase abstracta Dog tiene un método abstracto Dog :: Bark (). Pero todos los perros ladran de manera diferente. Por lo tanto, en cada subclase de perro debe describir CÓMO ese perro ladra de manera concreta, por lo que debe definir, por ejemplo, SmartDog :: Bark ().


Quería usar un método abstracto dentro de una clase no abstracta (¿clase normal?) Y encontré que podía envolver el contenido del método en una declaración ''if'' con get_parent_class () de esta forma:

if (get_parent_class($this) !== false) {

O, en acción (probado en un archivo en la línea cmd: php -f "abstract_method_normal_class_test.php"):

<?php class dad { function dad() { if (get_parent_class($this) !== false) { // implements some logic echo "I''m " , get_class($this) , "/n"; } else { echo "I''m " , get_class($this) , "/n"; } } } class child extends dad { function child() { parent::dad(); } } $foo = new dad(); $bar = new child(); ?> Output: I''m dad I''m child

PHP get_parent_class () Documentación


Significa que lo propio de una clase abstracta es tener al menos un método abstracto. Por lo tanto, su clase debe implementar el método (no abstracto) o declararse abstracto.


Supongo que los métodos restantes en realidad se refieren a los métodos abstractos que está tratando de definir (en este caso, fuc() ), ya que los métodos no abstractos que podrían existir están bien de todos modos. Probablemente sea un mensaje de error que podría usar una mejor redacción: donde dice que debe decir, debe decir abstracto .

La solución es bastante sencilla (esa parte del mensaje de error está bien): necesita cambiar esto:

abstract public function fuc();

... en una implementación adecuada:

public function fuc(){ // Code comes here }

... o, alternativamente y según sus necesidades, haga que toda la clase sea abstracta:

abstract class absclass { abstract public function fuc(); }


Te estás desviando un poco por este mensaje de error. En este caso, dado que es dentro de esta clase que se está definiendo fuc , realmente no tendría sentido implementarlo en esta clase. Lo que el error está intentando decirle es que una clase no abstracta no puede tener métodos abstractos. Tan pronto como coloque un método abstracto en la definición de una clase, también debe marcar la clase como resumen.


Una clase abstracta no puede ser instanciada directamente, pero puede contener tanto métodos abstractos como no abstractos.

Si extiende una clase abstracta, debe implementar todas sus funciones abstractas o hacer que la subclase sea abstracta.

No puede anular un método regular y hacerlo abstracto, pero (eventualmente) debe anular todos los métodos abstractos y hacerlos no abstractos.

<?php abstract class Dog { private $name = null; private $gender = null; public function __construct($name, $gender) { $this->name = $name; $this->gender = $gender; } public function getName() {return $this->name;} public function setName($name) {$this->name = $name;} public function getGender() {return $this->gender;} public function setGender($gender) {$this->gender = $gender;} abstract public function bark(); } // non-abstract class inheritting from an abstract class - this one has to implement all inherited abstract methods. class Daschund extends Dog { public function bark() { print "bowowwaoar" . PHP_EOL; } } // this class causes a compilation error, because it fails to implement bark(). class BadDog extends Dog { // boom! where''s bark() ? } // this one succeeds in compiling, // it''s passing the buck of implementing it''s inheritted abstract methods on to sub classes. abstract class PassTheBuckDog extends Dog { // no boom. only non-abstract subclasses have to bark(). } $dog = new Daschund(''Fred'', ''male''); $dog->setGender(''female''); print "name: " . $dog->getName() . PHP_EOL; print "gender: ". $dog->getGender() . PHP_EOL; $dog->bark(); ?>

Ese programa bombardea con:

Error fatal de PHP: la clase BadDog contiene 1 método abstracto y, por lo tanto, debe declararse abstracta o implementar los métodos restantes (Dog :: bark)

Si comenta la clase BadDog, la salida es:

name: Fred gender: female bowowwaoar

Si intentas crear una instancia de un perro o un PassTheBuckDog directamente, así:

$wrong = new Dog(''somma'',''it''); $bad = new PassTheBuckDog(''phamous'',''monster'');

..es bombas con:

Error fatal de PHP: No se puede instanciar la clase abstracta Perro

o (si usted comenta la línea $ incorrecta)

Error fatal de PHP: No se puede instanciar la clase abstracta PassTheBuckDog

Sin embargo, puede llamar a una función estática de una clase abstracta:

abstract class Dog { .. public static function getBarker($classname, $name, $gender) { return new $classname($name, $gender); } .. } .. $other_dog = Dog::getBarker(''Daschund'', ''Wilma'', ''female''); $other_dog->bark();

Eso funciona bien.


Vea el capítulo sobre abstracción de clase en el manual de PHP :

PHP 5 introduce clases y métodos abstractos. Las clases definidas como abstractas no pueden ser instanciadas, y cualquier clase que contenga al menos un método abstracto también debe ser abstracta. Los métodos definidos como abstractos simplemente declaran la firma del método, no pueden definir la implementación.

Significa que tienes que

abstract class absclass { // mark the entire class as abstract abstract public function fuc(); }

o

class absclass { public function fuc() { // implement the method body // which means it won''t be abstract anymore }; }