我目前正在学习一本AP CS A考试的书,特别是Barron的考试准备书。
本书的一部分引用了两个类Student
和GradStudent
,其中GradStudent
extends
Student
。
GradStudent
的方法为getId()
,而Student
则没有。
如果我要运行以下代码:
Student s = new GradStudent()
s.getId()
这本书告诉我,我会收到错误。为什么是这样?由于我将其初始化为GradStudent
,因此s
无法访问方法getId()
吗?
基本上,如果我将变量声明为超类,并将其初始化为子类,会发生什么?
换句话说,以下示例中的s
和g
有何区别:
Student s = new GradStudent()
GradStudent g = new GradStudent()
编辑:
我现在明白s
只能访问Student
类中的方法。
那么如果我执行以下操作会发生什么:
Student s = (new GradStudent().setId(1) )
id
字段会怎样? (假设它仅存在于GradStudent
类中)如果我再次将s
投放到GradStudent
,它是否可以访问相同的id
?
答案 0 :(得分:10)
您收到错误,因为s
宣布为Student
类型。将实例化作为new GradStudent()
并不重要,编译器只知道声明的类型为s
。所以基本上你只能使用s
,就像它是Student
一样(你只能使用Student
类定义的方法)。
如果您确实需要使用.getId()
,则有两种选择。您可以将s
声明为GradStudent
:
GradStudent s = new GradStudent();
System.out.println(s.getId());
或者,您可以将s
投射到GradStudent
:
Student s = new GradStudent();
System.out.println(((GradStudent) s).getId());
答案 1 :(得分:3)
变量
Student s
被声明为Student
,而不是GradStudent
。您为GradStudent
变量分配了Student
实例 - 这不会更改所述变量的类型。
您可以执行以下操作来解决编译时错误:
Student s = new GradStudent()
((GradStudent)s).getId()
但这被认为是代码味道。
答案 2 :(得分:2)
正是因为GradStudent
的方法为getId()
而Student
没有。
您的GradStudent
继承了Student
方法,但Student
类只有自己的OWN方法。
如果GradStudent
实现Student
getId()
答案 3 :(得分:2)
我希望你能得到上述人的回答。只想添加一些要点。
调用方法s.getId()
最终会给你一个错误,因为s是一种Student类型,并且在编译时编译器会检查Student中是否存在getId()
方法,如果它找不到它,会给你一个错误。
但是s指向一个子类型的对象,它是GradStudent,它将在运行时解析,编译器不知道它。所以为了满足编译器,你必须像这样下载
((GradStudent)s).getId()