MST

星途 面试题库

面试题:Java中不同访问修饰符对类可见性的影响

请阐述Java中public、protected、default(包访问权限)和private这几种访问修饰符修饰类时,其可见性的具体规则,并举例说明在不同包结构下,不同修饰符修饰的类如何被访问。
17.8万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. 访问修饰符修饰类时的可见性规则

  • public:被public修饰的类具有最大的访问权限,对所有包中的所有类都可见。任何其他类,无论在同一个包还是不同包中,只要能找到该类的字节码文件,就可以访问它。
  • protectedprotected不能修饰顶级类(即直接定义在包下的类),只能修饰内部类。如果修饰内部类,它的访问权限比包访问权限(default)更宽泛一些,除了同包内的类可以访问,不同包中该类的子类也可以访问。
  • default(包访问权限):当类没有显式使用任何访问修饰符时,就具有包访问权限。具有包访问权限的类只能被同一个包中的其他类访问,不同包中的类无法访问。
  • privateprivate同样不能修饰顶级类,只能修饰内部类。被private修饰的内部类只能在其外部类内部被访问,其他任何类(包括同一个包中的其他类)都无法访问。

2. 不同包结构下的访问示例

假设我们有以下包结构:

com
├── example
│   ├── ParentPackage
│   │   ├── ParentClass.java
│   │   └── OtherClassInSamePackage.java
│   └── ChildPackage
│       └── ChildClass.java

2.1 public修饰的类

ParentClass.java

package com.example.ParentPackage;

public class ParentClass {
    public void publicMethod() {
        System.out.println("This is a public method in ParentClass.");
    }
}

ChildClass.java

package com.example.ChildPackage;
import com.example.ParentPackage.ParentClass;

public class ChildClass {
    public static void main(String[] args) {
        ParentClass parent = new ParentClass();
        parent.publicMethod();
    }
}

在上述示例中,ChildClass在不同包com.example.ChildPackage中可以通过导入com.example.ParentPackage.ParentClass来访问public修饰的ParentClass及其public方法。

2.2 default修饰的类(包访问权限)

OtherClassInSamePackage.java

package com.example.ParentPackage;

class OtherClassInSamePackage {
    void accessDefaultClass() {
        ParentClass parent = new ParentClass();
        parent.publicMethod();
    }
}

如果ParentClass没有public修饰符,而是默认的包访问权限,OtherClassInSamePackage在同一个包com.example.ParentPackage中可以访问ParentClass及其public方法。但ChildClass在不同包中就无法访问ParentClass

2.3 protected修饰内部类的示例

ParentClass.java

package com.example.ParentPackage;

public class ParentClass {
    protected static class InnerProtectedClass {
        void innerMethod() {
            System.out.println("This is an inner method of InnerProtectedClass.");
        }
    }
}

ChildClass.java

package com.example.ChildPackage;
import com.example.ParentPackage.ParentClass;

public class ChildClass extends ParentClass {
    public static void main(String[] args) {
        ParentClass.InnerProtectedClass inner = new ChildClass().new InnerProtectedClass();
        inner.innerMethod();
    }
}

这里InnerProtectedClassParentClass的内部类且被protected修饰,ChildClass作为ParentClass的子类,虽然在不同包,但仍可以访问InnerProtectedClass

2.4 private修饰内部类的示例

ParentClass.java

package com.example.ParentPackage;

public class ParentClass {
    private static class InnerPrivateClass {
        void innerMethod() {
            System.out.println("This is an inner method of InnerPrivateClass.");
        }
    }

    public void accessInnerPrivateClass() {
        InnerPrivateClass inner = new InnerPrivateClass();
        inner.innerMethod();
    }
}

ParentClass外部,即使在同一个包中,其他类也无法访问InnerPrivateClass。只有ParentClass自身的方法accessInnerPrivateClass可以访问InnerPrivateClass