《JAVA编程思想(第四版)》第六章(访问权限控制)小结

控制对成员的访问权限有两个原因.

第一,为了使用户不要碰触那些他们不该碰触的部分,这些部分对于类内部的操作时必要的,但是他并不属于客户端程序员所需接口的一部分.因此,将方法和域指定称private,对客户端程序员而言是一种服务.

第二.为了让类库设计者可以更改类的内部工作方式,而不必担心这样会对客户端程序员产生重大的影响.

tip:访问权限控制专注于类库创建者和该类库的外部使用者之间的关系,这种关系是一种通信方式

访问控制(或隐藏具体实现)与"最初的实现并不恰当"有关.换句话说就是:"我们的代码几乎不可能在一开始就做到最好,后期的迭代可以逐步改善情况,访问控制很大情况下就是为了后续代码的改善".

因为如果别的程序员可以随意调用你的代码中的任何东西.

想象一下,你正在写一个方法a(),你只想让其他人调用a()

void a(){

    b();

    c();

}
void b(){}
void c(){}

而有一个程序员在他认为可以的情况下调用了你的c(),

而后来你发现,c()与b()方法有更好的e()方法实现,于是你删掉了c(),改变了a();并且认为这个改动不会对调用a()的人产生影响.

void a(){

    e();

}
void e(){}

此时,调用c()的代码就会遇到大麻烦了.

诸如此类的情况很多,有很多情况下,我不想让调用a()的人看到我拥有b(),c(),d(),以及一些变量,

比如Java中String的内部char[],他不希望你调用这个,你只用调用他提供好的方法就可以了,而随着算法的改进,对于客户端程序员只收到代价的降低,而不需要改进任何代码.

这就是Java提出来的访问权限:

public > protected > 包访问权限(没有关键字) > private.(公开性由高到底).

权限名称

public

protected

default

private

对应权限

无论是谁无论在哪里,都可以访问该成员 继承类,同一包下,可以访问到. 只有同一包下可以访问

不允许其他类访问

包内有一组类,他们在单一的名字空间下呗组织在一起.

我们可以通过

import java.util.ArrayList;

导入在java包下的util包中的ArrayList.java文件.使这行语句所在的类可以使用其提供的方法和变量.

java.util.ArrayList aList = new java.util.ArrayList();//也是合法的.

package语句必须是文件中除注释以外的第一句程序代码.

package access; //必须是第一行程序代码

Java包的命名规则全部使用小写字母,包括中间的字也是.(曾有部分大写,现在已经全部规定为小写.)

package package.method.access; //必须全部是.

package和import关键字允许你做的,是将单一的全局名字空间分隔开,使得无论多少人使用Internet以及Java开始编写类,都不会出现名称冲突问题.

为了不出现类名,我们自己写的代码应该尽可能放在自己的包下,而为了保证不出现包名也冲突,所以使用一套独有的包命名规则:域名命名,

//假设我现在拥有域名:testpackage.com,
//那么我自己的包名为:
package com.testpackage.util;//util为我的名为util的类库,用来存放我的一些工具类.

访问权限的控制常被称为是具体实现的隐藏,把数据和方法包装在类中,以及具体实现的隐藏,常共同被称作为封装.其结果是一个同时带有特征和行为的数据类型.

  • 每个编译单元都必须有一个后缀名.java
  • 而在编译单元内则可以有一个public类
  • 该类的名称必须与文件的名称相同(包括大小写,但不包含后缀名.java)
  • 每个编译器最多只能用一个public 类,否则编译器就不会接受
  • 编译单元内完全不带public类也是可能的.此时可以随意对文件命名.(可能会付出debug的代价.)

对于某个类,只有 public 和包访问权限(default),不可以是 private 和 protected.

如果不想要他人生成该类,可以把所有的构造器都置为 private权限,从而阻止任何人创建该类的对象.但是有一个例外,就是你在该类的static成员内部可以创建.

package unit06_access.util.blog;

class Soup1 {
	private Soup1() {}

	public static Soup1 makeSoup() {
		return new Soup1();
	}
}
class Soup2 {
	private Soup2() {}
	private static Soup2 soup2 = new Soup2();
	public static Soup2 access() {
		return soup2;
	}

	public void f() {}
}

public class Lunch {
	void testPrivate() {
		// Soup1 soup1 = new Soup1();//编译器提醒:The constructor Soup1() is not visible
	}

	void testStatic() {
		Soup1 soup1 = Soup1.makeSoup();	//合法
	}
	void testSingleton() {
		Soup2.access().f();	//单例模式,始终只有soup2一个对象.
		
	}
}

猜你喜欢

转载自blog.csdn.net/m0_37961948/article/details/81236381