java - 无论如何在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();
}
我已经按照永久铸造对象的方式寻找了一些东西,但这对我来说太复杂了。
解决方案
您似乎混淆了变量类型和它指向的对象的类型。
鉴于:
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;
这是一个类型检查强制转换操作:此代码可以做以下两件事之一:
- 如果 p 变量碰巧没有引用任何内容(null)或 Child 的实例或其任何子类型,那么此代码绝对不会执行任何操作;它只是
c = p
,并且强制转换操作仅用于使编译器执行它(没有强制转换,编译器将拒绝编译它)。关键是,没有任何内容被转换,p 引用了一个对象,并且在此语句之后,c 引用了完全相同的对象。只是你现在可以用 c 变量做更多的事情。但这是同一个例子。 - 如果 p 变量恰好引用了其他任何东西,
ClassCastException
则抛出 a。
在任何情况下都不会转换任何东西,并且强制转换操作根本无法转换任何东西,除了原语(这是一个真正的枪和奶奶的情况:int x = (int) v;
看起来非常相似,String y = (String) z;
但是这两个片段做了完全不相关的事情,只是碰巧看起来相似。
推荐阅读
- python - 将 kaggle 安装在错误的目录中
- c# - 通过脚本将多种材质分配给游戏对象?
- javascript - 如何在 php 中添加图像验证,如大小和重量
- excel - 如何使用powershell确保以匹配日期复制最新的两个文件?
- azure-cosmosdb - 如何使用连接在 CosmosDB 中进行 select * 查询?
- leaflet - How to use a unique PNG for multiple tile?
- c# - 从一个模型获取名称到另一个模型
- omnet++ - 如何使用 3rd 方 dll (libaudiofile) 编译 INET
- php - created_at 列中的时间不正确 - Laravel 5.4
- amazon-web-services - 在 EC2 用户数据中运行 tmux