如何在不创建新对象的情况下更改对象的类?

时间:2014-04-24 15:25:42

标签: java

假设我有一个类Foo,以及两个类Foo1和Foo2扩展Foo。

假设我有一个Foo f,结果是Foo1,我想在不使用构造函数的情况下更改它。如果只是改变f的字段,我可以手动完成:

f.field1= ..
f.field2= ..

但如果我想将其改成Foo2,我该怎么办?

N.B:关键是我想做那样的事情:

Foo f=new Foo1( ...);
Foo g=f;
g=new Foo2(...);

并且当g发生变化时会改变f,但显然这不起作用。

4 个答案:

答案 0 :(得分:1)

请注意,Java为static typed programming languagestrong typed,因此除非Foo2Foo的子类,否则它无法正常工作。但即使这样做,您只需更改变量的对象引用的类型(并启用多态),而不是变量的类型。

答案 1 :(得分:1)

你可能会围绕这些线做点什么。注意:此代码是伪代码。

abstract class Common{
...
}

class Foo{
  private Common currentReference;

  public Foo(...){
    currentReference = new Foo1();
  }

  public Foo changeReferenceToClass(Class clazz){
    ...
    currentReference = clazz.newInstance();
    ...
    return this;
  }

  public <T extends Common> T getReference()
  {
    return (T) currentReference;
  }
}

class Foo1 extends Common{
...
}

class Foo2 extends Common{
...
}

Foo f=new Foo( ... );
Foo g=f;
g=g.changeReferenceToClass(Foo2.class);

这是做什么的:

  • 创建一个包含对具有common接口的对象的引用的类(在示例中为Common抽象类。
  • 在构造时将实例化的默认值实例化(在示例中为Foo1)。
  • changeget参考提供方法。
  • 当您在一个地方将参考更改为Foo2时,您可以在所有地方访问它

在示例中,当您更改g以保留对Foo2的引用时,f也会引用Foo2

答案 2 :(得分:0)

您无法在Java中执行此操作,因为您声明的类型是您所限定的类型。这就是静态类型的工作方式。那说你可以这样做:

Foo g = new Foo2();
((Foo2)g).gInstanceMethod();

答案 3 :(得分:0)

其他人已经解释了为什么你不能改变现有对象的类。但即使你可以,由于Java的引用工作方式,你正在尝试做的事情也不会起作用。

 Foo f=new Foo1( ...);

这一行在堆上分配一个新对象,调用Foo1构造函数来初始化它,并在变量f中将引用存储到该对象。

 Foo g=f;

此行复制引用的(即将地址而不是被引用的对象复制到新变量g

 g=new Foo2(...);

此行在堆上分配一个新对象,调用Foo2构造函数对其进行初始化,并将引用存储到新对象中g,覆盖引用以前存储在那里。 g之前引用的对象从不受此操作的影响。