首页 > 解决方案 > 无论如何在java中运行时更改对象类?

问题描述

我的代码看起来像这样。

class A {
 //constructor
}

class B extends A {
 //constructor

 public void someMethod() {
  System.out.println("In B");
 }
}

class C extends A {
 //constructor

 public void someMethod() {
  System.out.println("In C");
 }
}

public static void main(String args[]){
 Object obj = new obj();
 B[] classB = new B(){0,1,2,3,4};
 C[] classC = new C(){0,1,2,3,4};

 Scanner input = new Scanner(System.in);

 System.out.print("Enter class: ");

 String class = input.next();

 System.out.print("Enter index: ");

 int index = input.nextInt();

 if(class.equals("B") {

// 我想将 obj 的 Object 类型更改为 B 以便我可以访问 B 的方法

 obj = classB[index];

 } else if(class.equals("C")  {

// 我想将 obj 的 Object 类型更改为 C,以便我可以访问 C 的方法

  obj = classC[index];
 }

// 如果用户输入 B 类,下面的代码应该运行 B 类的方法

 obj.someMethod();
}

我已经按照永久铸造对象的方式寻找了一些东西,但这对我来说太复杂了。

标签: javaobject

解决方案


您似乎混淆了变量类型和它指向的对象的类型。

鉴于:

class Parent {}
class Child extends Parent {}

在:

Parent p = new Child();

您只有 1 个实例;它的类型是Child;就像任何有类型的东西一样Child,它也是类型的Parent,也是类型的Object

说“p 是 Parent 类型”令人困惑。所以不说了。

这有效: p 是 Parent 类型的变量;它引用了 Child 的一个实例。

并且应该澄清一两件事。

p 可以指向其他东西。你可以写:

Parent p;
p = null;
p = new Child();
p = new Parent();

并且编译器不会抱怨。在 p 的整个生命周期中,从它开始读取是非法的,然后不引用任何内容(null),然后引用 Child 的实例,最后引用 Parent 的实例。不,您不能突然将 p 变量“重新定义”为 Child 类型,即使它指向一个恰好是孩子的对象。这有点像试图重新定义一个有角的圆。

尽管如此,在:

Parent p = new Child();

p(变量)是 Parent 类型,但 p(在解析引用之后)是 Child。您可以将其视为一个:

Child c = (Child) p;

这是一个类型检查强制转换操作:此代码可以做以下两件事之一:

  1. 如果 p 变量碰巧没有引用任何内容(null)或 Child 的实例或其任何子类型,那么此代码绝对不会执行任何操作;它只是c = p,并且强制转换操作仅用于使编译器执行它(没有强制转换,编译器将拒绝编译它)。关键是,没有任何内容被转换,p 引用了一个对象,并且在此语句之后,c 引用了完全相同的对象。只是你现在可以用 c 变量做更多的事情。但这是同一个例子。
  2. 如果 p 变量恰好引用了其他任何东西,ClassCastException则抛出 a。

在任何情况下都不会转换任何东西,并且强制转换操作根本无法转换任何东西,除了原语(这是一个真正的枪和奶奶的情况:int x = (int) v;看起来非常相似,String y = (String) z;但是这两个片段做了完全不相关的事情,只是碰巧看起来相似。


推荐阅读