书上讲到protected访问修饰符时,一般会这样描述:
对本包和所有子类可见。
真的是所有子类都可见吗?
下面做一个实验
父类Person
package com.example.demo.person;
public class Person {
protected Integer age;
protected String name;
public Person(String name, Integer age){
this.name = name;
this.age = age;
}
protected Integer getAge() {
return age;
}
protected String getName() {
return name;
}
}
第一个子类Student
package com.example.demo.Student;
import com.example.demo.person.Person;
public class Student extends Person {
private String school;
public Student(String name, Integer age, String school){
super(name, age);
this.school = school;
}
}
第二个子类Employee
package com.example.demo.Employee;
import com.example.demo.Student.Student;
import com.example.demo.person.Person;
import java.util.Date;
public class Employee extends Person {
private Date hireDay;
public Employee(String name, Integer age, Date hireDay){
super(name, age);
this.hireDay = hireDay;
}
public void test(Employee employee, Student student, Person person){
// protected域,对本包和所有子类可见
// 不过,子类的方法只能够访问子类对象中的域,而不能访问其他对象中的域(除非public)
// 后文的所有name域和getName方法均是父类的protect域/方法,但不是所有都是合法的调用
System.out.println(name); // 编译通过(被访问的name域属于Employee对象)
System.out.println(getName()); // 编译通过(被访问的getName()方法属于Employee对象)
System.out.println(employee.name); // 编译通过(被访问的name域属于Employee对象)
System.out.println(employee.getName()); // 编译通过(被访问的getName()方法属于Employee对象)
System.out.println(student.name); // 编译错误(被访问的name域不属于Employee对象)
System.out.println(student.getName()); // 编译错误(被访问的getName()方法不属于Employee对象)
System.out.println(person.name); // 编译错误(被访问的name域不属于Employee对象)
System.out.println(person.getName()); // 编译错误(被访问的getName()方法不属于Employee对象)
Person parent = employee;
System.out.println(parent.name); // 编译错误(被访问的name域不属于Employee对象)
}
}
试验结果表明:
子类可以访问父类中的protect域/方法,但是有一个前提,对应的域/方法属于子类。注意,是子类对象,而不是子类。