【java第14集】java访问修饰符详解
文章目录
- 1. Java 访问修饰符概述
- 2. 四种访问修饰符详解
- 2.1 `public`(公共访问)
- 2.2 `protected`(受保护访问)
- 2.3 `default`(默认,包级私有,无修饰符)
- 2.4 `private`(私有访问)
- 3. 顶层类的访问修饰符
- 4. 访问修饰符的设计哲学
- 5. 常见问题与注意事项
- 6. 总结
1. Java 访问修饰符概述
Java 提供了 四种访问修饰符,用于控制类、方法、变量和构造器的访问权限。通过合理设置访问权限,可以实现代码的封装性,降低类之间的耦合度,并提高代码的安全性和可维护性。
修饰符 | 类内部 | 同一包 | 子类 | 其他包 |
---|---|---|---|---|
public | ✔️ | ✔️ | ✔️ | ✔️ |
protected | ✔️ | ✔️ | ✔️ | ❌ |
default (默认,无修饰符) | ✔️ | ✔️ | ❌ | ❌ |
private | ✔️ | ❌ | ❌ | ❌ |
2. 四种访问修饰符详解
2.1 public
(公共访问)
- 作用:被
public
修饰的类、方法、变量或构造器可以被任何类访问,无论是否在同一个包中。 - 使用场景:
- 公共接口方法(如
get
/set
方法)。 - 工具类或常量类(如
Math
类的PI
常量)。
- 公共接口方法(如
- 示例:
public class PublicExample {public int publicVar = 100; // 可被任何类访问public void publicMethod() {System.out.println("Public Method");} }
2.2 protected
(受保护访问)
- 作用:
- 被
protected
修饰的成员可以在 同一包内访问,也可以在 不同包的子类中访问。 - 跨包子类不能直接访问父类实例的
protected
成员(需通过继承)。
- 被
- 使用场景:
- 父类中需要被子类继承但对外部隐藏的成员。
- 包内协作的扩展功能。
- 示例:
// 父类(包 com.example.parent) public class Parent {protected int protectedVar = 200; // 同包或子类可见protected void protectedMethod() {System.out.println("Protected Method");} }// 子类(包 com.example.child) public class Child extends Parent {void accessProtected() {System.out.println(protectedVar); // 允许:继承的 protected 成员protectedMethod(); // 允许:继承的 protected 方法Parent p = new Parent();// p.protectedVar = 300; // ❌ 错误:跨包不能直接访问父类实例的 protected 成员} }
2.3 default
(默认,包级私有,无修饰符)
- 作用:
- 未显式使用修饰符时,成员默认只能在 同一包内访问。
- 子类无法继承默认访问权限的成员(即使在不同包中)。
- 使用场景:
- 包内共享的辅助类或工具方法。
- 不需要跨包访问的实现细节。
- 示例:
// 包 com.example.utils class DefaultExample { // 仅同包可见int defaultVar = 300; // 同包内可见void defaultMethod() {System.out.println("Default Method");} }// 同包类 public class Test {void testDefault() {DefaultExample obj = new DefaultExample();obj.defaultVar = 400; // 允许:同包访问obj.defaultMethod(); // 允许:同包访问} }
2.4 private
(私有访问)
- 作用:
- 被
private
修饰的成员 仅在定义它的类内部可见。 - 子类和包外类都无法直接访问。
- 被
- 使用场景:
- 封装类的内部实现细节(如字段、工具方法)。
- 防止外部直接修改对象状态。
- 示例:
public class PrivateExample {private int privateVar = 400; // 仅本类可见private void privateMethod() {System.out.println("Private Method");}// 公共方法提供对私有成员的受控访问public void accessPrivate() {System.out.println(privateVar); // 允许:本类内部访问privateMethod(); // 允许:本类内部访问} }// 测试类 public class Test {void testPrivate() {PrivateExample obj = new PrivateExample();// System.out.println(obj.privateVar); // ❌ 错误:外部无法访问 private 成员// obj.privateMethod(); // ❌ 错误:外部无法访问 private 方法obj.accessPrivate(); // 允许:通过公共方法间接访问} }
3. 顶层类的访问修饰符
- 顶层类(非内部类)的修饰符限制:
- 只能使用
public
或default
(默认,包私有) 修饰符。 - 不能使用
private
或protected
。
- 只能使用
- 示例:
// 允许 public class PublicClass { /* ... */ } class DefaultClass { /* ... */ } // 默认访问权限// ❌ 错误:顶层类不能使用 private 或 protected private class PrivateClass { /* ... */ } protected class ProtectedClass { /* ... */ }
4. 访问修饰符的设计哲学
- 封装性:
- 使用
private
隐藏实现细节,通过public
或protected
提供受控的访问接口。 - 例如:
private int age
通过getAge()
和setAge(int age)
方法访问。
- 使用
- 模块化:
- 使用默认修饰符将实现细节限制在包内,降低外部依赖。
- 继承与扩展:
- 使用
protected
允许子类继承并扩展功能,同时限制外部访问。
- 使用
5. 常见问题与注意事项
Q1: protected
成员在跨包子类中如何访问?
- 答案:
- 子类可以继承父类的
protected
成员,但 不能直接访问父类实例的protected
成员。 - 必须通过 继承的子类实例 或 自身继承的成员 访问。
- 子类可以继承父类的
Q2: 为什么 private
成员不能被子类继承?
- 答案:
private
成员仅在定义它的类内部可见,子类无法直接访问。- 如果需要子类使用,需通过
protected
或public
方法暴露接口。
Q3: 如何选择访问修饰符?
- 建议:
- 默认:优先使用
private
,仅在需要时放宽权限。 - 跨包访问:使用
public
。 - 子类继承:使用
protected
。 - 包内共享:使用默认修饰符。
- 默认:优先使用
6. 总结
范围:public
> protected
> default
> private
修饰符 | 作用范围 | 典型用途 |
---|---|---|
public | 所有类 | 公共接口、工具类 |
protected | 同包 + 子类 | 父类成员供子类继承 |
default (默认,无修饰符) | 同包 | 包内协作、实现细节 |
private | 本类 | 封装内部状态、工具方法 |