Java访问指示符 访问修饰符
5.2 Java访问指示符
针对类内每个成员的每个定义,Java访问指示符poublic,protected以及private都置于它们的最前面——无论它们是一个数据成员,还是一个方法。每个访问指示符都只控制着对那个特定定义的访问。这与C++存在着显著不同。在C++中,访问指示符控制着它后面的所有定义,直到又一个访问指示符加入为止。
通过千丝万缕的联系,程序为所有东西都指定了某种形式的访问。在后面的小节里,大家要学习与各类访问有关的所有知识。首次从默认访问开始。
5.2.1 “友好的”
如果根本不指定访问指示符,就象本章之前的所有例子那样,这时会出现什么情况呢?默认的访问没有关键字,但它通常称为“友好”(Friendly)访问。这意味着当前包内的其他所有类都能访问“友好的”成员,但对包外的所有类来说,这些成员却是“私有”(Private)的,外界不得访问。由于一个编译单元(一个文件)只能从属于单个包,所以单个编译单元内的所有类相互间都是自动“友好”的。因此,我们也说友好元素拥有“包访问”权限。
友好访问允许我们将相关的类都组合到一个包里,使它们相互间方便地进行沟通。将类组合到一个包内以后(这样便允许友好成员的相互访问,亦即让它们“交朋友”),我们便“拥有”了那个包内的代码。只有我们已经拥有的代码才能友好地访问自己拥有的其他代码。我们可认为友好访问使类在一个包内的组合显得有意义,或者说前者是后者的原因。在许多语言中,我们在文件内组织定义的方式往往显得有些牵强。但在Java中,却强制用一种颇有意义的形式进行组织。除此以外,我们有时可能想排除一些类,不想让它们访问当前包内定义的类。
对于任何关系,一个非常重要的问题是“谁能访问我们的‘私有’或private代码”。类控制着哪些代码能够访问自己的成员。没有任何秘诀可以“闯入”。另一个包内推荐可以声明一个新类,然后说:“嗨,我是Bob的朋友!”,并指望看到Bob的“protected”(受到保护的)、友好的以及“private”(私有)的成员。为获得对一个访问权限,唯一的方法就是:
(1) 使成员成为“public”(公共的)。这样所有人从任何地方都可以访问它。
(2) 变成一个“友好”成员,方法是舍弃所有访问指示符,并将其类置于相同的包内。这样一来,其他类就可以访问成员。
(3) 正如以后引入“继承”概念后大家会知道的那样,一个继承的类既可以访问一个protected成员,也可以访问一个public成员(但不可访问private成员)。只有在两个类位于相同的包内时,它才可以访问友好成员。但现在不必关心这方面的问题。
(4) 提供“访问器/变化器”方法(亦称为“获取/设置”方法),以便读取和修改值。这是OOP环境中最正规的一种方法,也是Java Beans的基础——具体情况会在第13章介绍。
5.2.2 public:接口访问
使用public关键字时,它意味着紧随在public后面的成员声明适用于所有人,特别是适用于使用库的客户程序员。假定我们定义了一个名为dessert的包,其中包含下述单元(若执行该程序时遇到困难,请参考第3章3.1.2小节“赋值”):
//: Cookie.java
// Creates a library
package c05.dessert;public class Cookie {public Cookie() { System.out.println("Cookie constructor"); }void foo() { System.out.println("foo"); }
} ///:~
请记住,Cookie.java必须驻留在名为dessert的一个子目录内,而这个子目录又必须位于由CLASSPATH指定的C05目录下面(C05代表本书的第5章)。不要错误地以为Java无论如何都会将当前目录作为搜索的起点看待。如果不将一个“.”作为CLASSPATH的一部分使用,Java就不会考虑当前目录。 现在,假若创建使用了Cookie的一个程序,如下所示:
//: Dinner.java
// Uses the library
import c05.dessert.*;public class Dinner {public Dinner() {System.out.println("Dinner constructor");}public static void main(String[] args) {Cookie x = new Cookie();//! x.foo(); // Can't access}
} ///:~
就可以创建一个Cookie对象,因为它的构建器是public的,而且类也是public的(公共类的概念稍后还会进行更详细的讲述)。然而,foo()成员不可在Dinner.java内访问,因为foo()只有在dessert包内才是“友好”的。
- 默认包
大家可能会惊讶地发现下面这些代码得以顺利编译——尽管它看起来似乎已违背了规则:
//: Cake.java
// Accesses a class in a separate
// compilation unit.class Cake {public static void main(String[] args) {Pie x = new Pie();x.f();}
} ///:~
在位于相同目录的第二个文件里:
//: Pie.java
// The other classclass Pie {void f() { System.out.println("Pie.f()"); }
} ///:~
最初可能会把它们看作完全不相干的文件,然而Cake能创建一个Pie对象,并能调用它的f()方法!通常的想法会认为Pie和f()是“友好的”,所以不适用于Cake。它们确实是友好的——这部分结论非常正确。但它们之所以仍能在Cake.java中使用,是由于它们位于相同的目录中,而且没有明确的包名。Java把象这样的文件看作那个目录“默认包”的一部分,所以它们对于目录内的其他文件来说是“友好”的。
5.2.3 private:不能接触!
private关键字意味着除非那个特定的类,而且从那个类的方法里,否则没有人能访问那个成员。同一个包内的其他成员不能访问private成员,这使其显得似乎将类与我们自己都隔离起来。另一方面,也不能由几个合作的人创建一个包。所以private允许我们自由地改变那个成员,同时毋需关心它是否会影响同一个包内的另一个类。默认的“友好”包访问通常已经是一种适当的隐藏方法;请记住,对于包的用户来说,是不能访问一个“友好”成员的。这种效果往往能令人满意,因为默认访问是我们通常采用的方法。对于希望变成public(公共)的成员,我们通常明确地指出,令其可由客户程序员自由调用。而且作为一个结果,最开始的时候通常会认为自己不必频繁使用private关键字,因为完全可以在不用它的前提下发布自己的代码(这与C++是个鲜明的对比)。然而,随着学习的深入,大家就会发现private仍然有非常重要的用途,特别是在涉及多线程处理的时候(详情见第14章)。 下面是应用了private的一个例子:
//: IceCream.java
// Demonstrates "private" keywordclass Sundae {private Sundae() {}static Sundae makeASundae() { return new Sundae(); }
}public class IceCream {public static void main(String[] args) {//! Sundae x = new Sundae();Sundae x = Sundae.makeASundae();}
} ///:~
这个例子向我们证明了使用private的方便:有时可能想控制对象的创建方式,并防止有人直接访问一个特定的构建器(或者所有构建器)。在上面的例子中,我们不可通过它的构建器创建一个Sundae对象;相反,必须调用makeASundae()方法来实现(注释③)。
③:此时还会产生另一个影响:由于默认构建器是唯一获得定义的,而且它的属性是private,所以可防止对这个类的继承(这是第6章要重点讲述的主题)。
若确定一个类只有一个“助手”方法,那么对于任何方法来说,都可以把它们设为private,从而保证自己不会误在包内其他地方使用它,防止自己更改或删除方法。将一个方法的属性设为private后,可保证自己一直保持这一选项(然而,若一个句柄被设为private,并不表明其他对象不能拥有指向同一个对象的public句柄。有关“别名”的问题将在第12章详述)。
5.2.4 protected:“友好的一种”
protected(受到保护的)访问指示符要求大家提前有所认识。首先应注意这样一个事实:为继续学习本书一直到继承那一章之前的内容,并不一定需要先理解本小节的内容。但为了保持内容的完整,这儿仍然要对此进行简要说明,并提供相关的例子。
protected关键字为我们引入了一种名为“继承”的概念,它以现有的类为基础,并在其中加入新的成员,同时不会对现有的类产生影响——我们将这种现有的类称为“基础类”或者“基本类”(Base Class)。亦可改变那个类现有成员的行为。对于从一个现有类的继承,我们说自己的新类“扩展”(extends)了那个现有的类。如下所示:
class Foo extends Bar {
类定义剩余的部分看起来是完全相同的。
若新建一个包,并从另一个包内的某个类里继承,则唯一能够访问的成员就是原来那个包的public成员。当然,如果在相同的包里进行继承,那么继承获得的包能够访问所有“友好”的成员。有些时候,基础类的创建者喜欢提供一个特殊的成员,并允许访问衍生类。这正是protected的工作。若往回引用5.2.2小节“public:接口访问”的那个Cookie.java文件,则下面这个类就不能访问“友好”的成员:
//: ChocolateChip.java
// Can't access friendly member
// in another class
import c05.dessert.*;public class ChocolateChip extends Cookie {public ChocolateChip() {System.out.println("ChocolateChip constructor");}public static void main(String[] args) {ChocolateChip x = new ChocolateChip();//! x.foo(); // Can't access foo}
} ///:~
对于继承,值得注意的一件有趣的事情是倘若方法foo()存在于类Cookie中,那么它也会存在于从Cookie继承的所有类中。但由于foo()在外部的包里是“友好”的,所以我们不能使用它。当然,亦可将其变成public。但这样一来,由于所有人都能自由访问它,所以可能并非我们所希望的局面。若象下面这样修改类Cookie:
public class Cookie {public Cookie() { System.out.println("Cookie constructor");}protected void foo() {System.out.println("foo"); }
}
那么仍然能在包dessert里“友好”地访问foo(),但从Cookie继承的其他东西亦可自由地访问它。然而,它并非公共的(public)。
from: https://quanke.gitbooks.io/think-in-java/content/5.2%20Java%E8%AE%BF%E9%97%AE%E6%8C%87%E7%A4%BA%E7%AC%A6.html
Java访问指示符 访问修饰符相关推荐
- java中的权限修饰符_Java的权限修饰符的区别和用法总结
类中的数据成员和成员函数据具有的访问权限包括:public.private.protect.friendly(包访问权限). 1.public:public表明该数据成员.成员函数是对所有用户开放的, ...
- java修饰方法有哪些,探讨Java语言中那些修饰符
一.在java中提供的一些修饰符,这些修饰符可以修饰类.变量和方法,在java中常见的修饰符有:abstract(抽象的).static(静态的).public(公共的).protected(受保护的 ...
- Java final修饰符的作用,Java中的final修饰符
1.什么时候可以选择final修饰符 如果想让一个类不被其他类继承,不允许在有子类,这时候就要考虑用到final来修饰. 2.用final修饰的类 首先大家要明白,用final修饰的类是不能被继承的, ...
- Java 四种权限修饰符
Java 四种权限修饰符访问权限 public protected (default) private 同一个类(我自己) yes yes yes yes 同一包(我邻居) yes yes yes n ...
- JAVA软件海豚_Java 修饰符
一.访问控制修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java支持4种不同的访问权限. 默认的,也称为 default,在同一包内可见,不使用任何修饰符. 私有的, ...
- Java常见的各种修饰符
Java常见的各种修饰符 目录 Java常见的各种修饰符 修饰符的分类 一.访问权限修饰符 二.非访问权限修饰符 修饰符的使用 一.类修饰符 1.外部类修饰符 2.内部类修饰符 二.方法修饰符 三.变 ...
- 实际上Java注解与普通修饰符(public、static、void等)的使用方式并没有多大区别
Java 注解 实际上Java注解与普通修饰符(public.static.void等)的使用方式并没有多大区别 注解的定义 日常开发中新建Java类,我们使用class.interface比较多,而 ...
- java 接口中变量修饰符,Java的访问修饰符与变量的作用域讲解
Java访问修饰符(访问控制符) Java 通过修饰符来控制类.属性和方法的访问权限和其他功能,通常放在语句的最前端.例如: ? Java 的修饰符很多,分为访问修饰符和非访问修饰符.本节仅介绍访问修 ...
- 同包类 和 其他类 java_关于继承:为什么Java中的“protected”修饰符允许访问同一个包中的其他类?...
在Java中,具有"受保护"修饰符的成员不仅可以由同一个类和子类访问,还可以由同一个包中的每个人访问? 我想知道语言设计的原因,而不是实际的应用程序(例如,测试) +1坦率地说我也 ...
最新文章
- html文字字号不改变,如何在不改变div大小的情况下更改HTML / css中的字体大小?...
- 110. Balanced Binary Tree
- matlab简单程序实例视频,matlab编程实例100例.docx
- java语言构造顺序树_PAT-1086(Tree Traversals Again)Java语言实现+根据中序和前序遍历构建树并且给出后序遍历序列...
- 【JOURNAL】Salles de SV Toulouse
- Winform控件学习笔记【第四天】——WebBrowser
- android系统关闭wifi,Android以编程方式打开/关闭WiFi HotSpot
- Java空字符串与null区别
- java简历自我评价_java程序员简历自我评价怎么写
- otdr进行多种测试鸿蒙包括,OTDR 测试
- LoadRunner压力测试:测试报告
- 技术评审之技术文档的规范模板
- 看球二三事 - 世界杯征文
- 快速识别无效数据(数据有效性/数据验证)
- 身份管理的15个安全开发实践
- simulink他励直流电动机串电阻启动仿真
- 木马免杀原理及方法(超全)
- .Net混淆工具和反混淆工具
- 关于项目外包的一些总结
- mysql存储csv文件_MySQL 查询结果保存为CSV文件
热门文章
- 老赖凭本事骗钱,你有本事不被骗吗?
- 今年美国广告程序化购买支出将超252亿美元
- 为什么JavaScript现在和将来都是编程语言首选?
- 转载:谢谢原作者: 块设备驱动实战基础篇二 (继续完善170行过滤驱动代码至200行)
- MyBatis-06 MyBatis XML方式之多个接口参数用法
- Java-Java I/O流解读之java.io.PrintStream java.io.PrintWriter
- Android日期分组,按查询分组在列表视图android中显示一些意...
- linux检查是否安装proc编译器,编译安装 GCC 4.9并验证使用
- java.lang.InstantiationException 不能实例化某个对象
- android唤醒前台,Android将后台应用唤起到前台的方法 (SDK 4.0, ActivityLifecycleCallbacks)...