2016-12-29 1 views
2

La classe de clé a une méthode non-abstraite getDescription() (à de nombreuses fins).PHP. Est-il possible de redéclarer la méthode non-abstraite comme abstraite?

La classe de clés est étendue par (l'un des) "une classe abstraite enfant".

"Une classe abstraite enfant" est étendue par "une classe concrète".

Je veux forcer "une classe concrète" pour implémenter la méthode getDescription() et essayer de le redéclare dans "une classe abstraite enfant" comme une méthode abstraite, mais échouer.

Alors, est-il possible de redéclarer la méthode non-abstraite comme abstraite en php? Si non - comment force une méthode concrète à mettre en œuvre?

La classe de clé. J'ai besoin de getDescription comme déclaré de cette manière à plusieurs fins.

abstract class beverage{ 
public $description = "Unknown beverage"; 
public function getDescription(){return $this->description;} 
}; 

La classe abstraite, overriden getDescription() - mais ne fonctionne pas.

abstract class condimentDecorator extends beverage { 
    //public abstract function getDescription(); 
}; 

Classe de béton, qui doit reimpliment getDescription.

class milk extends condimentDecorator{ 
public $beverage; 
public function __construct(beverage $beverage){$this->beverage = $beverage;} 
public function getDescription(){return $this->beverage->getDescription().", Milk";} 
}; 
+1

Peut-on voir le code? – Federkun

Répondre

2

est-il possible de redéclarer la méthode non-abstraite comme abstraite en PHP?

Non, vous ne pouvez pas le faire en PHP


Il semble que vous essayez de mettre en œuvre un modèle Décorateur.
Dans ce cas, la chaîne des classes présentées est trop compliquée.
Le décorateur est conçu pour ajouter (étendre) des fonctionnalités à une autre classe sans modifier sa structure.
Ce qui suit est une approche classique et plus optimale de la mise en œuvre décorateurs:

abstract class Beverage { 
    public $description = "Unknown beverage"; 

    public function getDescription(){ 
     return $this->description; 
    } 
} 

class CondimentDecorator extends Beverage { 
    protected $beverage; 

    public function __construct(Beverage $beverage) { 
     $this->beverage = $beverage; 
    } 

    public function getDescription() { 
     return "Description:\t" . $this->beverage->getDescription() . " with condiment"; 
    } 
}; 

class Milk extends Beverage { 
    public function __construct($desc = "") { 
     $this->description = $desc; 
    } 
} 

$milk = new Milk('Milk beverage'); 
$milk_with_condiment = new CondimentDecorator($milk); 
echo $milk_with_condiment->getDescription(); 

La sortie:

Description: Milk beverage with condiment 
+0

Reste que la question clé demeure: "est-il possible de redéclarer la méthode concrète comme abstraite en php"? – bbe

+0

@bbe, voir ma mise à jour – RomanPerekhrest

+0

cette redéclaration de "concret à abstrait" est cependant possible dans java. – bbe

0

Je pense que le principal problème est de savoir comment vous mettre en œuvre cela.

Si vous avez une classe qui implémente déjà une méthode, tous ses enfants l'implémenteront par défaut.

Disons donc que vous avez les suivantes:

Class A { 
    public function niceFunction() {return "some awesome return with potato"; } 
} 

Class B extends A{ 
    //it already has niceFunction 
} 
Class Avocado extends B { 
    // it also already has NiceFunction 
} 

Alors ce que vous voulez faire est de remplacer la fonction par défaut.

Je pense que vous devriez prendre le temps de repenser si la structure est correcte.

Le condimentDecorator ne pouvait pas être une interface?

Editd:

Ma suggestion serait faire quelque chose comme ceci:

Interface Descritible() 
{ 
    public function getDescription(); 
} 

class beverage implements Descritible{ 
//do the stuff you need to do 
// It must have getDescription() cuz it implements Descritible 
} 

abstract class A implements Descritible{} 

class Avocado extends A { 
    //It'll not have a default implementation of getDescription 
    //so it'll have to implement it. 
} 

Alors l'avocat de classe devra en œuvre getDescription comme les boissons l'aurait fait aussi bien, et vous devriez être sans conflit .

+0

J'ai pensé à utiliser une interface, je n'ai pas essayé, mais j'ai le sentiment que cela va aussi mener à un conflit. La classe de boisson doit avoir getDescription() concrète; définir une interface pour une classe enfant avec la même méthode que dans le parent ne sonne déjà pas bien. Le problème d'abstraction (c'est-à-dire, redéclarer le concret à l'abstrait) restera toujours. – bbe

+0

Ma suggestion serait de faire quelque chose comme ceci: – Unamed