【问题标题】:Can a custom class know the name of the object that called it?自定义类可以知道调用它的对象的名称吗?
【发布时间】:2013-05-19 18:24:42
【问题描述】:

到底有没有,当通过一个对象(实例)调用一个方法的时候,让那个方法知道是哪个实例(对象)调用了它?

这是我的意思的示例(伪代码):

伪代码示例

public class CustomClass{


public void myMethod(){


    if (calling method is object1){

    //Do something here

    }

        else {

        //Do something else

        }


        }//End of method


}//End of class

然后在另一个班级:

public SomeOtherClass{

CustomClass = object1;

public void someOtherMethod(){

object1 = new CustomClass();

object1.myMethod();    //This will call the 1st condition as the calling object is object1, if it were some other object name, it would call the 2nd condition.

    }//End of method

}//End of class

可能的解决方法

我发现这样做的唯一方法是让该方法接受另一个参数,比如一个“int”,然后检查该 int 的值并执行与它相关的“if else”语句的任何部分(如果肯定使用“int”值,则为“switch”语句)但这似乎是一种非常混乱的方式。

【问题讨论】:

  • 你为什么要这个?你想达到什么目的?
  • 变量“名称”真的没有意义。请注意,多个具有不同名称的变量都可以引用同一个对象。重要的是对象references。我也同意@Heuster 的观点,您提出此请求的动机可能会影响最终可能是最佳答案。
  • @Heuster,它用于碰撞检测例程,我有 1 个平台,由 3 个瓦片组成,一个左瓦、一个中间瓦和一个右瓦,碰撞响应将根据角色的瓦片而有所不同命中,因此我需要碰撞检测例程来知道它正在处理哪种类型的平台图块。我正在创建 3 个不同的对象(CDLeft、CDMiddle 和 CDRight,并从我的逻辑例程中调用它们,但它不知道如何区分。)
  • 那么也许它应该是 Game 对象,即持有瓷砖并运行游戏的对象,它识别哪些瓷砖发生了碰撞,然后在两个瓷砖上调用碰撞方法,传递给这些方法什么类型的瓷砖与之碰撞。

标签: java class object instance


【解决方案1】:

你需要的是Strategy Pattern

public abstract class CustomClass {
    public abstract void MyMethod();
}

public class Impl1 extends CustomClass {
    @Override
    public void MyMethod() {
        // Do something
    }
}

public class Impl2 extends CustomClass {
    @Override
    public void MyMethod() {
        // Do something else
    }
}

这样使用

public static void main(String[] args) {
    CustomClass myObject = new Impl1();
    // or CustomClass myObject = new Impl2();
}


正如您的评论所说,您真正需要的可能是Template method Pattern
public abstract class CustomClass {
    public void myMethod(){ // this is the template method
        // The common things
        theDifferentThings();
    }

    public abstract void theDifferentThings();
}

public class Impl1 extends CustomClass {
    @Override
    public void theDifferentThings() {
        // Do something
    }
}

public class Impl2 extends CustomClass {

    @Override
    public void theDifferentThings() {
        // Do something else
    }
}

【讨论】:

  • 谢谢@Mohayemin,这是一个有趣的方法,我能看到的唯一问题是我的自定义类中的方法非常大,我想用这种方式我必须有 3本质上相同的不同方法,只有几行不同的代码。如果我对此有误,请纠正我?
  • @Zippy:任何常见的代码都可以成为超类实现的一部分,如果需要,子类可以在方法覆盖中调用的代码。
  • 好吧,如果是这样的话,你需要另一种接近策略的设计模式,叫做模板模式,等一下,我可以这样编辑代码。
【解决方案2】:

您可以通过调用getClass().getName() 知道当前的名称。但是你不知道对象的名称,而且这没有任何意义:

MyClass myObject1 = new MyClass();
MyClass myObject2 = myObject1;

myObject1.foo();
myObject2.foo();

您是否希望 foo() 知道它是使用 myObject1myObject1 调用的?但是两个引用都指向同一个对象!

好的,有非常复杂的方法可以知道这一点。您可以使用 javassist、ASM、CGLib 等流行库之一使用字节码工程,并将有关“对象名称”的缺失信息注入字节码,然后读取此信息。但是恕我直言,这不是您所需要的。

【讨论】:

    【解决方案3】:

    您可以在CustomClass 中定义一个新属性,该属性将存储实例的标识符。如果CustomClass 的实例很少,那么您可以使用枚举类型。

    替换:

    object1 = new CustomClass();
    

    与:

    object1 = new CustomClass(1);
    

    向 CustomClass 添加一个新的构造函数和一个属性:

    private int id;
    public CustomClass(int id) {
        this.id = id;
    }
    

    然后你可以替换:

    if (calling method is object1){
    

    与:

    if (id == 1){
    

    但是,请记住,这是一个糟糕的设计。 根据调用此方法的实例,您不应该有不同的逻辑条件。您应该为此目的使用多态性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2012-09-03
      • 2017-05-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多