隐藏超类外观中的非相互方法

时间:2018-02-15 15:27:56

标签: java inheritance design-patterns extensibility

有没有办法可以隐藏不符合特定方法的类型的非相互方法?

假设我们有一个抽象的超类,我们不希望将这些方法暴露给对象本身。我们使用我们想要允许的方法创建一个外观。 (我们不希望能够将猫的年龄设置为32岁。)

我最终在一个场景中,我公开了一个特定子类的方法,这个子类实际上是针对另一个子类的。 (即使我们在方法中可以控制类型是正确的)

场景:

public abstract class Animal {

    //setters and code we want to protect
}

public class Cat extends Animal{

    private boolean giveBirth;

    public void giveBirth(){giveBirth = true;}

    //setters etc


}

public class Bird extends Animal{

    private boolean layEgg;

    public void layEgg(){layEgg = true;}

    //setters etc

}

public class FacadeAnimal {

    Animal animal;

    public FacadeAnimal(Animal a){
        animal = a;
    }

    public void layEgg(){
        if(animal instanceof Bird){
            ((Bird) animal).layEgg();
        }
    }

    public void giveBirth(){
        if(animal instanceof Cat){
            ((Cat) animal).giveBirth();
        }
    }

}

因此,在这种情况下,如果我们想要layEgg,我们可以控制类型需要为Bird的方法内部。但是我们也可以让一只猫躺下来。虽然逻辑得到了解决,但让猫可以选择产卵仍然不是很直观。

我认为可以创建一个" Facade继承结构",我们为每个子类创建一个特定子类的外观。但就可扩展性而言,这意味着我们将迫使未来的开发人员不仅创建一个子类,而且还要实现它的外观。

这是要走的路还是我们可以改变我们的方式?

干杯!

编辑:也许动物场景不是很清楚。

它可以以同样的方式是两辆不同的汽车,其中一辆有涡轮增压器,一辆没有,如果" activateTurbo"方法存在于立面中,我可以在实际上没有涡轮增压器的汽车上调用activateTurbo方法。

2 个答案:

答案 0 :(得分:0)

我将giveBirth()和layEgg()统一到Animal中的一个单独方法中,子类决定自己该做什么。

您还可以将此行为封装到一个新类中,例如具有子类LayEggStrategy或GiveBirthStrategy的NextGenerationStrategy。 Animal(Bird或Cat)的子类选择自己的策略。因此,当你与动物一起工作时,你不在乎它会产卵或分娩。

答案 1 :(得分:0)

giveBirth()layEgg()等方法名称过于具体 - 请考虑更常见的内容,例如:

public abstract class Animal {
    public void reproduce();
}

然后每个子类都可以根据需要实现。例如:

public class Cat extends Animal {
    public void reproduce() {
       liveBirth();
   }

   private void liveBirth() {
       // ...
   }
}

public class Bird extends Animal {
    public void reproduce() {
       layEgg();
   }

   private void layEgg() {
       // ...
   }
}

这种方法可能会导致私有方法中至少出现一些重复的代码。正如@Lini所说,结合战略模式。一点点重构,它从继承变为组合。