Java 如何在包之外修改预定义的包方法?
假设我有一个名为“animal”的包,其中包括动物父类、Cat从animal扩展而来、Dog也从animal扩展而来。然而,动物的设计是这样的:Java 如何在包之外修改预定义的包方法?,java,design-patterns,dispatcher,visitor-pattern,Java,Design Patterns,Dispatcher,Visitor Pattern,假设我有一个名为“animal”的包,其中包括动物父类、Cat从animal扩展而来、Dog也从animal扩展而来。然而,动物的设计是这样的: class Animal { int amount; Animal next; // Then a constructor initializes these. drinkWater(int n) { ... } } public void drinkWwater(int n) { amount -= n; if (amount
class Animal {
int amount;
Animal next; // Then a constructor initializes these.
drinkWater(int n) { ... }
}
public void drinkWwater(int n) {
amount -= n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
class NonThirstyCat extends Cat {
Cat(int amount, Animal next) {
super(amount, next);
}
@Override
public void drinkWater(int n) {
amount += n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
}
class FixedAnimal extends Animal {
public static Animal fix(Animal a) {
Animal result = a;
if (a instanceof Cat || a instanceof Dog)
result = new FixedAnimal(a);
if (a.next != null) a.next = fix(a.next);
return result;
}
Animal a;
FixedAnimal(Animal a) {
super(0, null);
this.a = a;
}
public void drink(int n) {
// do stuff
if (a.next != null) a.next.drink(n);
}
}
猫狗类遵循以下结构:
class Cat extends Animal {
Cat(int amount, Animal next) {
super(amount, next);
}
@Override
drinkWater(int n) { .. }
}
它们都有如下方法drinkWater():
class Animal {
int amount;
Animal next; // Then a constructor initializes these.
drinkWater(int n) { ... }
}
public void drinkWwater(int n) {
amount -= n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
class NonThirstyCat extends Cat {
Cat(int amount, Animal next) {
super(amount, next);
}
@Override
public void drinkWater(int n) {
amount += n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
}
class FixedAnimal extends Animal {
public static Animal fix(Animal a) {
Animal result = a;
if (a instanceof Cat || a instanceof Dog)
result = new FixedAnimal(a);
if (a.next != null) a.next = fix(a.next);
return result;
}
Animal a;
FixedAnimal(Animal a) {
super(0, null);
this.a = a;
}
public void drink(int n) {
// do stuff
if (a.next != null) a.next.drink(n);
}
}
公共饮用水(int n){
数量-=n;
如果(金额<0)金额=0;
如果(next!=null)next.drinkWater(n);
}
我现在要做的是,我创建了一个动物的“链表”,每个动物都按顺序喝水。然而,假设一只猫喝了n量的水,它会将n+1量的水传递给它的下一只猫
我的目的是找到一个解决方案,以克服“不要触摸原始动物包装,而是改变饮用水的行为每一个”的问题。我在课堂上提出了一个“著名”的天真解决方案:
class InvokeStaticTypeBDrink {
static void typeBdrink(Animal animal, int n) {
animal.amount -= n;
if (animal.amount < 0) animal.amount = 0;
if (animal.next != null) {
if (animal instanceof Cat)
InvokeStaticTypeDrink.drinkWater(animal.next, n+1);
else if (animal instanceof Dog)
InvokeStaticTypeDrink.drinkWater(animal.next, n-1);
else
InvokeStaticTypeDrink.drinkWater(animal.next, n);
}
}
}
类InvokeStaticTypeBDrink{
静态空隙型溜冰场(动物,int n){
动物数量-=n;
如果(animal.amount<0)animal.amount=0;
if(animal.next!=null){
if(猫的动物实例)
InvokeStaticTypeDrink.drinkWater(animal.next,n+1);
else if(狗的动物实例)
调用EstaticTypeDrink.drinkWater(动物,下一步,n-1);
其他的
调用EstaticTypeDrink.drinkWater(动物,下一个,n);
}
}
}
然后,我开始研究。因为这看起来真的是又快又脏的解决方案
所以,我发现了一种叫做“访问者模式”的设计模式。好的,非常酷的模式解决了双重分派的问题,但我这边有一个问题:Visitable接口(声明accept()方法)应该由原始动物“实现”。然而,我的目标是“不要对原始动物包装做任何修改,但要改变饮用水的行为”。我很确定我错过了什么
所以,您认为稍微修改一下,访问者模式仍然有效,还是另一种模式/解决方案更好?谢谢。如果您不想接触原始类,那么应用访问者模式的唯一方法就是将原始类包装到新的(包装器)类中 无论如何,如果你只是想改变一些动物的行为,那么在你的情况下,我只想扩展那些特定的类,并覆盖饮酒行为 那么你会有一只这样的猫:
class Animal {
int amount;
Animal next; // Then a constructor initializes these.
drinkWater(int n) { ... }
}
public void drinkWwater(int n) {
amount -= n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
class NonThirstyCat extends Cat {
Cat(int amount, Animal next) {
super(amount, next);
}
@Override
public void drinkWater(int n) {
amount += n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
}
class FixedAnimal extends Animal {
public static Animal fix(Animal a) {
Animal result = a;
if (a instanceof Cat || a instanceof Dog)
result = new FixedAnimal(a);
if (a.next != null) a.next = fix(a.next);
return result;
}
Animal a;
FixedAnimal(Animal a) {
super(0, null);
this.a = a;
}
public void drink(int n) {
// do stuff
if (a.next != null) a.next.drink(n);
}
}
类非第三类扩展了Cat{
猫(整数,下一个是动物){
超级(金额,下一个);
}
@凌驾
公共饮水机(国际北){
金额+=n;
如果(金额<0)金额=0;
如果(next!=null)next.drinkWater(n);
}
}
我想子类化对您的情况没有帮助
访客模式很好,但如果不修改动物
,它就无法工作。我有两个建议。事实上,我有三个:
class Animal {
int amount;
Animal next; // Then a constructor initializes these.
drinkWater(int n) { ... }
}
public void drinkWwater(int n) {
amount -= n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
class NonThirstyCat extends Cat {
Cat(int amount, Animal next) {
super(amount, next);
}
@Override
public void drinkWater(int n) {
amount += n;
if (amount < 0) amount = 0;
if (next != null) next.drinkWater(n);
}
}
class FixedAnimal extends Animal {
public static Animal fix(Animal a) {
Animal result = a;
if (a instanceof Cat || a instanceof Dog)
result = new FixedAnimal(a);
if (a.next != null) a.next = fix(a.next);
return result;
}
Animal a;
FixedAnimal(Animal a) {
super(0, null);
this.a = a;
}
public void drink(int n) {
// do stuff
if (a.next != null) a.next.drink(n);
}
}
当然,这对动物的用法做出了一些假设,但也许你已经明白了
我的建议是#1。或者更具体地说明你想要实现什么