MST

星途 面试题库

面试题:Java访问控制符与继承中的方法重写

当父类方法使用不同的访问控制符时,子类重写该方法有哪些规则限制?以public、protected和default为例,详细说明在继承关系中方法重写时访问控制符的约束,并用代码展示违反规则时会出现什么错误。
18.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. public 修饰的父类方法

  • 规则限制:子类重写该方法时,访问控制符必须是 public。不能使用更严格(更窄)的访问控制符,如 protecteddefaultprivate。这是因为重写方法需要保证对父类方法的可访问性不降低,以遵循里氏替换原则。如果子类方法使用了更严格的访问控制符,那么在使用父类引用调用该方法时,可能会因为访问权限不足而无法调用。
  • 代码示例及错误
class Parent {
    public void publicMethod() {
        System.out.println("Parent's public method");
    }
}

class Child extends Parent {
    // 错误示例:试图使用更严格的访问控制符
    // protected void publicMethod() { 
    //     System.out.println("Child's publicMethod"); 
    // }

    // 正确示例
    public void publicMethod() {
        System.out.println("Child's publicMethod");
    }
}

如果尝试将 Child 类中的 publicMethodprotected 修饰,编译时会报错:'publicMethod()' in 'Child' cannot override 'publicMethod()' in 'Parent'; attempting to assign weaker access privileges; was public

2. protected 修饰的父类方法

  • 规则限制:子类重写该方法时,访问控制符可以是 protected 或者 public。因为 public 访问控制符比 protected 更宽松,所以使用 public 符合可访问性不降低的原则。但不能使用 defaultprivate,因为这两种访问控制符的访问范围比 protected 更窄,不符合里氏替换原则。
  • 代码示例及错误
class Parent {
    protected void protectedMethod() {
        System.out.println("Parent's protected method");
    }
}

class Child extends Parent {
    // 错误示例:试图使用更严格的访问控制符
    // void protectedMethod() { 
    //     System.out.println("Child's protectedMethod"); 
    // }

    // 正确示例1
    protected void protectedMethod() {
        System.out.println("Child's protectedMethod");
    }

    // 正确示例2
    public void protectedMethod() {
        System.out.println("Child's public protectedMethod");
    }
}

如果尝试将 Child 类中的 protectedMethoddefault 修饰(即不写访问控制符),编译时会报错:'protectedMethod()' in 'Child' cannot override 'protectedMethod()' in 'Parent'; attempting to assign weaker access privileges; was protected

3. default(包访问权限,即不写访问控制符)修饰的父类方法

  • 规则限制:子类重写该方法时,访问控制符可以是 defaultprotected 或者 public。因为 protectedpublic 的访问范围比 default 更广,符合可访问性不降低的原则。但不能使用 private,因为 private 访问控制符的访问范围比 default 更窄。
  • 代码示例及错误
class Parent {
    void defaultMethod() {
        System.out.println("Parent's default method");
    }
}

class Child extends Parent {
    // 错误示例:试图使用更严格的访问控制符
    // private void defaultMethod() { 
    //     System.out.println("Child's defaultMethod"); 
    // }

    // 正确示例1
    void defaultMethod() {
        System.out.println("Child's defaultMethod");
    }

    // 正确示例2
    protected void defaultMethod() {
        System.out.println("Child's protected defaultMethod");
    }

    // 正确示例3
    public void defaultMethod() {
        System.out.println("Child's public defaultMethod");
    }
}

如果尝试将 Child 类中的 defaultMethodprivate 修饰,编译时会报错:'defaultMethod()' in 'Child' cannot override 'defaultMethod()' in 'Parent'; attempting to assign weaker access privileges; was (package-private)