Java - 访问修饰符


Java 提供了许多访问修饰符来设置类、变量、方法和构造函数的访问级别。四个访问级别是 -

  • 对包可见,默认。不需要修饰符。
  • 仅对班级可见(私有)。
  • 对世界(公众)可见。
  • 对包和所有子类可见(受保护)。

默认访问修饰符 - 无关键字

默认访问修饰符意味着我们没有显式声明类、字段、方法等的访问修饰符。

没有任何访问控制修饰符声明的变量或方法可供同一包中的任何其他类使用。接口中的字段是隐式 public static final 的,接口中的方法默认是 public 的。

例子

变量和方法可以在没有任何修饰符的情况下声明,如以下示例所示 -

String version = "1.5.1";

boolean processOrder() {
   return true;
}

私有访问修饰符 - 私有

声明为私有的方法、变量和构造函数只能在声明的类本身内访问。

私有访问修饰符是最严格的访问级别。类和接口不能是私有的。

如果类中存在公共 getter 方法,则可以在类外部访问声明为 private 的变量。

使用 private 修饰符是对象封装自身并向外界隐藏数据的主要方式。

例子

以下类使用私有访问控制 -

public class Logger {
   private String format;

   public String getFormat() {
      return this.format;
   }

   public void setFormat(String format) {
      this.format = format;
   }
}

这里, Logger 类的格式变量是私有的,因此其他类无法直接检索或设置其值。

因此,为了使这个变量可供外界使用,我们定义了两个公共方法:getFormat(),它返回 format 的值;setFormat(String),它设置它的值。

公共访问修饰符 - 公共

声明为 public 的类、方法、构造函数、接口等可以从任何其他类访问。因此,在公共类中声明的字段、方法、块可以从属于 Java 宇宙的任何类访问。

但是,如果我们尝试访问的公共类位于不同的包中,则仍然需要导入该公共类。由于类继承,类的所有公共方法和变量都会被其子类继承。

例子

以下函数使用公共访问控制 -

public static void main(String[] arguments) {
   // ...
}

应用程序的 main() 方法必须是公共的。否则,Java解释器(例如java)无法调用它来运行该类。

受保护的访问修饰符 - 受保护

在超类中声明为 protected 的变量、方法和构造函数只能由其他包中的子类或受保护成员类的包中的任何类访问。

protected 访问修饰符不能应用于类和接口。方法、字段可以声明为 protected,但是接口中的方法和字段不能声明为 protected。

受保护的访问使子类有机会使用辅助方法或变量,同时防止不相关的类尝试使用它。

例子

以下父类使用受保护的访问控制,以允许其子类重写openSpeaker()方法 -

class AudioPlayer {
   protected boolean openSpeaker(Speaker sp) {
      // implementation details
   }
}

class StreamingAudioPlayer extends AudioPlayer {
   boolean openSpeaker(Speaker sp) {
      // implementation details
   }
}

在这里,如果我们将 openSpeaker() 方法定义为私有方法,那么除AudioPlayer之外的任何其他类都无法访问该方法。如果我们将其定义为公共的,那么所有外部世界都可以访问它。但我们的目的是仅将此方法公开给其子类,这就是我们使用 protected 修饰符的原因。

访问控制和继承

继承方法的以下规则是强制执行的 -

  • 在超类中声明为公共的方法也必须在所有子类中也是公共的。

  • 在超类中声明为 protected 的方法在子类中必须是 protected 或 public;它们不能是私有的。

  • 声明为私有的方法根本不被继承,因此没有针对它们的规则。

例子

在此示例中,我们创建了一个具有私有变量age 的类和一个以默认范围作为名称的变量。使用 setter/getter 方法,我们更新年龄并获取值,并且直接更新名称。

public class Puppy {
   private int age;
   String name;

   public Puppy() {      
   }

   public void setAge( int age ) {
      this.age = age;
   }

   public int getAge( ) {
      return age;
   }

   public static void main(String []args) {
      Puppy myPuppy = new Puppy();

      // update age variable using method call
      myPuppy.setAge( 2 );

      // update name directly
      myPuppy.name = "Tommy";
      System.out.println("Age: " + myPuppy.getAge() +", name: " + myPuppy.name );
   }
}

输出

年龄:2 岁,姓名:汤米
java_modifier_types.htm