是否有可能存储代码,可以从另一个对象上运行的对象?

问题描述 投票:0回答:5

在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) {}
}

...

许多不同的类都用方法foo()。

ArrayList<Object> arr;
arr.add(blablai);
arr.add(blablaj);
arr.add(blablak);
...

阵列ARR包含作为这些类的实例许多对象。问题是,所有这些FOO()方法不具有相同的参数。如何调用这些方法用正确的参数?

arr.get(i).foo(?,?,?);

我的解决方案:

所有FOO方法有一个包含所有需要的参数作为对象的ArrayList一个参数PARAMS:

class BlaBlaX {
     void foo(ArrayList<Object> params) {}
}

然后,我添加了()包含类FOO foo中所需的变量的变量的名称。调用foo()之前,我打电话getFooParams():

class BlaBlaTwentyTwo extends Parent {

    ArrayList<Object> getFooParams() {

        ArrayList<String> p;
        p.add("i");
        p.add("banana");
        p.add("volkswagen");

        return p;
    }

    void foo(ArrayList<Object> params) {
        Int i = (int) params.get(0);
        Fruit banana = (Fruit) params.get(1);
        Car volkswagen = (Car) params.get(2);
    }
}

对象调用foo()方法中包含所有FOO所需的变量():

class ObjCallingFoo {
   int i;
   Fruit banana;
   car volkswagen;

   //see below for what is here to call foo()
}

import java.lang.reflect.Method;
import java.lang.reflect.Field;

p = arr.get(i).getFooParams();
int size = p.size();
ArrayList<Object> arrParams = new ArrayList<>();
for (int i = 0; i < size; i++) {
    String variableName = p.get(i);
    Field field = objCallingFoo.getClass.getField(variableName);
    arrParams.add(field);
}

我现在可以调用与正确的参数FOO:

arr.get(i).foo(arrParams);

我尚未对其进行测试。你对那个怎么想的?

是否有可能存储代码,可以从另一个对象上运行的对象?

要么

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

java
5个回答
1
投票

你需要包含具体的方法调用以及如何调用它的抽象。这就是谋略和指挥的设计模式可以做。


0
投票

在一般情况下,你可以使用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(?,?);

附:这不是很好的保持在一个列表中的所有这些对象。你的代码组织应确实重构!


0
投票

你可以有不同的构造和基本方法foo()的母公司。然后你就可以覆盖每个班级都在UND做一些与领域不同。但我认为这是一种选择,但也许你应该重构以另一种方式代码/抽象/继承。

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<Parent> parent;
parent.add(blablai);
parent.add(blablaj);
parent.add(blablak);
...

parent.foo()
parent.foo()
parent.foo()

0
投票

您可能需要使用一个接口:

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

它会变得更好。你可能有一个未实现的接口,但看起来相同的方法的类:

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.

你唯一需要的就是确定要使用的,当你调用的方法,在接口的签名。你必须告诉java中如何将参数映射(它不能推测)。


0
投票

最后,我可能会做,

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()是,有一个特定getParams()方法用参数的方法,需要设置为true ----------

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;
    ...
}

// -------在对象中的其他对象的FOO()方法被调用-----

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

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

我想我应该有10-15可能不同的参数,因此10-15如果setFu PARAMS语句()。

© www.soinside.com 2019 - 2024. All rights reserved.