Key class has a non-abstract method getDescription() (for many purposes).
Key class is extended by (one of) "a child abstract class".
"A child abstract class" is extended by "a concrete class".
I want to force "a concrete class" to implement getDescription() method and try to redeclare it in "a child abstract class" as an abstract method, but fail.
So, is it possible to redeclare non-abstract method as abstract in php? If not - how to force a concrete method to be implemented?
The key class. I need getDescription as declared in this way for many purposes.
abstract class beverage{
public $description = "Unknown beverage";
public function getDescription(){return $this->description;}
};
The abstract class, overriden getDescription() - but does not work.
abstract class condimentDecorator extends beverage {
//public abstract function getDescription();
};
Concrete class, which MUST reimpliment getDescription.
class milk extends condimentDecorator{
public $beverage;
public function __construct(beverage $beverage){$this->beverage = $beverage;}
public function getDescription(){return $this->beverage->getDescription().", Milk";}
};
is it possible to redeclare non-abstract method as abstract in php?
No, you can't do that in PHP
It seems that you are trying to implement a Decorator pattern.
In such case the presented classes chain is over-complicated.
Decorator pattern is dedicated to add(extend) functionality to another class without changing its structure.
The following is a classical and more optimal approach of implementing decorators:
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();
The output:
Description: Milk beverage with condiment
I think the main problem is how you're implementing this.
If you've an class that already implements a method all it's children will by default implement it.
So lets say you've the following:
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
}
So what you want to do is overwrite the default function.
I think you should take a time and re-think if the structure is correct.
The condimentDecorator couldn't be a interface?
Editd:
My suggestion would be do something Like this:
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.
}
So then the Class avocado will need to implements getDescription as Beverage would've as well, and you should be conflict free.