📜  在Java中控制类和接口的可见性

📅  最后修改于: 2022-05-13 01:55:39.529000             🧑  作者: Mango

在Java中控制类和接口的可见性

维护是软件开发的重要方面之一,经验表明,保持其组件可见性低的软件比更多地暴露其组件的软件更易于维护。您不会预先知道它,但是在重新设计应用程序时,您会非常想念它。

您最终会修补并重复相同的错误,因为保持向后兼容性是许多应用程序的必备要求。您不会做太多事情,因为类和接口与许多其他应用程序紧密集成。 Java一直优先考虑封装,从一开始就提供支持的访问修饰符。通过将它们设为 public、package-private 或 private 提供了监视某些类型(例如类或接口)可见性的方法。

以下是控制可见性的一些规则:

  1. 顶级类(名称与包含它的Java源文件相同的类)也可以是公共包或私有包(没有访问修饰符),并且不能是私有包。 Private、public 或 package-private 可能只是一个嵌套类。
  2. 公共类是所有人都可以访问的,并且是最明显的,尽量只公开关键接口,在你相信它是完整和成熟的之前,永远不要让实现公开。
  3. 另一方面,私有类型不太明显,在Java中,只有嵌套的类或接口可以是私有的。您可以完全控制此类,以通过体验、新技术、工具和重新设计来更改其操作,因为它是最不显眼的。
  4. 包私有可见性是一个聪明的中途,也是默认可见性,没有包私有这样的关键字,相反,如果你没有任何访问修饰符,因为Java认为它是包私有的,然后让它只在同一个可见包裹。
  5. 如果类和接口仅在同一个包内的其他类之间共享,请将它们设为包私有。由于客户无法联系到他们,因此他们可以相当安全地进行更改。

如何控制Java接口的可见性?

除了使用访问修饰符降低类或接口的可见性之外,根据您的运行时环境,还有许多其他方法可以做到这一点。在组件级别,例如 Websphere、Weblogic 或 Application Server 中的 JBoss,接口类可能会被代理或包装以降低外部可见性。

不管你做什么,仍然会有某些类型需要暴露给外界,但你总是可以使用代理或包装器来处理它们。尽管客户端程序将加载代理的实现类,但通常会获得不可变的代理或包装器。

例如, Java Servlet API (javax.servlet) getServletContext() 返回 javax.servlet.ServletContext 的实现,它通常是满足 ServletContext 框架承诺的不可变代理。最有可能的是 javax.servlet.ServletContext 规范的一个单独版本在应用程序服务器上运行。

可以在其他外部可访问接口的实现中使用类似的模式,例如 Javax.ejb.EJBContext、Javax.ejb.TimerService、ServletRequest、ServletResponse 等。为了支持这些全局接口,各种应用服务器可以使用各种应用程序。

控制Java类可见性的JDK示例

EnumSet 类是管理可见性的另一个有趣的例子。为了防止实例化, Java设计者创建了抽象类并提供工厂方法作为创建该类实例的唯一方法,例如来自 EnumSet.of() 或 EnumSet.noneOf() 的方法。

在内部,以RegularEnumSet和JumboEnumSet的形式,它们有两个独立的实现,通过静态工厂方法根据主宇宙的大小自动选择。

例如,如果 Enum 中的值数小于 64,则使用 RegularEnumSet,否则返回 JumboEnumSet 实例。这种设计的美妙之处在于包私有意味着消费者不知道这些实现中的任何一个。

ModifierDescription
Defaultdeclarations are visible only within the package (package private)
Privatedeclarations are visible within the class only
Protecteddeclarations are visible within the package or all subclasses
Publicdeclarations are visible everywhere

私有访问修饰符

Java
// Java program for showcasing the behaviour
// of Private Access Modifier
  
class Data {
    
   // private variable
   private String name;
}
public class Main {
   public static void main(String[] main){
       
       // create an object of Data
       Data d = new Data();
       
       // access private variable and field from another class
       d.name = "Kapil";
   }
}


Java
// Java program for showcasing the behaviour
// of Protected Access Modifier
  
class Animal {
    
    // protected method
    protected void display() {
        System.out.println("I am an animal");
    }
}
  
class Dog extends Animal {
    
    public static void main(String[] args) {
  
        // create an object of Dog class
        Dog dog = new Dog();
        
        // access protected method
        dog.display();
    }
}


Java
// Java program for showcasing the behaviour
// of Public Access Modifier
  
// Animal.java file
// public class
  
class Animal {
    
    // public variable
    public int legCount;
  
    // public method
    public void display() {
        System.out.println("I am an animal.");
        System.out.println("I have " + legCount + " legs.");
    }
}
  
// Main.java
public class Main {
    public static void main( String[] args ) {
        // accessing the public class
        Animal animal = new Animal();
  
        // accessing the public variable
        animal.legCount = 4;
        // accessing the public method
        animal.display();
    }
}


输出:

Main.java:18: error: name has private access in Data
     d.name = "Programiz";
      ^

在上面的例子中,我们声明了一个名为 name 的私有变量和一个名为 display() 的私有方法。当我们运行程序时,我们会得到上面的错误:

受保护的访问修饰符

Java

// Java program for showcasing the behaviour
// of Protected Access Modifier
  
class Animal {
    
    // protected method
    protected void display() {
        System.out.println("I am an animal");
    }
}
  
class Dog extends Animal {
    
    public static void main(String[] args) {
  
        // create an object of Dog class
        Dog dog = new Dog();
        
        // access protected method
        dog.display();
    }
}
输出
I am an animal

公共访问修饰符:

Java

// Java program for showcasing the behaviour
// of Public Access Modifier
  
// Animal.java file
// public class
  
class Animal {
    
    // public variable
    public int legCount;
  
    // public method
    public void display() {
        System.out.println("I am an animal.");
        System.out.println("I have " + legCount + " legs.");
    }
}
  
// Main.java
public class Main {
    public static void main( String[] args ) {
        // accessing the public class
        Animal animal = new Animal();
  
        // accessing the public variable
        animal.legCount = 4;
        // accessing the public method
        animal.display();
    }
}
输出
I am an animal.
I have 4 legs.