web-dev-qa-db-fra.com

Comment déclarer une méthode abstraite en classe non abstraite en PHP?

class absclass {
    abstract public function fuc();
}

rapports:

Erreur irrécupérable PHP: Class absclass contient 1 méthode abstraite et doit donc être déclaré abstrait ou mettre en œuvre les méthodes restantes (absclass :: fuc)

Je veux savoir ce que cela signifie par implémenter les méthodes restantes , comment?

48
user198729

Je présume que méthodes restantes fait en fait référence aux méthodes abstraites que vous essayez de définir (dans ce cas, fuc()), car les méthodes non abstraites qui existent peuvent quand même bien fonctionner. C'est probablement un message d'erreur qui pourrait utiliser une meilleure formulation: où il est dit restant, il devrait dire abstract.

Le correctif est assez simple (cette partie du message d'erreur convient): vous devez changer ceci:

abstract public function fuc();

... dans une mise en œuvre appropriée:

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

... ou, alternativement et selon vos besoins, résumez toute la classe:

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

Voir le chapitre sur Abstraction de classe dans le manuel PHP :

PHP 5 introduit des classes et des méthodes abstraites. Les classes définies comme abstraites ne peuvent pas être instanciées et toute classe contenant au moins une méthode abstraite doit également être abstraite. Les méthodes définies comme abstraites déclarent simplement la signature de la méthode - elles ne peuvent pas définir l'implémentation.

Cela signifie que vous devez soit

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

ou 

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

Une classe abstraite ne peut pas être directement instanciée, mais elle peut contenir des méthodes abstraites et non abstraites. 

Si vous étendez une classe abstraite, vous devez implémenter toutes ses fonctions abstraites ou rendre la sous-classe abstraite.

Vous ne pouvez pas remplacer une méthode régulière et la rendre abstraite, mais vous devez (éventuellement) remplacer toutes les méthodes abstraites et les rendre non abstraites.

<?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();

?>

Ce programme explose avec:

Erreur PHP irrécupérable: Class BadDog contient 1 méthode abstraite et doit donc être déclaré abstrait ou mettre en œuvre les méthodes restantes (Aboiement) 

Si vous commentez la classe BadDog, le résultat est le suivant:

name: Fred
gender: female
bowowwaoar

Si vous essayez d’instancier un chien ou un PassTheBuckDog directement, procédez comme suit:

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

..il bombes avec:

Erreur irrécupérable PHP: Impossible d'instancier classe abstraite chien

ou (si vous commentez la mauvaise ligne)

Erreur irrécupérable PHP: Impossible d'instancier classe abstraite PassTheBuckDog

Vous pouvez cependant appeler une fonction statique d'une classe abstraite:

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();

Cela fonctionne très bien.

26
Shavais

Les mots clés abstraits sont utilisés pour étiqueter des classes ou des méthodes en tant que modèles. Cela ressemble aux interfaces, mais peut contenir des variables et des implémentations de méthodes.

Il y a beaucoup de malentendus concernant les classes abstraites. Voici un exemple de classe abstraite Dog. Si un développeur souhaite créer une classe Dog de base pour d'autres développeurs ou pour qu'il s'étende lui-même, il déclare la classe comme abstraite. Vous ne pouvez pas instancier directement la classe Dog (personne ne le peut), mais vous pouvez étendre Dog de votre propre classe. SmartDog étend chien etc.

Toutes les méthodes déclarées abstraites par la classe Dog doivent être implémentées manuellement dans chaque classe qui étend Dog.

Par exemple, la classe abstraite Dog a une méthode abstraite Dog :: Bark (). Mais tous les chiens aboient différemment. Ainsi, dans chaque sous-classe de chien, vous devez décrire COMMENT ce chien aboie de manière concrète. Vous devez donc définir par exemple SmartDog :: Bark ().

3
Alex Yaroshevich

Cela signifie que le propre d'une classe abstraite a au moins une méthode abstraite. Votre classe doit donc implémenter la méthode (non abstraite) ou être déclarée abstraite.

2
instanceof me

Vous êtes légèrement dérouté par ce message d'erreur. Dans ce cas, puisque c'est dans cette classe que fuc est en cours de définition, cela n'aurait aucun sens de l'implémenter dans cette classe. Ce que l'erreur essaie de vous dire, c'est qu'une classe non abstraite ne peut pas avoir de méthodes abstraites. Dès que vous mettez une méthode abstraite dans la définition d'une classe, vous devez également marquer la classe elle-même comme abstraite.

2
AakashM

Je voulais utiliser une méthode abstraite dans une classe non abstraite (classe normale?) Et j'ai découvert que je pouvais envelopper le contenu de la méthode dans une instruction 'if' avec get_parent_class () comme suit:

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

Ou, en action (testé dans un fichier sur la ligne de commande: 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 () Documentation

0
Brent Self