Discuss / Java / 问:为什么在Main中调用在PrimaryStudent中定义的getGrade()会报错呢??

问:为什么在Main中调用在PrimaryStudent中定义的getGrade()会报错呢??

Topic source

YANGZY1202

#1 Created at ... [Delete] [Delete and Lock User]
//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
...
//Student.java 
...
//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;
	}

}

YANGZY1202

#2 Created at ... [Delete] [Delete and Lock User]

自己研究了一下,好像是因为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

YANGZY1202

#3 Created at ... [Delete] [Delete and Lock User]

再看了一遍廖老师的教程......好像弄明白了 /(ㄒ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

YANGZY1202

#4 Created at ... [Delete] [Delete and Lock User]

完整代码如下:

//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;
	}

}

YANGZY1202

#5 Created at ... [Delete] [Delete and Lock User]

上面的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());
	}

}



  • 1

Reply