简体   繁体   中英

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.

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 .

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

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 . Unless you extend Util and crete a method that creates an object of MyClass and copy the configuration code there.

And now pc will have all the methods of ParentComponent and ChildComponent , but the childsBehavior will be what you declared.

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). This way no other code should change at all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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