详解Java之路(五) 访问权限控制

 更新时间:2016年12月09日 08:26:00   作者:songoo  
本篇文章主要介绍了Java之路(五) 访问权限控制 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在Java中,所有事物都具有某种形式的访问权限控制。

访问权限的控制等级从最大到最小依次为:public,protected,包访问权限(无关键词)和private。

public,protected和private这几个Java访问权限修饰词在使用时,是置于类中每个成员(域或者方法)定义之前的。

一、类成员的访问权限

取得对某成员的访问权的唯一途径是:

  1).使该成员成为public。无论谁在哪里,都可以访问该成员;

  2).通过不加访问权限的修饰词并将其他类放置于同一包内的方式给成员赋予包访问权限,包内的其他类可以访问该成员;

  3).继承而来的类既可以访问public成员也可以访问protected成员。

  4).提供访问器和变异器方法,以读取和改变数值。

1.包访问权限

默认访问权限没有任何关键字,但通过是指包访问权限,这表示当前报中的所有其他类都对那个成员有访问权限,但是对于这个包之外的所有类,这个成员确是private。

包访问权限将包内所有相关的类组合起来,以使它们彼此之间可以轻松地相互作用。

注意:如果两个类处于相同的目录下,并且没有给自己设定任何包名称,Java会将这样的文件自动看作是隶属于该目录的默认包之中,于是这些文件互相之间有包访问权限。

下面的例子说明了这个问题:

//类Cake和Pie处于同一目录下,没有明确的显示在任何包中

class Pie{
  void f(){
    System.out.println("Pie.f()");
  }
}

class Cake{
  public static void main(String[] args){
     Pie x = new Pie();
     x.f();
   }
}

//输出为Pie.f()

2.public:接口访问权限

使用关键字public,就意味着其后的成员声明对所有人可用,特别是使用类库的客户程序员也是如此。

3.private:你无法访问

关键字private表示出了包含该成员的类之外,其他任何类都无法访问这个成员。同一包内的其他类不可以访问这个类的private成员,因此这相当于自己隔离了自己。

private关键字的这种作用有许多用途,比如,控制如何创建对象,阻止别人直接访问某个特定的构造器(或全部构造器)。看

下面的例子:

class Sundae{
  private Sundae(){}
  static Sundae makeASundae(){
    return new Sundae();
  }
}

public class IceCream {
  public static void main(String[] args){
    Sundae x = Sundae.makeASundae();
  }
}

这个例子里,我们可以通过调用makeASundae()方法来创建Sundae对象,但是不能通过构造器来创建。

这对于类中的private域同样适用。

但是要注意一点,不能因为在类中某个对象的引用是private,就认为其他的对象无法拥有该对象的public引用。

4.protected:继承访问权限

如果创建了一个新包,并自另一个包继承类,那么唯一可以访问的成员就是源包的public成员。

有时,基类的创建者希望将某个特定成员的访问权限赋予派生类而非所有类,这就需要使用关键字protected来实现。

注意,protected也提供包访问权限,即相同包内的其他类也可以访问此类的protected元素。

二、接口和实现

访问权限的控制通常被称为具体实现的隐藏。

把数据和方法包装进类中,以及具体实现的隐藏,常共同被称作是封装。

出于两个重要的原因,访问权限控制将权限的边界划在了数据类型的内部:

1.要设定客户端程序员可以使用和不可以使用的界限。可以在结构中建立自己的内部机制,儿不必担心客户端程序员会偶然地将内部机制当做是他们使用的接口的一部分。

2.接口和具体实现进行分离。

三、类的访问权限

Java中,访问权限修饰词也可以用于确定库中的哪些类对于该库的使用者是可用的。

修饰词必须放在关键字class之前。例如:

public class Widget{......}


improt access.Widget;

要知道,类不可以是private的(如果类是private的,那么除了该类之外,其他任何类都不可以访问它),也不可以是protected的(其实一个内部类可以是private或protected的,但这是特例,后续文章中叙述),只可以是包访问权限或public的。

如果不希望其他人访问该类,可以把该类的所有构造器都指定为private,阻止任何人创建该类的对象。但这也有例外,这种做法不能阻止你在该类的static成员内部创建该类。我们来看下边的例子:

class Soup1{
  private Soup1(){}
  public static Soup1 makeSoup(){ //使用静态方法创建对象
    return new Soup1();
  }
}

class Soup2{
  private Soup2(){}
  private static Soup2 ps1 = new Soup2(); //使用单例模式创建对象
  public static Soup2 access(){
    return ps1;
  }
  public void f(){}
}

public class Lunch {
  void testPrivate(){
  //Soup1 soup = new Soup1; 不能执行
  }
  void testSingleton(){
    Soup2.access().f();
  }
}


我们可以看到,Soup1和Soup2类的构造器都是private的,谁也无法直接使用构造器来创建该类的对象了。但是我们也可以使用这两个类:在Soup1中创建一个static方法,在这个方法中使用构造函数创建一个Soup1对象并返回它的引用;Soup2的创建用了设计模式中的单例模式,只能创建它的一个对象。Soup2类的对象是作为Soup2的一个static private成员而创建的,所以有且仅有一个,而且除非是通过public方法access(),否则是无法访问到它的。

 此外,一些限制也值得注意:

1.每个编译单元都只能有一个public类。

2.public类的名称必须完全与含有给编译单元的文件名相匹配,包括大小写。

3.如果编译单元内没有带public的类,这时可以对文件随意命名。

 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Java实现多个数组间的排列组合

    Java实现多个数组间的排列组合

    这篇文章主要为大家详细介绍了Java实现多个数组间的排列组合,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • Java 自定义注解在登录验证的应用示例

    Java 自定义注解在登录验证的应用示例

    本文主要介绍了Java 自定义注解在登录验证的应用示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Java获取电脑真实IP地址的示例代码

    Java获取电脑真实IP地址的示例代码

    这篇文章主要介绍了Java如何获取电脑真实IP地址,忽略虚拟机等IP地址的干扰,帮助大家更好的理解和使用Java,感兴趣的朋友可以了解下
    2020-09-09
  • Mybatis中TypeAliasRegistry的作用及使用方法

    Mybatis中TypeAliasRegistry的作用及使用方法

    Mybatis中的TypeAliasRegistry是一个类型别名注册表,它的作用是为Java类型建立别名,使得在Mybatis配置文件中可以使用别名来代替完整的Java类型名。使用TypeAliasRegistry可以简化Mybatis配置文件的编写,提高配置文件的可读性和可维护性
    2023-05-05
  • JavaMail实现发送邮件功能

    JavaMail实现发送邮件功能

    这篇文章主要为大家详细介绍了JavaMail实现发送邮件功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • 关于java.math.BigDecimal比较大小问题

    关于java.math.BigDecimal比较大小问题

    这篇文章主要介绍了关于java.math.BigDecimal比较大小问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Spring AOP底层机制之代理模式

    Spring AOP底层机制之代理模式

    如何实现在不修改源码的基础上实现代码功能的增强呢?spring为我们提供了代理模式。所谓的代理模式通俗来说就是一个中介,它给某一个对象提供一个代理对象,并由代理对象控制原对象的引用,从而实现在不修改源码的基础上实现代码功能的增强
    2022-08-08
  • Java中转义字符反斜杠\的代替方法及repalceAll内涵解析

    Java中转义字符反斜杠\的代替方法及repalceAll内涵解析

    这篇文章主要介绍了Java中转义字符反斜杠\的代替方法及repalceAll内涵解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • 基于Listener监听器生命周期(详解)

    基于Listener监听器生命周期(详解)

    下面小编就为大家带来一篇基于Listener监听器生命周期(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • SpringCloud @RefreshScope注解源码层面深入分析

    SpringCloud @RefreshScope注解源码层面深入分析

    @RefreshScope注解能帮助我们做局部的参数刷新,但侵入性较强,需要开发阶段提前预知可能的刷新点,并且该注解底层是依赖于cglib进行代理的,所以不要掉入cglib的坑,出现刷了也不更新情况
    2023-04-04

最新评论