面试题答案
一键面试访问修饰符访问规则
- public(公共的):
- 在基类
Animal
中声明为public
的成员(属性和方法),在子类Dog
中可以直接访问。这意味着在子类的方法内部可以调用基类的public
方法,也可以访问基类的public
属性。 - 从外部代码来看,无论是基类对象还是子类对象,都可以访问其
public
成员。
- 在基类
- private(私有的):
- 在基类
Animal
中声明为private
的成员,在子类Dog
中无法直接访问。即使子类继承自基类,也不能访问基类的private
成员。这是为了保证封装性,防止外部(包括子类)对内部实现细节的直接访问。 - 外部代码同样无法访问基类或子类对象的
private
成员。
- 在基类
- protected(受保护的):
- 在基类
Animal
中声明为protected
的成员,在子类Dog
中可以直接访问。与public
不同的是,外部代码不能直接访问基类或子类对象的protected
成员,只有子类内部可以访问。这提供了一种介于public
和private
之间的访问级别,允许子类访问一些基类的内部成员,但限制外部访问。
- 在基类
重写或扩展基类方法维持封装性
- 重写(Override):
- 当子类需要改变基类方法的行为时,可以重写该方法。在重写方法时,方法的签名(方法名、参数列表、返回类型)必须与基类中被重写的方法完全相同(在Java中,返回类型可以是协变的,即子类重写方法的返回类型可以是基类方法返回类型的子类)。
- 重写方法时,访问修饰符不能比基类中被重写方法的访问修饰符更严格。例如,如果基类方法是
public
,子类重写方法不能是protected
或private
。
- 扩展:
- 子类可以在重写方法中通过调用
super
关键字来调用基类的方法,从而在基类方法的基础上进行功能扩展。这样既利用了基类已有的功能,又增加了子类特有的功能,同时维持了封装性。
- 子类可以在重写方法中通过调用
代码示例(以Java语言为例)
class Animal {
private String name;
protected int age;
public String color;
public Animal(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
public void eat() {
System.out.println(name + " is eating.");
}
private void sleep() {
System.out.println(name + " is sleeping.");
}
}
class Dog extends Animal {
public Dog(String name, int age, String color) {
super(name, age, color);
}
@Override
public void eat() {
// 扩展基类的eat方法
super.eat();
System.out.println(name + " is eating dog food.");
}
public void play() {
// 可以访问protected属性age
System.out.println(name + " which is " + age + " years old is playing.");
// 不能访问private方法sleep()
// sleep(); 这行代码会报错
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("Buddy", 3, "Brown");
dog.eat();
dog.play();
// 可以访问public属性color
System.out.println("Dog's color is " + dog.color);
// 不能访问private属性name
// System.out.println("Dog's name is " + dog.name); 这行代码会报错
}
}
上述代码中,Animal
类是基类,Dog
类继承自Animal
。Dog
类重写了eat
方法并进行了扩展,同时展示了不同访问修饰符成员在子类中的访问情况。