例如,我有动物类,以及扩展动物类的Cat(Bird,Dog,Fish ......)。现在我想声明类Pet,它也是Animal,我希望它可以从任何现有的Animal构建,例如猫。
所以我需要像这样的构造函数:
class Pet extends Animal{
private String nickname;
private Animal kind;
Pet(Animal a, String nickname){
<...>;
this.nickname = nickname;
}
}
编辑: 我想要这样的东西:
Cat cat = new Cat();
Animal pet = new Pet(cat, "Foo");
if (pet instanceof Pet){
if (pet.kind instanceof Cat){
Pet.sayMeow();
}
}
这是否意味着我只需要&lt; ...&gt;中的Animal()
(受保护的)构造函数?
答案 0 :(得分:1)
即使在您进行编辑之后,您的意图对我来说也不是很清楚。看起来好像你只是想找到一种方法,让你在运行时说:&#34;这只猫以前是流浪的,但它现在只是变成了某人的宠物!&#34 ;
如果那是对的,你可以选择一个非常简单直接的解决方案 -
将此功能添加到Animal
类:
public class Animal {
private boolean isPet = false;
private String nickname = "";
public Animal() {
/*...*/
}
public makeStray() {
isPet = false;
nickname = "";
}
public makePet(String nickname) {
isPet = true;
this.nickname = nickname;
}
public boolean isPet() {
return isPet;
}
public void makeNoise() {
/* Override in child classes */
}
}
根据你的例子,你可以简单地做:
Animal cat = new Cat();
cat.makePet("Foo");
if (cat.isPet()) { // Apparently, only pet cats ever meow.
cat.makeNoise(); // Cats will meow, dogs will bark, ...
}
但请注意,这种编码方式可能会很快膨胀。这实际上取决于你计划用它做什么而不是这个。我说这是 quick&#39; n&#39;脏解决方案。
有关更复杂的解决方案,请查看其他答案。
EDIT1 :正如Fildor正确指出的那样,使用方法sayMeow()
并不是一个好主意。最好在makeNoise()
中使用Animal
方法并在子类中覆盖它以获取不同种类动物的特定行为。现在,如果您从未想要实际创建Animal
类的实例,您还可以创建类abstract
以及makeNoise()
方法。这将确保每个子类都必须实现makeNoise()
方法。或者,如果方法没有被覆盖,你可以使用静音动物的默认行为。
EDIT2 :This answer对相关问题可能会更清楚地了解您的情况。它是关于C#的,但原则转化为Java。
答案 1 :(得分:0)
您描述的内容完全可能,通常称为“装饰模式”。
仅链接答案很糟糕,稍后我会详细说明我有更多时间。
与此同时,维基百科有更多信息:Decorator Pattern。
1 Cat cat = new Cat();
2 Animal pet = new Pet(cat, "Foo");
3 if (pet instanceof Pet){
4 if (pet.kind instanceof Cat){
5 Pet.sayMeow();
6 }
7 }
这样做的缺点是你需要使用instanceOf
。通常,您的Animal
课程会有一个方法 - 让我们称之为makeNoise
。可能是抽象的。你动物实现(Cat
,Dog
...)然后将覆盖该方法以产生各自的噪音(“Bark”,“Miow”......)。
在片段中,似乎只有宠物可以发出声音......这会使它变得有点复杂,因为会有各种方法来做到这一点。
您可以让装饰者保存声音并覆盖makeNoise以发出声音。像这样:
Cat catInstance = new Cat();
catInstance.makeNoise(); // Default impl: NOP => "" - no sound.
Animal pet = new Pet( catInstance, "Mieow" );
pet.makeNoise(); // => "Mieow"
所有这一切的要点是:您希望避免使用instanceof
。你不在乎动物是猫,宠物猫还是宠物狗。如果被告知,他们应该发出正确的声音。所以你可以拥有一个“动物”的集合,并告诉他们所有人“makeNoise”,每个人都会保持沉默,吠叫或mieow,如果他们是宠物或Animal
的特定孩子,你不必照顾。 / p>
编辑:再次阅读我的答案,它更像是一个政策(策略模式),而不是一个装饰器。 该政策改变了某些事情的完成方式,而装饰者则会添加该功能。
因此,要成为一名真正的装饰者,这意味着makeNoise
将位于Pet
的界面中。这意味着你无法在动物身上调用该方法。
这就是为什么我将我的建议从“装饰者”改为“Strategy”模式。
上面的例子仍然存在。您可以采用“默认”策略,并使用类似Decorator的实现方法注入“Pet”-Strategy。
当然,所有这些也可以采用不同的方式来更严格地实施模式。
最后,if( x instanceof X) ...
总是叮嘱“访客” - 贝尔。