我有类Class1的object1。我想将类Class1扩展为Class2,添加一个方法,然后创建Class2的object2,它将在所有方法中完全作为object1运行,除了现在它将有一个额外的方法。
Class1 object1 = new Class1();
Class2 object2 = new Class2(object1);
object2.oldMethod();
object2.newMethod();
object1.oldMethod应该与object2.oldMethod具有完全相同的行为。一种愚蠢的方法是编写一个脚本来生成新类,其中包含来自Class1的100多个继承方法:
public class Class2 {
private final Class1 object1;
public Class2(Class1 object1) {
this.object1 = object1;
}
public void oldMethod() {
object1.oldMethod();
}
...
public void newMethod() {
...
}
}
但我希望比那更聪明。怎么样?
修改: 我很抱歉没有说清楚。我从第三方获得了object1,这个对象带有一些内部状态 - 比如之前有一些setter在上面运行。我需要让object2具有相同的内部状态(这就是我在执行方法时的相同行为的意思)。我不能只扩展Class1,然后从Class2获取object2。 object2如何知道object1的状态?我不知道object1的内部状态(变量,数组,字段)。
EDIT2: 我想包装object1,但不想为保持相同的内容编写100个包装器方法。
答案 0 :(得分: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.
}
}
这种行为称为多态,在这种情况下,您将超类委托为通用的,只实现对您已经工作的类非常重要的内容。
答案 1 :(得分:1)
除非Object1
具有复制构造函数,否则不能使用继承,因为您从API接收Object1
的实例而不是自己构建它。
您可能想要的是Decorator Pattern。在这种模式中,装饰器由另一个对象组成,并通过装饰器向对象添加功能。
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
需要复制构造函数,以便您可以扩展它并从Object2
构建Object1
的实例。
答案 2 :(得分:0)
Class Class1{
public void methodx(){
}
}
class Class2 extends Class1{
public void extraMethod(){
}
}
继承是完美的案例。此处methodx
将继承与class1
和class2
中定义的完全相同的行为,您可以定义一个与class2
相关的新行为。
答案 3 :(得分: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
。
答案 4 :(得分: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();