Java 教程

Java 控制语句

面向对象编程

Java 内置类

Java 文件处理

Java 错误和异常

Java 多线程

Java 同步

Java 网络编程

Java 集合

Java 接口

Java 数据结构

Java 集合算法

高级 Java

Java 杂项

Java API 和框架

Java 类引用

Java 有用资源

Java - 访问修饰符



Java **访问修饰符** 用于指定变量的作用域数据成员、方法、类或构造函数。这些有助于限制和保护数据的访问(或访问级别)。

Java中有四种不同的访问修饰符,我们列举如下:

  • 默认(不需要关键字)
  • 私有 (private)
  • 受保护 (protected)
  • 公有 (public)
java access modifiers

默认访问修饰符

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

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

默认访问修饰符示例

变量和方法可以声明为没有任何修饰符,如下例所示:

String version = "1.5.1";

boolean processOrder() {
   return true;
}

私有访问修饰符

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

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

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

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

私有访问修饰符示例

示例 1

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

public class Logger {
   private String format;

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

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

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

因此,为了使此变量可用于外部世界,我们定义了两个公共方法:*getFormat()*,它返回 format 的值,以及 *setFormat(String)*,它设置其值。

示例 2

在此示例中,Logger 类的类数据成员和方法是私有的。我们尝试在另一个类 Main 中访问这些类方法。

class Logger {
  private String format;

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

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

public class Main {
  public static void main(String[] args) {
    // Creating an object 
    Logger log = new Logger();
    // Setting the value
    log.setFormat("Text");
    // Getting the value
    System.out.println(log.getFormat());

  }
}

输出

Main.java:18: error: setFormat(String) has private access in Logger
    log.setFormat("Text");
       ^
Main.java:20: error: getFormat() has private access in Logger
    System.out.println(log.getFormat());
                          ^
2 errors

受保护访问修饰符

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

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

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

受保护访问修饰符示例

示例 1

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

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

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

这里,如果我们将 `openSpeaker()` 方法定义为私有(private),那么除了 `AudioPlayer` 类之外,任何其他类都无法访问它。如果将其定义为公共(public),那么外部世界的所有类都可以访问它。但我们的意图是仅将其暴露给它的子类,这就是我们使用受保护(protected)修饰符的原因。

示例 1

此示例演示了受保护访问修饰符的使用。

// Class One
class One {
  protected void printOne() {
    System.out.println("printOne method of One class.");
  }
}

// Inheriting class One on Main
public class Main extends One {
  public static void main(String[] args) {
    // Creating an object of Main class
    Main obj = new Main();

    // Calling printOne() method of class One
    // through the object of Main class
    obj.printOne();
  }
}

输出

printOne method of One class.

公共访问修饰符

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

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

语法

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

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

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

公共访问修饰符示例

此示例演示了公共访问修饰符的使用。

// Class One
class One {
  public void printOne() {
    System.out.println("printOne method of One class.");
  }
}

public class Main {
  public static void main(String[] args) {
    // Creating an object of class One
    One obj = new One();

    // Calling printOne() method of class One
    obj.printOne();
  }
}

输出

This example demonstrates the use of public access modifier.

访问修饰符和继承

继承方法将强制执行以下规则:

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

  • 在超类中声明为受保护的方法在子类中必须是受保护的或公共的;它们不能是私有的。

  • 私有方法根本不会被继承,因此没有关于它们的规则。

下表根据访问修饰符总结了在相同/不同类(或包)中的可访问性。

java access modifiers - summary

带有继承的访问修饰符示例

在这个示例中,我们创建了一个类,其中包含一个私有变量 `age` 和一个具有默认作用域的变量 `name`。使用 setter/getter 方法,我们更新 `age` 并获取其值,而 `name` 是直接更新的。

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 );
   }
}

输出

Age: 2, name: Tommy
java_modifier_types.htm
广告