问:为什么在Main中调用在PrimaryStudent中定义的getGrade()会报错呢??
Topic source自己研究了一下,好像是因为Main中定义的ps实际上是一个Student的实例(向上转型)
Student ps = new PrimaryStudent("小军", 9, 100, 5);
因此在Main中直接使用
System.out.println(ps.getGrade());
编译无法通过——Student中并没有getGrade()方法,需要向下转型才可以通过编译:
System.out.println(((PrimaryStudent) ps).getGrade());
但为什么这里向下转型是OK的呢?明明在子类PrimaryStudent中新增了grade相关字段和方法,为何Student ps可以向下转型为PrimaryStudent?
如果是因为Student ps定义时是new了一个 PrimaryStudent的对象,那么为什么我们又要说ps是一个Student实例呢?
......有点晕QAQ
再看了一遍廖老师的教程......好像弄明白了 /(ㄒoㄒ)/~~
Main中定义了一个Student实例ps(实际上是一个PrimaryStudent的实例,向上转型成一个Student实例),ps拥有Student的全部属性,但直接使用时并无PrimaryStudent中比Student多的部分属性。因此,在Main中调用ps.getGrade()时会报错
System.out.println(ps.getGrade()); // Exception: The method getGrade() is undefined for the type Student
但由于ps实际上是一个PrimaryStudent的实例,我们可以将其向下转型为PrimaryStudent类型来使用getGrade() 方法:
System.out.println(((PrimaryStudent) ps).getGrade()); //OK
完整代码如下:
//Main.java
public class Main {
public static void main(String[] args) {
Person p = new Person("小明", 12);
Student s = new Student("小红", 20, 99);
// TODO: 定义PrimaryStudent,从Student继承,新增grade字段:
Student ps = new PrimaryStudent("小军", 9, 100, 5);
System.out.println(ps.getScore());
//为什么在Main中调用在PrimaryStudent中定义的getGrade()会报错呢??
System.out.println(ps.getGrade());
}
}
//Person.java
public class Person {
protected String name;
protected int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//Student.java
public class Student extends Person {
protected int score;
public Student(String name, int age, int score) {
super(name, age);
this.score = score;
}
public int getScore() {
return score;
}
}
//PrimaryStudent.java
public class PrimaryStudent extends Student{
protected int grade;
public PrimaryStudent(String name, int age, int score, int grade) {
super(name, age, score);
this.grade = grade;
}
public int getGrade() {
return grade;
}
}
上面的Main.java忘记修改了QAQ:
//Main.java
public class Main {
public static void main(String[] args) {
Person p = new Person("小明", 12);
Student s = new Student("小红", 20, 99);
// TODO: 定义PrimaryStudent,从Student继承,新增grade字段:
Student ps = new PrimaryStudent("小军", 9, 100, 5);
System.out.println(ps.getScore());
System.out.println(((PrimaryStudent)ps).getGrade());
}
}
太厉害了,非常感谢题主,这么好的答案为什么要翻到最后一个呢
因为自己也是困扰在了这里,看完题主解答才发现廖老师的代码已经包含了一个向上转型,可能是廖老师故意设计的吧
所以如果更改一下廖老师的代码,不使用转型就可以直接输出方法getGrade(),代码如下
Person p = new Person("小明", 12);
Student s = new Student("小红", 20, 99);
PrimaryStudent ps = new PrimaryStudent("小军", 9, 100, 5);//Student更改为PrimaryStudent,即可不通过转型打印结果
System.out.println(p.name + " " + p.age);
System.out.println(s.name + " " + s.age + " " + s.score);
System.out.println(ps.getgrade());
再提一嘴,由于学到现在,我们已经在不同的代码中多次使用过Person这个类
如果类名重复,即使是在不同的java文件,也会导致Eclipse报错:
The type Person is already defined
一个简单粗暴的解决办法是更改当前类的类名避免重复,例如把person更改成person2或person+文件名等
- 1
YANGZY1202