Java抽象类初始化差异:AP计算机科学考试技术问询
嘿,这可是AP计算机科学里多态部分的经典考点,我来给你掰扯清楚这两行代码的区别:
首先得明确一个关键前提:不管是bob还是jane,它们实际指向的对象都是Carpenter类的实例——因为右边的初始化语句都是new Carpenter()。真正的差异体现在左边的引用变量类型上,这直接决定了你能通过这个变量做什么操作。
1. 可调用的方法范围不同
对于
ConstructionWorker bob = new Carpenter();:bob的引用类型是父类ConstructionWorker,所以你只能调用ConstructionWorker类中定义(包括子类重写)的方法。如果Carpenter有自己独有的方法(比如buildWoodenFrame()),直接通过bob调用会触发编译错误,因为父类里没有这个方法的定义。
举个实际例子:// 假设Carpenter新增了这个专属方法 public void buildWoodenFrame() { System.out.println("搭建木质框架"); } bob.buildWoodenFrame(); // 编译错误!ConstructionWorker类中无此方法要是想调用这个专属方法,你得先把
bob强制转换为Carpenter类型:((Carpenter) bob).buildWoodenFrame(); // 这样就能正常执行了对于
Carpenter jane = new Carpenter();:jane的引用类型就是Carpenter本身,所以你可以调用所有Carpenter的方法——包括从ConstructionWorker继承来的,以及Carpenter自己新增的方法,不需要任何类型转换。jane.buildWoodenFrame(); // 完全合法,直接执行
2. 变量的赋值灵活性不同
bob是ConstructionWorker类型,所以它可以被赋值为任何ConstructionWorker子类的实例。比如如果有另一个子类Electrician,你可以直接写:bob = new Electrician(); // 编译通过,因为Electrician也是ConstructionWorker的子类- 而
jane是Carpenter类型,它只能被赋值为Carpenter或者它的子类实例,要是尝试把Electrician赋值给jane,会直接触发编译报错。
3. 多态的核心体现(AP考试重点!)
如果ConstructionWorker有一个被Carpenter重写的方法(比如抽象方法work()),那么不管是bob.work()还是jane.work(),最终执行的都是Carpenter里的重写版本——这就是多态的核心规则:实际执行的方法由对象的实际类型决定,而不是引用类型。
比如:
// ConstructionWorker中的抽象方法 public abstract void work(); // Carpenter中的重写实现 @Override public void work() { System.out.println("我是木匠,正在处理木工活"); } bob.work(); // 输出:我是木匠,正在处理木工活 jane.work(); // 输出完全相同的内容
总结一下:这两种声明的本质是引用类型的差异,它限制了你能通过变量访问的成员,但不会改变对象本身的类型和行为——多态正是基于这种机制实现的,这也是AP计算机科学考试里经常考察的核心知识点哦!
内容的提问来源于stack exchange,提问作者Jim

