Ensure method A is called after every call of B (an abstract implemented method)?
Having this tasteful class
public abstract class CakeSkill
{
//..
boolean cherry=false;
private void finalMandatoryTouch()
{
cherry=true;
}
abstract public void cook();
}
A class that extends it would be something like
class Cheff extends CakeSkill
{
//..
void cook()
{
//..Secret recipe
}
}
But of course this won't work,
finalMandaroryTouch() hasn't been called, then no cake will end with a cherry..
[EDIT开发者_如何学C]
This one could be a solution
class MemoriousCheff extends CakeSkill
{
//..
void cook()
{
//..Secret recipe
finalMandatoryTouch();
}
}
but requires :
- Cheff to have a perfect memory that don't forget to call finalMandatoryTouch()
- Making finalMandatoryTouch() to be protected (at least)
[/EDIT]
It would be great! (but no Java) if something like this could be done
abstract public void cook()
{
@implementedMethod
finalMandatoryTouch();
}
How can be implemented this useful functionality ?
Thank you very much
Change cook
to a protected method cookImpl
then have a public final method called cook:
public final void cook()
{
cookImpl();
finalMandatoryTouch();
}
protected abstract void cookImpl();
That way the subclass only needs to worry about cookImpl
, but callers of cook
get the cherry on top. Callers not in the same package or class hierarchy won't even see cookImpl
, so won't be able to call it directly.
This is the template method pattern, basically.
It's called the Template method pattern.
final public void cook() {
mainCookRecipe();
finalMandatoryTouch();
}
abstract public void mainCookRecipe();
public abstract class CakeSkill {
public void cook() {
doCook();
finalMandatoryTouch();
}
protected abstract doCook();
private finalMandatoryTouch() { ... }
}
Etc.
You could change your cook()
method to an actual method and then invoke a separate abstract
method as well as your finalMandatoryTouch()
method.
In your abstract
class:
public void cook() {
specificCook();
finalMandatoryTouch();
}
abstract void specificCook();
It seems that inheritance is not the right way to model your problem. In Java you can only inherit from one class, and since it's also a very static relationship, it limits your chef in the skills he can perform.
A better way would be to use composition. Cooking skills could be strategies that the chef performs:
interface CookingSkill {
void cook();
}
class CakeSkill implements CookingSkill {
private boolean cherry = false;
private void finalMandatoryTouch() {
cherry = true;
}
public void cook() {
//...
finalMandatoryTouch();
}
}
class Chef {
private CookingSkill cookingSkill;
// getters and setters ...
public void cook() {
// ...
cookingSkill.cook();
// ...
}
}
Now you can assign different cooking skills to your chef.
精彩评论