【问题标题】:How to override the behavior of a class if I have only its object?如果我只有它的对象,如何覆盖类的行为?
【发布时间】:2015-07-17 12:05:21
【问题描述】:

这个问题可能是一个愚蠢的问题,但请帮助我。 我需要重写一个类的行为,但我只会得到它的对象。 以下是代码示例。

我想在所有地方都使用方法 Util.newChildComponent(String id) 本身。

class ParentComponent{
    public ParentComponent(String id){}
    protected void someBehavior(){}
}

class ChildComponent extends ParentComponent{
    public ChildComponent(String id){
        super(id);
    }
    protected void childsBehavior(){}
}

public class Util {
    public static ParentComponent newChildComponent(String id)
    {
        ParentComponent fc = new ChildComponent(id);
        // Initialize the object, and performs some common configuration.
        // Performs different operations on the generated child object.
        // The child class has many members apart from childsBehavior().
        return fc;
    }
}


// The above classes belongs to a jar, so I cannot edit the code.
// I need to use Util.newChildComponent(String id)
// But I need to override the behavior as mentioned below.
public void f1()
{
    // TODO: How to override childsBehavior() method using the object 
    // I have it in pc? Is it possible?
    // Util.newChildComponent(id) method decorates the ChildComponent
    // So I need to use the same object and just override childsBehavior() method only.
    ParentComponent pc = Util.newChildComponent("childId");

    // I need to achieve the result below
    /*
    ParentComponent pc = new ChildComponent(id){
            @Override
            protected void childsBehavior(){
                super.someBehavior();
                // Do the stuff here.
            }
        }; */
}

提前致谢。

【问题讨论】:

  • 所以你想覆盖childsBehavior,同时使用Util.newChildComponent创建实例?
  • 而ChildComponent是不能修改的?
  • @milez 所有三个 - ParentComponent、ChildComponent 和 Util

标签: java


【解决方案1】:

听起来您正在寻找DynamicObjectAdaptorFactory

这是他出色的对象的使用。

static class ParentComponent {

    protected void someBehavior() {
        System.out.println("ParentComponent someBehavior");
    }
}

static class ChildComponent extends ParentComponent {

    private ChildComponent(String id) {

    }

    protected void childsBehavior() {
        System.out.println("childsBehavior");
    }
}

public static class Util {

    public static ParentComponent newChildComponent(String id) {
        ParentComponent fc = new ChildComponent(id);
        // Initialize the object, and performs some common configuration.
        return fc;
    }
}

interface Parent {

    void someBehavior();

}

// The adaptor.
public static class Adapter implements Parent {

    final ParentComponent parent;

    private Adapter(ParentComponent pc) {
        this.parent = pc;
    }

    // Override the parent behaviour.
    public void someBehavior() {
        System.out.println("Adapter invoke someBehaviour()");
        parent.someBehavior();
        System.out.println("Adapter finished someBehaviour()");
    }

}

public void test() {
    ParentComponent pc = Util.newChildComponent("childId");
    Parent adapted = DynamicObjectAdapterFactory.adapt(pc, Parent.class, new Adapter(pc));
    adapted.someBehavior();
}

打印:

Adapter invoke someBehaviour()
someBehavior
Adapter finished someBehaviour()

【讨论】:

    【解决方案2】:

    看看 Java 的动态代理。这应该允许您通过创建调用处理程序来处理对方法的调用来更改运行时的行为。如果需要,您甚至可以将其转发到原始方法。

    【讨论】:

      【解决方案3】:

      声明一个新的类,用你想改变的方法扩展一个类

      public class MyClass extends ChildComponent {
      
          @Override
          protected void childsBehavior()
          {
           .....
          }
      
      }
      

      然后你可以在你的代码中使用强制转换,这是我们可以通过继承来享受的功能

      MyClass pc = (myClass) Util.newChildComponent("childId");

      但是你必须像这样创建新对象

      MyClass pc = new MyClass("childId");
      

      并手动进行在Util 进行的配置。除非您扩展 Util 并创建一个创建 MyClass 对象的方法并将配置代码复制到那里。

      现在pc 将拥有ParentComponentChildComponent 的所有方法,但childsBehavior 将是您声明的。

      【讨论】:

      • 虽然这可行,但我认为在这里编写包装器是一种更合适的方法。因为它应该是完全相同的类,除了1个函数的行为而不是父子关系。
      • 这将在运行时返回 ClassCastException,因为您正在尝试向下转换到不同的类..
      【解决方案4】:

      如果您不想更改使用Util 来实例化您需要的对象的代码,您可以使用您需要的行为重写Util 类(即实例化一个扩展ChildComponent 的类覆盖方法),只需记住将其放在项目中的同名包中(这样其客户端的导入不会改变)。这样一来,其他代码根本不应该改变。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-01
        • 2016-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多