第二章 面向对象

1.  封装、IS-AHAS-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)     低内聚不是一种理想状态,其中类的成员支持多种、不明确的角色或职责

你可能感兴趣的:(F#)