MST

星途 面试题库

面试题:Java抽象类访问修饰符对继承与多态的影响

当一个抽象类使用不同的访问修饰符(如public、protected、默认、private)时,对其继承体系以及多态特性的实现会产生哪些影响?请深入分析并结合代码示例,说明在不同访问修饰符下,子类继承抽象类、重写抽象方法以及通过多态调用方法的具体情况。
12.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. public 访问修饰符

  • 继承体系:任何包中的类都可以继承public修饰的抽象类。这使得该抽象类具有最广泛的可访问性,适合作为框架或通用库中的基础抽象类。
  • 多态特性实现:子类重写抽象方法时,重写的方法必须至少具有和父类抽象方法相同的访问权限(public),以确保多态调用的正确性。
// 定义一个public抽象类
public abstract class PublicAbstractClass {
    public abstract void publicAbstractMethod();
}
// 子类继承public抽象类
public class PublicSubClass extends PublicAbstractClass {
    @Override
    public void publicAbstractMethod() {
        System.out.println("Subclass implementation of public abstract method");
    }
}

在上述代码中,PublicSubClass 继承 PublicAbstractClass 并正确重写 publicAbstractMethod 方法,通过多态可以正常调用:

PublicAbstractClass obj = new PublicSubClass();
obj.publicAbstractMethod(); 

2. protected 访问修饰符

  • 继承体系:同包中的类以及不同包中的子类可以继承protected修饰的抽象类。这种访问修饰符适用于内部框架,对外部类不可见,但允许子类扩展。
  • 多态特性实现:子类重写抽象方法时,重写方法的访问权限至少为protected。在不同包的子类中,重写方法可以为public。
// 定义一个protected抽象类
protected abstract class ProtectedAbstractClass {
    protected abstract void protectedAbstractMethod();
}
// 同包中的子类
class SamePackageSubClass extends ProtectedAbstractClass {
    @Override
    protected void protectedAbstractMethod() {
        System.out.println("Same package subclass implementation");
    }
}
// 不同包中的子类
package anotherpackage;
import yourpackage.ProtectedAbstractClass;
public class DifferentPackageSubClass extends ProtectedAbstractClass {
    @Override
    public void protectedAbstractMethod() {
        System.out.println("Different package subclass implementation");
    }
}

在多态调用时:

// 同包中多态调用
ProtectedAbstractClass samePackageObj = new SamePackageSubClass();
samePackageObj.protectedAbstractMethod(); 
// 不同包中多态调用
ProtectedAbstractClass differentPackageObj = new DifferentPackageSubClass();
differentPackageObj.protectedAbstractMethod(); 

3. 默认(包访问权限)修饰符

  • 继承体系:只有同包中的类可以继承默认访问修饰符的抽象类。这限制了抽象类的继承范围,适用于只在同一个包内复用的抽象类。
  • 多态特性实现:子类重写抽象方法时,重写方法的访问权限至少为默认。
// 定义一个默认访问修饰符的抽象类
abstract class PackagePrivateAbstractClass {
    abstract void packagePrivateAbstractMethod();
}
// 同包中的子类
class PackagePrivateSubClass extends PackagePrivateAbstractClass {
    @Override
    void packagePrivateAbstractMethod() {
        System.out.println("Subclass implementation of package - private abstract method");
    }
}

多态调用:

PackagePrivateAbstractClass obj = new PackagePrivateSubClass();
obj.packagePrivateAbstractMethod(); 

如果在不同包中尝试继承会导致编译错误。

4. private 访问修饰符

  • 继承体系:无法被其他类继承,因为private修饰的抽象类只能在其所在类中被访问。这使得该抽象类失去了作为继承基础的意义。
  • 多态特性实现:由于不能被继承,也就无法实现多态。
// 定义一个private抽象类(这种定义意义不大,通常不会这么做)
private abstract class PrivateAbstractClass {
    private abstract void privateAbstractMethod();
}
// 尝试继承会导致编译错误
// class PrivateSubClass extends PrivateAbstractClass {
//     @Override
//     void privateAbstractMethod() {
//         System.out.println("This won't work");
//     }
// }

因为 PrivateAbstractClass 是private的,外部类无法继承,privateAbstractMethod 也是private,无法被重写,所以不能基于此类实现继承体系和多态。