1. 封装、IS-A、HAS-A
(1) 封装的目的是隐藏接口(或API)背后的实现
(2) 被封装的代码具有两个特性:a.使实例变量称为受保护的(通常用private修饰符)b. Getter方法和setter方法提供对实例变量的访问
(3) IS-A指继承或实现
(4) IS-A用关键字extends表达
(5) “IS-A”、”继承自”以及”是······的一个子类型”都是等价的表达方式
(6) HAS-A指一个类实例”具有”对另一个实例的引用,或者”具有”同一个类的另一个实例的引用
2. 继承
(1) 继承允许类成为一个超类的子类,从而继承该超类公共的和保护的变量及方法
(2) 继承是支持IS-A、多态性、重写、重载和强制转换的关键概念
(3) 所有的类(除Object类之外)都是Object类型的子类,因而它们继承Object的方法
3. 多态性
(1) 多态性意指”多种形式”
(2) 引用变量总是单一、不可变的类型,但是它可以引用子类型对象
(3) 单一对象可以被许多不同类型的引用变量引用,只要它们具有对象的相同类型或者子类型
(4) 引用变量的类型(而不是对象的类型)决定了可以调用哪些方法
(5) 多态的方法调用仅适用于被重写的实例方法
4. 重写和重载
(1) 可以重写或重载方法。构造函数可以重载,但不能重写
(2) 第一个具体(非抽象)子类必须重写抽象方法
(3) 与原方法相比,重写方法:
a. 必须具有相同的变元列表
b. 必须具有相同的返回类型。但从JAVA5起,返回类型可以是子类型—这称为协变式返回
c. 一定不能有限制性更强的访问修饰符
d. 可以有限制性更弱的访问修饰符
e. 一定不能抛出新的或更广的检验异常
f. 可以抛出更少或更窄的检验异常,或者任何非检验异常
(4) 不能重写final方法
(5) 只有继承的方法才可以被重写,并且私有方法不能被继承
(6) 子类使用super.overriddenMethodName()调用重写方法的超类版本
(7) 重载意味着复用相同的方法名称,但是具有不同的变元
(8) 重载方法:
a. 必须有不同的变元列表
b. 可以有不同 的返回类型,但是变元列表也必须是不同的
c. 可以有不同的访问修饰符
d. 可以抛出不同的异常
(9) 来自超类的方法在子类中可以重载
(10) 多态性适用于重写而不是重载
(11) 对象类型(不是引用变量的类型)决定在运行时使用哪个重写方法
(12) 引用类型决定了在编译时使用哪个重载方法
5. 引用变量强制转换
(1) 引用变量强制转换有两类:向下强制转换和向上强制转换
(2) 向下强制转换:如果具有引用子类型对象的引用变量,则可以赋予它一个子类型的引用变量。必须执行显示强制转换来完成这项工作,其结果是:可以使用这个新的变量引用来访问子类型的成员
(3) 向上强制转换:可以显示或隐式地赋予引用变量一个超类型的引用变量。这是一个天生安全的操作,因为赋值限制了新变量的访问能力
6. 实现接口
(1) 当实现一个接口时,就是在履行一份契约
(2) 通过正确地、具体地重写接口定义的所有方法,就可以实现一个接口
(3) 一个类可以实现多个接口
7. 返回类型
(1) 重载方法能够改变返回类型。但是除协变式返回的情况,重写方法不能改变返回类型
(2) 对象引用返回类型可以接受null作为返回值
(3) 对于声明和作为一个值返回来说,数组都是一种合法的返回类型。
(4) 对于带基本返回类型的方法,可以返回能够隐式转换为返回类型的任何值
(5) 不能从void返回任何值,但是可以什么也不返回。允许在具有void返回类型的任何方法内只写一条return语句,返回到以前的方法。但是,不能让一个具有非void返回类型的方法什么也不返回
(6) 对于具有对象引用返回类型的方法,可以返回这种类型的子类型
(7) 对于具有接口返回类型的方法,可以返回该接口的任何实现
8. 构造函数和实例化
(1) 当创建一个新对象时,总是需要调用构造函数
(2) 对象继承树中的每个超类都将有一个构造函数调用
(3) 每个类(即使是抽象类)都至少有一个构造函数
(4) 构造函数必须具有与其类相同的名称
(5) 构造函数一定不能有返回类型。如果看到代码具有返回类型,则它就是一个方法而不是构造函数,只不过是具有与类相同的名称
(6) 典型的构造函数执行方式如下:
a. 构造函数调用其超类的构造函数,超类构造函数又调用其超类的构造函数,如此继续,直至到达Object构造函数为止
b. Object构造函数执行,然后返回到调用构造函数,它运行完成后返回到它的调用构造函数,如此继续,直至所创建实际实例的构造函数完成为止
(7) 构造函数能够使用任何访问修饰符,包括private
(8) 如果在类中没有创建任何构造函数,则编译器将创建一个默认构造函数
(9) 默认构造函数是一个无变元构造函数,它带有对super()的无变元调用
(10) 每个构造函数中的第一条语句必须调用this()(一个重载构造函数)或super()
(11) 没有没有调用super(),则编译器将添加它,除非已经插入了对this()或super()的调用
(12) 只有在运行超类构造函数之后才可以访问实例成员
(13) 抽象类具有的构造函数在实例化具体子类时被调用
(14) 接口没有构造函数
(15) 如果超类没有无变元构造函数,则必须创建构造函数,并插入带变元的super()调用,这些变元要与超类构造函数的那些变元匹配
(16) 构造函数永远不会被继承,因此不能重写它们
(17) 构造函数只能由另一个构造函数直接调用[使用对super()或this()的调用]
(18) 调用this()的问题:
a. 只可以作为构造函数内的第一条语句出现
b. 变元列表决定了调用哪个重载构造函数
(19) 构造函数能够调用构造函数,并且可以如此循环下去,但它们中的一个迟早要调用super(),否则将膨胀到爆炸
(20) 对this()和super()的调用不能位于同一个构造函数内。构造函数内只能有其中之一,不能二者兼有。
9. 静态成员
(1) 使用静态方法实现的行为不受任何实例状态的影响
(2) 使用静态变量保存类特有的数据,而不是实例特有的数据—静态变量只有一份副本
(3) 所有的静态成员都属于类,而不属于任何实例
(4) 静态方法不能直接访问实例变量
(5) 使用点运算符访问静态成员,但使用带点运算符的引用变量确实是一种语法技巧,编译器将用引用变量的类名称代替它。例如:d.doStuff()会变成:Dog.doStuff();
(6) 不能重写静态方法,但是可以重新定义
10. 耦合与内聚
(1) 耦合指一个类了解或使用另一个类成员的程度
(2) 松耦合是一种理想状态,它具有良好封装的类,将相互间的引用减至最少,并限制了API使用的幅度
(3) 紧耦合不是一种理想状态,它具有破坏松耦合规则的类
(4) 内聚是指类具有单一的、良好定义的角色或职责的程度
(5) 高内聚是一种理想状态,其中类的成员支持单一的、明确的角色或职责
(6) 低内聚不是一种理想状态,其中类的成员支持多种、不明确的角色或职责