内部类和嵌套类:
在另一个类中定义的类就是嵌套类(nested classes)。嵌套类的范围由装入它的类的范围限制。这样,如果类B被定义在类A之内,那么B为A所知,然而不被A的外面所知。嵌套类可以访问嵌套它的类的成员,包括private成员。但是,包围类不能访问嵌套类的成员。
嵌套类一般有2种类型:前面加static标识符的和不加static标识符的。
一个static的嵌套类有static修饰符。因为它是static,所以只能通过对象来访问它包围类的成员。也就是说,它不能直接引用它包围类的成员。因为有这个限制,所以static嵌套类很少使用。
嵌套类最重要的类型是内部类(inner class)。内部类是非static的嵌套类。它可以访问它的外部类的所有变量和方法,它可以直接引用它们,就像外部类中的其他非static成员的功能一样。这样,一个内部类完全在它的包围类的范围之内
抽象类
有时希望创建一个只定义一个被它的所有子类共享的通用形式,由每个子类自己去填写细节。这样的类决定了子类所必须实现的方法的本性。
父类的方法本身不需要实现任何功能,仅仅是为了定义方法签名,目的是让子类去覆写它,那么,可以把父类的方法声明为抽象方法;
声明一个抽象方法的通用形式:
abstract type name(parameter-list);
任何含有一个或多个抽象方法的类都必须声明成抽象类。声明一个抽象类,只需在类声明开始时在关键字class前使用关键字abstract。抽象类没有对象。
一个抽象类不能通过new操作符直接实例化。这样的对象是无用的,因为抽象类是不完全定义的。而且,不能定义抽象构造函数或抽象静态方法。所有抽象类的子类都必须执行超类中的所有抽象方法或者是它自己也声明成abstract;
接口
在抽象类中,抽象方法本质上是定义接口规范:即规定高层类的接口,从而保证所有子类都有相同的接口实现;如果一个抽象类没有字段,所有方法全部都是抽象方法,就可以把该抽象类改写为接口;
接口声明
接口的通用形式:
access interface name {
return-type method-name1(parameter-list);
return-type method-name2(parameter-list);
type final-varname1 = value;
type final-varname2 = value;
// ...
return-type method-nameN(parameter-list);
type final-varnameN = value;
}
access要么是public,要么就没有用修饰符。当没有访问修饰符时,则是默认访问范围;
接口声明中可以声明变量。它们一般是final 和static型的,意思是它们的值不能通过实现类而改变。它们还必须以常量值初始化。如果接口本身定义成public ,所有方法和变量都是public的。
接口实现
一旦接口被定义,一个或多个类可以实现该接口。为实现一个接口,在类定义中包括implements 子句,然后创建接口定义的方法。
一个包括implements 子句的类的一般形式如下:
access class classname [extends superclass]
[implements interface [,interface...]] {
// class-body
}
这里,access要么是public的,要么是没有修饰符的。如果一个类实现多个接口,这些接口被逗号分隔。如果一个类实现两个声明了同样方法的接口,实现接口的方法必须声明成public。而且,实现方法的类型必须严格与接口定义中指定的类型相匹配。
如果一个类包含一个接口但是不完全实现接口定义的方法,那么该类必须定义成abstract类型-(局部实现)
接口继承
接口可以通过运用关键字extends被其他接口继承。语法与继承类是一样的。当一个类实现一个继承了另一个接口的接口时,它必须实现接口继承链表中定义的所有方法。
包package
Java提供了把类名空间划分为更多易管理的块的机制。这种机制就是包。包既是命名机制也是可见度控制机制。你可以在包内定义类,而且在包外的代码不能访问该类。
定义包
创建一个包是很简单的:只要包含一个package命令作为一个Java源文件的第一句就可以了。该文件中定义的任何类将属于指定的包。
package语句定义了一个存储类的名字空间。如果你省略package 语句,类名被输入一个默认的没有名称的包
package 声明的通用形式:pkg 是包名
package pkg;
一个多级包的声明的通用形式如下:每个包名与它的上层包名用点号“.”分隔开
package pkg1[.pkg2[.pkg3]];
在Java虚拟机执行的时候,JVM只看完整类名,因此,只要包名不同,类就不同
包作用域
类是Java的最小的抽象单元。因为类和包的相互影响,
Java将类成员的可见度分为四个种类:
- 相同包中的子类
- 相同包中的非子类
- 不同包中的子类
- 既不在相同包又不在相同子类中的类
要特别注意:包没有父子关系。java.util和java.util.zip是不同的包,两者没有任何继承关系。
三个访问控制符,private、public和protected,
| |Private成员 | 默认的成员 | Protected成员 | Public成员|
|--|--|--|--|--|
| 同一类中可见 |是 |是|是|是|
|同一个包中对子类可见 |否 |是|是|是|
|同一个包中对非子类可见 |否 |是|是|是|
| 不同包中对子类可见 |否|否|是|是|
|不同的包中对非子类可见|否 |否|否|是|
引入包:
Java包含了import语句来引入特定的类甚至是整个包。一旦被引入,类可以被直呼其名的引用。在程序中将要引用若干个类,那么用import 语句将会节省很多时间。
在Java源程序文件中,import语句紧接着package语句,它存
在于任何类定义之前
import声明的通用形式:
import pkg1[.pkg2].(classname|*);
pkg1是顶层包名,pkg2是在外部包中的用逗点(.)隔离的下级包名。
打包成为jar
可以把 package 组织的目录层级,以及各个目录下的所有文件(包括 .class 文件和其他文件)都打成一个jar文件;
jar包实际上就是一个zip格式的压缩文件,而jar包相当于目录。
jar包还可以包含一个特殊的 /META-INF/MANIFEST.MF 文件, MANIFEST.MF 是纯文本,可以指定 Main-Class 和其它信息。JVM会自动读取这个 MANIFEST.MF 文件,如果存在 Main-Class ,可以直接运行jar
java -jar *.jar