类
1. 基本概念
- 由类构造对象的过程成为创建类的实例
- 对象:类的一个实例
实例域:对象中的数据
方法:操纵数据的过程 - 隐式参数:调用方法的对象在类的方法中使用了类的实例域,这个被调用的实例域就是隐式参数。
显示参数:方法名括号中的参数,即看得见的参数。 - 类之间的关系:
依赖(uses - a):一个类的方法操纵另一个类的对象
聚合(has - a):一个类的对象包含另一个类的对象
继承(is - a):一个类包含另一个类的方法 - 对象的行为:可以对对象施加哪些方法
同一个类的所有对象实例,由于支持相同的行为而具有家族式的相似性。对象的行为是用可调用的方法定义的。 - 对象的状态:每个对象保存着的描述当前特征的信息,有时对象的状态会影响对象的行为。
对象状态的改变必须用过调用方法实现,否则封装性就遭到了破坏。
2. 封装
- 类的方法不应该返回引用可变对象,因为这样在操作这个对象时,这个对象所指向的还是类的实例域,因此破坏了封装性;如果要返回应该首先对它进行clone再返回克隆值。
- 对于一个对象的隐式参数,可以使用this标记,以区分局部变量
- 一个类的方法可以访问这个类的任何一个对象的私有域
- 对于一个私有方法,由于它不会被外部其他类调用,所以可以任意改动,但公有类不能随意改动。
3. 对象构造
- 默认域初始化,若构造时没有初始化,则数值默认为0,布尔值默认false,对象引用默认为null。
- 只有当类中没有提供任何构造器时系统才会提供默认构造器,否则就必须自己提供一个默认构造器
- 重载:不能有两个名字和参数相同,但返回类型不同的方法
- 对象与对象变量不是一个概念,定义一个对象变量时,它既不是一个对象,也没有引用任何对象,它既可以用新构造的对象(new+构造器)初始化,也可以用已存在的对象初始化。在没有初始化时可以显式地把对象变量置为null。所有对象都存储在堆中,如果把一个变量赋值给另一个,则这两个变量指向同一个对象。
在 Java 中, 任何对象变量的值都是对存储在另外一个地方的一个对象的引用 。 new 操作符的返回值也是一个引用。
4. 域
域,也称成员变量,体现了对象的状态,而状态的改变由类体的方法实现。
修饰符:
-
private static:
将域定义为static说明这个域是属于类的,也称为类域(静态域),即所有对象共享这一个域,它属于类,而不属于任何一个对象。它的初始化应该通过静态初始化器来实现。(由static和一对大括号组成)静态初始化在所属类被加载到内存中时进行。 -
final:
将实例域定义为final说明在构建对象时(即调用构造器时)必须初始化这样的域,并且之后不能再修改它。final修饰符大都应用于基本类型域,或不可变类型域(例如String,即类中的每个方法都不能改变其 对象) -
public static final:
虽然实例域应设为私有,但由于有final修饰,不能修改,所以没有问题。(由于final域固定不变,为了节省空间,一般用static修饰)
5. 方法
public static:
静态方法,即没有隐式参数,或只需要访问类的静态域的方法的方法,一般应由类而不是对象调用- 工厂方法
main:
也是静态方法,不需要使用对象调用,可以用于单元测试- java的方法参数是传值调用的,不会改变传入的参数,即使传入的参数是对象引用,也会对该引用值(即实际对象的地址)进行拷贝,如果想要改变这个引用所指向的对象,那么不会改变,但可以改变所指对象的内容。
接口
概念:主要用来描述类有什么功能,而并不给出每个功能的具体实现。一个类可以实现一个或多个接口
- 接口不是类,而是对类的一组需求描述,这些类要遵从接口描述的统一格式进行定义
- 接口中的所有方法自动地属于public,因此在接口声明方法时不必提供关键字,但在类实现时必须提供
- 接口中可以定义常量,但绝不能含有实例域,提供实例域和方法实现的任务应该由实现接口的那个类来完成
- 为了让类实现一个接口 , 通常需要下面两个步骤 :
1 ) 将类声明为实现给定的接口
2 ) 对接口中的所有方法进行定义
接口的特性
- 不能用new运算符实例化一个接口:
x = new Comparable() // ERROER
- 但可以声明接口变量:
Comparable x; // OK
- 接口变量必须引用实现了接口的类对象
x = new Employee(); // OK
- 可以使用instanceof检查对象是否实现某个接口:
if ( anObject instanceof Comparable ) { . . . }
- 接口可以被扩展
- 接口中不能包含实例域或静态方法,但却可以包含常量,接口中的域被自动设为public static final
- 每个类可以实现多个接口,只要用逗号分隔即可,但只能扩展于一个类
静态方法和默认方法
- 通常将静态方法放在伴随类中,例如Collection / Collections 或 Path / Paths(成对的接口和实用工具类),但在实现自己的接口时可以直接将实现放在接口中
- 可以为接口方法提供一个默认实现,但经常是每一个实现都要覆盖这个方法。若默认方法冲突,则:
1 ) 超类优先。 如果超类提供了一个具体方法 , 同名而且有相同参数类型的默认方法会被忽略。
2 ) 接口冲突 。 如果一个超接口提供了一个默认方法, 另一个接口提供了一个同名而且参数类型 ( 不论是否是默认参数 ) 相同的方法 , 必须覆盖这个方法来解决冲突。
接口默认方法冲突
来源:《Java 核心技术》