java - java扩展类的实例是有可能

  显示原文与译文双语对照的内容
133 5

例如我有类动物,类 cat ( ,。),它扩展了动物。现在我要声明类宠物,它也是动物,我希望它是由任何现存的动物 比如 cat 构建的。

因此,我需要这样的构造函数:

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();
 }
}

这意味着我只需要 <中的Animal() ( 这是 protected ) 构造函数。>?

时间:原作者:0个回答

93 3

即使在你的编辑之后,你的意图对我也不太清楚。似乎你只是在寻找一种允许你在运行时使用的方法:这个 cat 以前是个 stray,但它现在变成了别人的宠物。

在:中,你可以使用一个非常简单且直接的正向解决方案- 向 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,.. .
}

但是要注意,这种编码方式会迅速增加类的数量。它真正取决于你计划做什么,而不是这个。我想说这是的快速'n'dirty解决方案。

对于更复杂的解决方案,请检查其他 answer(s) 。

EDIT1: Fildor正确指出了方法 sayMeow() 不是一个好主意。最好在 Animal 中使用 makeNoise() 方法并在子类中重写它以获得不同类型动物的特定行为。现在,如果你不想实际创建 Animal 类的实例,那么还可以创建类 abstract,以及 makeNoise() 方法。这将确保每个子类都必须实现 makeNoise() 方法。或者,如果方法未被重写,则可以很好地使用静音动物的默认行为。

EDIT2: 这个答案对相关问题可能会影响你的情况。它是关于 C#的,但原则转换为 Java 。

原作者:
144 4

你所描述的是完全可能的,通常被称为"装饰器 Pattern"。

只有链接坏了,我会在以后有更多时间的时候阐述。

同时,维基百科有更多信息:装饰器 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可能是抽象的。你的动物实现( CatDog) 然后将覆盖该方法,使它的各自的噪声("","miow"。) 。

在Fragment中,只有宠物才能发出噪音。因为有多种方法可以做到这一点,所以让它变得更加复杂。

你可以让decorator保存一个声音并覆盖makeNoise以使它的声音。就像这样:

Cat catInstance = new Cat();
catInstance.makeNoise();//Default impl: NOP =>"" - no sound.
Animal pet = new Pet( catInstance,"Mieow" );
pet.makeNoise();//=>"Mieow"

所有这一切的要点是:你想避免使用 instanceOf你不关心这只动物是 cat 狗。宠物猫还是宠物狗。他们应该在and时发出正确的声音。如果你的宠物不是宠物,那么你就可以在他们的宠物或者特定的孩子身上保持安静。

:再次阅读我的答案,它更像一个策略,而不是一个 Decorator 。策略改变了事情的执行方式,而Decorator将添加特性。

因这里,为了成为 true 修饰器,这意味着 makeNoise 将在 Pet 界面中。也就是说你不能把这种方法叫做动物。

这就是为什么我把我的建议从"装饰器"改为"策略"。

上面的例子仍然保持。你将有一个"默认值"策略,并使用像实现方法这样的decorator注入"宠物"-strategy 。

当然,也可以通过不同的方式实现 Pattern 更严格的实现。

最后if( x instanceof X).. .总是给"访客"-bell播放音乐。

原作者:
...