Java 是否可以将代码存储在可以从另一个对象运行的对象中?

Java 是否可以将代码存储在可以从另一个对象运行的对象中?,java,Java,在爪哇 class BlaBlaThirty extends Parent { void foo(String s, int i) {} } class BlaBlaTwentyNine extends Parent { void foo(int i, Bla a, This t, Other o) {} } class BlaBlaFive extends Parent { void foo(Bla a, Other o) {} } ... 许多不同的类都有一个

在爪哇

class BlaBlaThirty extends Parent {
    void foo(String s, int i) {}
}

class BlaBlaTwentyNine extends Parent {
    void foo(int i, Bla a, This t, Other o) {}
}

class BlaBlaFive extends Parent {
    void foo(Bla a, Other o) {}
}

...
许多不同的类都有一个foo()方法

我的解决方案:

所有foo方法都有一个ArrayList params参数,其中包含作为对象的所有必需参数:

class BlaBlaX {
     void foo(ArrayList<Object> params) {}
}
我还没有测试。 你觉得怎么样

是否可以将代码存储在可以从另一个对象运行的对象中


如果我们不知道在调用对象时作为参数传递给方法的具体成员变量是什么,如何使用另一个对象的参数调用方法?

通常,您可以使用
instanceof

Object parent = obj.get(i);

if(parent instanceof BlaBlaThirty)
    ((BlaBlaThirty)parent).foo(?,?);
else if(parent instanceof BlaBlaTwentyNine)
    ((BlaBlaTwentyNine)parent).foo(?,?,?);
else if(parent instanceof BlaBlaFive )
    ((BlaBlaFive )parent).foo(?,?);

p.S.将所有这些对象放在一个列表中是不好的。您的代码组织确实应该重构

在父级中可以有不同的构造函数和基本方法foo()。 然后,您可以在每个类中重写它,并对字段执行不同的操作。 但我认为这是一种选择,但也许你应该用另一种方式重构你的代码/抽象/继承

class Parent {
   void foo(){}
}

class BlaBlaThirty extends Parent {
//Contructor with String s, int i

void foo() {
   //Do something here with fields  String s, int i
}

class BlaBlaTwentyNine extends Parent {
//Contructor with int i, Bla a, This t, Other o

void foo() {
  //Do something here with fields int i, Bla a, This t, Other o
}

class BlaBlaFive extends Parent {
//Constructor Bla a, Other o
void foo() {
  //Do something here with fields Bla a, Other o
}

许多不同的类都有一个foo()方法

ArrayList父项;
添加(blablai);
添加(blablaj);
parent.add(blablak);
...
parent.foo()
parent.foo()
parent.foo()

您可能需要使用以下界面:

public interface Blainterface{
   public void foo();
}

public class BlaBlaTwentyNine extends Parent implements Blainterface {
     public void foo() {}
}
....
ArrayList<Blainterface> obj;
obj.add(blablai);
obj.add(blablaj);
obj.add(blablak);

//now you can acces it like 

obj.get(2).foo();
公共接口Blainterface{
公开无效foo();
}
公共类BlaBlaTwentyNine扩展父接口{
公共void foo(){}
}
....
ArrayList obj;
对象添加(blablai);
对象添加(blablaj);
对象添加(blablak);
//现在,你可以像这样访问它
obj.get(2.foo();
它变得更好了。您可能有一个类没有实现接口,但其方法看起来相同:

public interface Blainterface{
    public void foo();
}

public class Blubclass{
    public void bar(){ //note its bar here and not foo()!!!
      //do something cool!  
    }
}
//...

ArrayList<Blainterface> obj;
obj.add(blablai);
obj.add(blablaj);
obj.add(blablak);
Blubclass blub = new Blubclass(); //note that blub has no foo() method.
obj.add(blub::bar);

//And that call will work too:
obj.get(3).foo(); //this will call bar() in the Blubclass.
公共接口Blainterface{
公开无效foo();
}
公共类Blubclass{
public void bar(){//注意这里的条,而不是foo()!!!
//做点酷的事!
}
}
//...
ArrayList obj;
对象添加(blablai);
对象添加(blablaj);
对象添加(blablak);
Blubclass blub=新Blubclass()//请注意,blub没有foo()方法。
对象添加(blub::bar);
//这一呼吁也会奏效:
obj.get(3.foo()//这将调用Blubclass中的bar()。
现在,进一步介绍一些具有不同参数的内容:

public interface Blainterface{
    public void foo();
}

public class Bazclass{
    public void baz(Sting name){ //note its baz here and not foo() and it has a parameter!!!
      //do something cool!  
    }
}
//...

ArrayList<Blainterface> obj;
obj.add(blablai);
obj.add(blablaj);
obj.add(blablak);
Bazclass baz = new Bazclass(); //note that baz has no foo() method and a parameter.
obj.add(()->baz.baz("name"));//mapping of parameters

//And that call will work too:
obj.get(3).foo(); //this will call baz("name") in the Bazclass. Even though we use a different method name and parameters for the call.
公共接口Blainterface{
公开无效foo();
}
公共课{
public void baz(Sting name){//注意这里的baz,而不是foo(),它有一个参数!!!
//做点酷的事!
}
}
//...
ArrayList obj;
对象添加(blablai);
对象添加(blablaj);
对象添加(blablak);
Bazclass baz=新的Bazclass()//请注意,baz没有foo()方法和参数。
对象添加(()->baz.baz(“名称”)//参数映射
//这一呼吁也会奏效:
obj.get(3.foo()//这将在baz类中调用baz(“name”)。即使我们为调用使用了不同的方法名和参数。
您只需要在接口中定义调用方法时要使用的签名。
您必须告诉java如何映射参数(它无法猜测)。

您需要一个抽象,包括调用的特定方法和如何调用它。这就是战略和指挥设计模式可以做的。

最后,我可以做什么

class FooParamsNeeded {
    public boolean blaBlaI;
    public boolean blaBlaJ;
    public boolean i;
    public boolean blaBlaK;
    public boolean banana;
    public boolean blaBlaL;
    public boolean volkswagen;
    public boolean blaBlaM;
    ...
}
//------------在foo()所在的对象中,有一个特殊的getFooParams()方法,其参数需要设置为true----------

class FooParams {
    public BlaBlaI blaBlaI;
    public BlaBlaJ blaBlaJ;
    public int i;
    public BlaBlaK blaBlaK;
    public Fruit banana;
    public BlaBlaL blaBlaL;
    public Car volkswagen;
    public BlaBlaM blaBlaM;
    ...
}
//--------------------

class FooParams {
    public BlaBlaI blaBlaI;
    public BlaBlaJ blaBlaJ;
    public int i;
    public BlaBlaK blaBlaK;
    public Fruit banana;
    public BlaBlaL blaBlaL;
    public Car volkswagen;
    public BlaBlaM blaBlaM;
    ...
}
//-------在调用其他对象的foo()方法的对象中-----

//-------------------------------------

class FooParams {
    public BlaBlaI blaBlaI;
    public BlaBlaJ blaBlaJ;
    public int i;
    public BlaBlaK blaBlaK;
    public Fruit banana;
    public BlaBlaL blaBlaL;
    public Car volkswagen;
    public BlaBlaM blaBlaM;
    ...
}

我想我应该有10-15个可能不同的参数,因此setFooParams()中的10-15 if语句。

好吧,因为它们都继承自同一个基类(父类),这意味着它们具有相似的功能。这并不意味着您应该将它们都放在同一个ArrayList中。编程中的每个问题都可以通过另一层抽象来解决。我的意见是你应该改变这种结构。你的解决方案假设有数百个if instanceof else if instanceof else if instanceof else if instanceof。。。如果ArrayList obj包含数百个对象。如果可能的话,我会考虑重构。这是你的!事实上,我会完全删除您的代码并正确重写。如果对象不在数组中,如何存储对象?这是一个游戏,当玩家玩一张卡类型的卡时,例如CardPikahu扩展卡,CardCharizar扩展卡,我在ArrayList cardsInHand中添加一张卡,做cardsInHand.add(cardPikachu);cardsInHand代表玩家手中的所有牌。所有卡片都有相同的方法,如attack(),但attack()的参数可能因卡片而异。不知道如何重构。如果参数是同一类型的(意思是:你可以使用数组),你也可以使用一个变量参数列表,比如:void foo(String…params){},然后用你自己创建的类型规范替换一堆“instanceof”if's和相同数量的“if's”,这不会有很大的区别。但对于后一种情况,枚举可能是一种选择。
public interface Blainterface{
    public void foo();
}

public class Blubclass{
    public void bar(){ //note its bar here and not foo()!!!
      //do something cool!  
    }
}
//...

ArrayList<Blainterface> obj;
obj.add(blablai);
obj.add(blablaj);
obj.add(blablak);
Blubclass blub = new Blubclass(); //note that blub has no foo() method.
obj.add(blub::bar);

//And that call will work too:
obj.get(3).foo(); //this will call bar() in the Blubclass.
public interface Blainterface{
    public void foo();
}

public class Bazclass{
    public void baz(Sting name){ //note its baz here and not foo() and it has a parameter!!!
      //do something cool!  
    }
}
//...

ArrayList<Blainterface> obj;
obj.add(blablai);
obj.add(blablaj);
obj.add(blablak);
Bazclass baz = new Bazclass(); //note that baz has no foo() method and a parameter.
obj.add(()->baz.baz("name"));//mapping of parameters

//And that call will work too:
obj.get(3).foo(); //this will call baz("name") in the Bazclass. Even though we use a different method name and parameters for the call.
class FooParamsNeeded {
    public boolean blaBlaI;
    public boolean blaBlaJ;
    public boolean i;
    public boolean blaBlaK;
    public boolean banana;
    public boolean blaBlaL;
    public boolean volkswagen;
    public boolean blaBlaM;
    ...
}
FooParamsNeeded getFooParams() {
    FooParamsNeeded fpn = new FooParamsNeeded();
    fpn.i = true;
    fpn.banana = true;
    fpn.volkswagen = true;
    return fpn;
}
class FooParams {
    public BlaBlaI blaBlaI;
    public BlaBlaJ blaBlaJ;
    public int i;
    public BlaBlaK blaBlaK;
    public Fruit banana;
    public BlaBlaL blaBlaL;
    public Car volkswagen;
    public BlaBlaM blaBlaM;
    ...
}
FooParams setFooParams(FooParamsNeeded fpn) {
    FooParams fp = new FooParams();
    if (fpn.blaBlaI)
        fp.blaBlaI = blaBlaI;
    if (fpn.blaBlaJ)
        fp.blaBlaJ = blaBlaJ;
    if (fpn.i)
        fp.i = i;
    if (fpn.blaBlaK)
        fp.blaBlaK = blaBlaK;
    if (fpn.banana)
        fp.banana = banana;
    if (fpn.blaBlaL)
        fp.blaBlaL = blaBlaL;
    if (fpn.volkswagen)
        fp.volkswagen = volkswagen;
    if (fpn.blaBlaM)
        fp.blaBlaM = blaBlaM;
    ...

    return fp;
}

FooParamsNeeded fpn = arr.get(i).getFooParams();
FooParams fp = setFooParams(fpn);
arr.get(i).foo(fp);