2

I have object1 of class Class1. I would like to extend class Class1 to Class2 adding one method and then create object2 of Class2 that would behave in all methods exactly as object1, except that now it would have an additional method.

Class1 object1 = new Class1();
Class2 object2 = new Class2(object1);
object2.oldMethod();
object2.newMethod();

object1.oldMethod should have exactly the same behaviour as object2.oldMethod. A stupid way would be to write a script that would generate the new class with all more than 100 inherited methods from Class1:

public class Class2 {
    private final Class1 object1;
    public Class2(Class1 object1) {
         this.object1 = object1;
    }

    public void oldMethod() {
        object1.oldMethod();
    }
    ...
    public void newMethod() {
    ...
    }
}

But I would like to be smarter than that. How?

EDIT: I am sorry for not making it more explicit. I get object1 from some 3rd party, this object comes with some internal state - say some setters were ran on it before. I need to get object2 with the same internal state (this is what I mean by the same behaviour when a method is executed). I cannot just extend Class1, then get object2 from Class2. How will object2 know about the state of object1? I do not know the internal state (variables, arrays, fields) of the object1.

EDIT2: I want to wrap object1, but do not want to have to write 100 wrapper methods for what stays the same.

4

5 回答 5

1
public class Class2 extends Class1{
    //signature of old method, with the same parameters (if exists).
    public void oldMethod(){
        super.oldMethod(); //call the Class1 method
        //do what you have to do for this class down here.
    }
}

这种行为称为多态性,您将通用的东西委托给超类,并且只实现对您已经在工作的类真正重要的东西。

于 2013-06-17T21:03:57.197 回答
1

Object1除非有复制构造函数,否则不能使用继承,因为您Object1从 API 接收实例而不是自己构造它。

您可能想要的是装饰器模式。在这种模式中,装饰器由另一个对象组成,并通过装饰器向对象添加功能。

class Object1 {
    //...stuff...
}

class Decorator {
    private Object1 object;
    public Decorator(Object1 obj) {
        object = obj;
    }
    public Object1 getComposite() {
        return object;
    }
    public void extra() {
        //Do stuff with object1 and any other state specific to the decorator
    }
}

Object1这也可以作为继承来完成,但只有在您真的尝试扩展接口而不是简单地增强接口时才有意义。

作为单独的说明,我认为实际上尝试扩展第三方类是不明智的,除非文档明确说明该类是为扩展而设计的。将来的版本可能会将类标记为,final或者构造该类可能很复杂或具有包/私有访问权限。此外,根据您的编辑,它甚至可能是不可能的。Object1将需要一个复制构造函数,以允许您扩展它并Object2Object1.

于 2013-06-17T21:15:19.913 回答
0
Class Class1{
    public void methodx(){

    }
}

class Class2 extends Class1{
    public void extraMethod(){

    }

}

继承是完美的案例。这里methodx将继承与定义完全相同的行为,class1并且class2您可以定义一个新的行为,这将是特定于class2.

于 2013-06-17T20:45:58.413 回答
0

我觉得你应该去继承。详细说明 zerocool 的注释,您可以声明 Class2 扩展 Class1。

Class Class1{
    public void methodx(){

    }
}

class Class2 extends Class1{
    public void extraMethod(){

    }

}

然后你仍然可以拥有一个

Class1 obj = new Class2();

这将为您提供带有 Class1 引用的 Class2 obj。

如果你真的想要一个从 Class2 到 Class1 的数据转换器,你可以编写一个 Class2 的重载构造函数,它接受一个 Class1 对象,如下所示:

public Class2 (Class1 obj)
{
    this.setName(obj.getName()); //Assuming name attribute
    ... // and other setter methods
}

编辑:

作为包装器,您可以执行以下操作:

public class Class2
{
    private Class1 obj;

    public Class1 getClass1Obj()
    {
        return obj;
    }

    public void newMethod()
    {
        // your method here
    }
}

旧方法可以在返回的对象上调用,也可以getClass1Obj()直接在 的newMethod()对象上调用Class2

于 2013-06-17T21:00:07.610 回答
0

您可以使用AspectJ和 ajc 编译器尝试以下操作。

// Class1Extensions.aj
aspect Class1Extensions {
    // An inter-type declaration
    public void Class1.newMethod() {
       //...
    }
}

您将需要编译,ajc以便代码调用object1.newMethod()不会反叛。您还可以newMethod为该方面创建一个接口并将其放入:

declare parents Class1+ implements Class1NewMethods;

然后,你可以写

Class1NewMethods object2 = (Class1NewMethods) object1;
object2.newMethod();
于 2013-06-18T13:53:28.693 回答