这是我想要实现的一个小例子。我有一个包含许多参数的类 - Dog
。我有一个子课JumpyDog
,我想学习如何“扩展”Dog
的实例,使其成为JumpyDog
的实例。
class Dog {
int age, numberOfTeeth, grumpiness, manyOtherParameters;
JumpyDog learnToJump(int height) {
JumpyDog jumpy = new JumpyDog(this); // I do not want to copy all parameters
jumpy.jumpHeight=height;
return jumpy;
}
}
class JumpyDog extends Dog {
int jumpHeight;
void jump(){}
}
或者我可以这样说:
Dog dog=new Dog();
dog.makeJumpy();
dog.jump()
答案 0 :(得分:2)
您可以在Java中实现Decorator pattern,以避免在"扩展程序期间复制初始对象中的所有字段。通过内部保持对它的引用,但它不再是Dog
(因为Dog
类具有我们避免复制的字段。)
class JumpyDog {
Dog meAsDog;
int jumpHeight;
public JumpyDog(Dog me) {
meAsDog = me;
}
public Dog meAsDog() {
return meAsDog();
}
void jump(){}
}
您可以像以下一样使用它:
Dog dog=new Dog();
JumpyDog meAsJumpy = dog.learnToJump(100);
meAsJumpy.jump()
不,您不能在示例中执行以下操作,因为Dog
没有jump()
方法:
Dog dog=new Dog();
dog.makeJumpy();
dog.jump() // Dog has no method jump
答案 1 :(得分:0)
class Dog {
int age;
int numberOfTeeth;
int grumpiness;
int manyOtherParameters;
boolean hasLearnedHowToJump;
int jumpHeight;
void learnToJump(int heigth) {
hasLearnedHowToJump = true;
jumpHeight = heigth;
}
void jump(){
if(!hasLearnedHowToJump) {
throw new RuntimeException("must learn how to jump first...");
}
}
}
那么你就可以这样使用它:
Dog dog=new Dog();
//dog.jump() would end in a exception...
dog.learnToJump(100);
dog.jump()
答案 2 :(得分:0)
一旦dog
被声明为Dog
类型,这就永远是它的类型。您可以将其投射到任何超级班级,但它仍然是Dog
。
您可以使用复制构造函数。这实际上要求您为所有属性编写一些复制代码,但会为您提供接近您所需风格的内容。
public class Dog {
int age, numberOfTeeth, grumpiness, manyOtherParameters;
public Dog() {
}
public Dog(Dog other) {
other.age = this.age;
other.numberOfTeeth = this.numberOfTeeth;
other.grumpiness = this.grumpiness;
other.manyOtherParameters = this.manyOtherParameters;
}
}
class JumpyDog extends Dog {
int jumpHeight;
void jump(){}
public JumpyDog(Dog other) {
super(other);
}
}
会让你写下像:
Dog dog = new Dog();
JumpyDog jumpyDog = new JumpyDog(dog);
jumpyDog.jump();
离开你2个实例。这将使jumpyDog
跳转,但不会对dog
实例执行任何操作。
答案 3 :(得分:0)
你可以做这样的事情
class Dog {
protected int age, numberOfTeeth, grumpiness, manyOtherParameters;
protected Dog(Dog g) {
// assign all attributes here
}
JumpyDog learnToJump(int heigth) {
return new JumpyDog(this, heigth);;
}
}
class JumpyDog extends Dog {
int jumpHeight;
public JumpyDog(Dog dog, int jumpHeight) {
super(dog);
this.jumpHeight = jumpHeight;
}
void jump(){}
}
然后你可以这样做:
Dog dog=new Dog();
JumpyDog jDog = dog.learnToJump(100);
jdog.jump()
答案 4 :(得分:0)
最好是实施链接论文所描述的Role Object Pattern。这是@Philip Voronov已经建议的类似装饰的图案。有一个概念作为接口,由一个核心和一个抽象类实现,该类表示一个对象可以播放的所有角色的超类。为了缓解object schizophrenia(在逻辑单元对象在许多物理对象之间分配时出现),每次对角色对象的调用(对角色来说都不是特定的)都会被转发到核心对象。
逻辑上,核心及其角色构建一个单元。但是对象被分成核心(管理角色)和对象可以扮演的所有角色。
客户端要么与核心对象交谈,要么与角色对象交谈。您可以在运行时添加和删除角色。
我用你的狗情景写了a short implementation。
它提供了逻辑狗(世界已知的狗的概念)与其所有能力之间的分离。因此,您不必了解先验能力。