简体   繁体   English

如果我只有对象,该如何重写类的行为?

[英]How to override the behavior of a class if I have only its object?

The question may be a stupid one to ask but, kindly help me on this. 这个问题可能是一个愚蠢的问题,但是请帮我解决这个问题。 I need to override the behavior of a class, but I will get only the object of it. 我需要重写类的行为,但是我只会得到它的对象。 Following is the code sample. 以下是代码示例。

I want to use the method Util.newChildComponent(String id) itself in all the places. 我想在所有地方都使用方法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.
            }
        }; */
}

Thanks in advance. 提前致谢。

Sounds like you are looking for a DynamicObjectAdaptorFactory . 听起来您正在寻找DynamicObjectAdaptorFactory

Here's a use of his excellent object. 这是他出色的对象的用途。

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

Prints: 打印:

Adapter invoke someBehaviour()
someBehavior
Adapter finished someBehaviour()

Have a look at Java's Dynamic Proxy. 看看Java的动态代理。 This should allow you to change the behavior at runtime by creating invocation handlers to handle a call to a method. 这应该允许您通过创建调用处理程序来处理对方法的调用,从而在运行时更改行为。 You can even then forward it to the original method if you want. 如果需要,您甚至可以将其转发到原始方法。

Declare a new class that extends the one with the method you want to change 声明一个新类,用您要更改的方法扩展该类

public class MyClass extends ChildComponent {

    @Override
    protected void childsBehavior()
    {
     .....
    }

}

Then in your code you can use casting, which is a feature we get to enjoy thanks to inheritance 然后在您的代码中可以使用强制转换,由于继承,我们可以享受这一功能

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

But then you would have to create the new object like so 但是然后您必须像这样创建新对象

MyClass pc = new MyClass("childId");

and do the configurations by hand that would have been done at Util . 并手动进行在Util完成的配置。 Unless you extend Util and crete a method that creates an object of MyClass and copy the configuration code there. 除非您扩展Util并创建一个创建MyClass对象并在其中复制配置代码的方法。

And now pc will have all the methods of ParentComponent and ChildComponent , but the childsBehavior will be what you declared. 现在pc将具有ParentComponentChildComponent所有方法,但是childsBehavior将是您声明的内容。

If you don't want to change the code that uses Util to instantiate the objects you need, you could rewrite the Util class with the behavior you need (ie instantiating a class that extends ChildComponent with the overridden method), just remember to put it in a package of the same name in your project (so that the import of its clients doesn't change). 如果您不想更改使用Util实例化所需对象的代码,则可以使用所需行为重写Util类(即,使用重写的方法实例化扩展ChildComponent的类),只需记住将其放入在项目中具有相同名称的程序包中(以便其客户端的导入不会更改)。 This way no other code should change at all. 这样,其他任何代码都不会更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM