本文 部分内容出自菜鸟教程
Java修饰符
Java提供了很多修饰符
- 访问修饰符
- 非访问修饰符
一.访问控制修饰符
Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。
default
(即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。private
: 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)public
: 对所有类可见。使用对象:类、接口、变量、方法protected
: 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
修饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Yes | Yes | Yes | Yes | Yes |
protected | Yes | Yes | Yes | Yes | No |
default | Yes | Yes | No | No | No |
private | Yes | No | No | No | No |
1、默认访问修饰符-不使用任何关键字
如果在类、变量、方法或构造函数的定义中没有指定任何访问修饰符,那么它们就默认具有默认访问修饰符。
默认访问修饰符的访问级别是包级别(package-level),即只能被同一包中的其他类访问。
2、private访问修饰符
私有访问修饰符是最严格的访问级别,所以被声明为 private
的方法、变量和构造方法只能被所属类访问,并且类和接口不能声明为 private
。
声明为私有访问类型的变量只能通过类中公共的 getter
方法被外部类访问。
Private
访问修饰符的使用主要用来隐藏类的实现细节和保护类的数据。
public class Person {
// 使用 private 修饰符定义私有变量
private String name;
private int age;
// 构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 公共的 getter 方法,用于获取私有变量的值
public String getName() {
return name;
}
public int getAge() {
return age;
}
// 打印个人信息的方法
public void printInfo() {
System.out.println("姓名: " + name + ", 年龄: " + age);
}
public static void main(String[] args) {
// 创建 Person 对象
Person person = new Person("张三", 25);
// 通过公共方法打印个人信息
person.printInfo();
// 可以通过 getter 方法访问私有变量
System.out.println("姓名: " + person.getName());
System.out.println("年龄: " + person.getAge());
// 下面代码将导致编译错误,因为 name 是 private
// System.out.println(person.name); // 不能直接访问
}
}
输出:
姓名: 张三, 年龄: 25
姓名: 张三
年龄: 25
3、公有访问修饰符-public(常用)
被声明为 public
的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的 public
类分布在不同的包中,则需要导入相应 public
类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。
// 定义一个公共类
public class Car {
// 使用 public 修饰符定义公共变量
public String brand;
public String model;
// 公共构造方法
public Car(String brand, String model) {
this.brand = brand;
this.model = model;
}
// 公共方法,用于显示汽车信息
public void displayInfo() {
System.out.println("品牌: " + brand + ", 型号: " + model);
}
public static void main(String[] args) {
// 创建 Car 对象
Car car = new Car("丰田", "卡罗拉");
// 直接访问公共变量
System.out.println("汽车品牌: " + car.brand);
System.out.println("汽车型号: " + car.model);
// 调用公共方法
car.displayInfo();
}
}
输出:
汽车品牌: 丰田
汽车型号: 卡罗拉
品牌: 丰田, 型号: 卡罗拉
4、受保护访问修饰符-protected
protected
需要从以下两个点来分析说明:
- 子类与基类在同一包中:被声明为
protected
的变量、方法和构造器能被同一个包中的任何其他类访问; - 子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的
protected
方法,而不能访问基类实例的protected
方法。
protected
可以修饰数据成员,构造方法,方法成员,不能修饰类(内部类除外)。
①访问范围的理解
子类访问:protected
变量和方法可以在子类中访问,即使子类在不同的包中。
包内访问:同一包中的其他类也能够访问 protected
成员,这一点需要清楚,以免意外暴露类的实现细节。
②继承关系的设计
设计目的:确保使用 protected
是因为你希望子类能够访问这些成员。避免随意使用 protected
,以免导致子类对基类的实现产生不必要的依赖。
关注子类需求:在设计基类时,思考哪些成员确实需要被子类访问,哪些则应该保持私有。
③复杂性和耦合性
增加依赖关系:protected
增加了父类与子类之间的耦合,如果子类过于依赖父类的 protected
成员,可能会使代码在重构时变得复杂。
版本控制:子类可能会依赖父类中某个 protected
方法的实现,未来对该方法的修改可能会影响所有子类。
④尽量遵循封装原则
考虑使用组合:在某些情况下,使用组合而非继承可能更好。通过将需要共享的功能放在独立的类中,来减少对子类的依赖。
使用接口:如果可能,考虑使用接口(Interface)来定义契约,这样可以更好地控制访问权限,并提高灵活性。
Animal.java
// 定义一个基类(父类)
public class Animal {
// 使用 protected 修饰符定义保护变量
protected String name;
// 公共构造方法
public Animal(String name) {
this.name = name;
}
// 使用 protected 方法
protected void makeSound() {
System.out.println(name + " 发出声音");
}
}
Dog.java
// 定义一个子类
public class Dog extends Animal {
// 子类构造方法
public Dog(String name) {
super(name);
}
// 子类特有的方法
public void bark() {
System.out.println(name + " 在叫");
}
}
Main.java
// 主类
public class Main {
public static void main(String[] args) {
// 创建 Dog 对象
Dog dog = new Dog("小白");
// 通过子类调用 protected 方法
dog.makeSound(); // 小白 发出声音
dog.bark(); // 小白 在叫
}
}
输出:
小白 发出声音
小白 在叫
评论区