抽象数据类型+面向对象编程基础

1.基本数据类型、引用数据类型

抽象数据类型+面向对象编程基础
基本数据类型
抽象数据类型+面向对象编程基础
1、在基本数据类型中,除了boolean类型所占长度与平台有关外,其他数据类型长度都是与平台无关的。比如,int永远占4个字节(1 Byte = 8 bit)。

2、void不是基本数据类型

3、基本数据类型的默认值仅在作为类中属性时生效,在方法内部必须先对基本数据类型变量赋值后才能使用,否则编译不通过。

引用数据类型

引用类型(reference type)指向一个对象,不是原始值,指向对象的变量是引用变量。

在java里面除去基本数据类型的其它类型都是引用数据类型,自己定义的class类都是引用类型,可以像基本类型一样使用。

引用类型常见的有:String,StringBuffer,ArrayList,HashSet,HashMap等。
如果要对比两个对象是否相同,则需要使用equals()方法,但有一点需要注意:equals()方法的默认行为是比较引用。如果是你自己写的类,你应该为它重写equals()来比较对象的内容。大多数Java类库都实现了比较对象内容的equals()方法。

两者比较
抽象数据类型+面向对象编程基础

2.类型检查

静态类型检查:编译时可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性/健壮性

关于“类型”的检查,不考虑值

①语法错误

②类名、函数名错误

③参数数目错误

④参数类型错误

⑤返回值类型错误

⑥其他情况,如变量可能没有初始化,在一些条件分支里声明的变量无法在分支外使用等等

动态类型检查:运行时

关于“值”的检查

①非法的参数值,如除零错误

②非法的返回值,如返回的具体值不能被转换成对应的类型

③越界

④空指针

3.可变对象、不可变对象、final关键字

不变对象:

如String,一旦被创建,始终指向同一个值/引用。如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分。

不提供可改变其内部数据的值的操作。

可变对象:

如StringBuilder,拥有方法可以修改自己的值/引用。

提供了可改变其内部数据的值的操作。

比较:

①使用不可变类型,对其频繁修改会产生大量的临时拷贝(需要垃圾回收) ,使用可变类型会减少拷贝

②使用可变数据类型,可以提高性能,方便在多个模块之间共享数据。

③使用不可变数据类型,更容易达到安全要求。

final关键字:

①修饰类当用final去修饰一个类的时候,表示这个类不能被继承。

注意:

a. 被final修饰的类,final类中的成员变量可以根据自己的实际需要设计为fianl。

b. final类中的成员方法都会被隐式的指定为final方法。

②被final修饰的方法不能被重写。

注意:

a. 一个类的private方法会隐式的被指定为final方法。

b. 如果父类中有final修饰的方法,那么子类不能去重写。

③修饰局部变量

注意:

a. 必须要赋初始值,而且是只能初始化一次。

④修饰成员变量

注意:

a. 必须初始化值。

b. 被fianl修饰的成员变量赋值,有两种方式:1、直接赋值 2、全部在构造方法中赋初值。

c. 如果修饰的成员变量是基本类型,则表示这个变量的值不能改变。

d. 如果修饰的成员变量是一个引用类型,则是说这个引用的地址的值不能修改,但是这个引用所指向的对象里面的内容还是可以改变

4.防御式拷贝

返回可变类型对象时,为了防止该对象在别处被修改,创建一个新的对象,并复制原来的对象的各项属性,并返回这个复制后的新对象。

5.snapshot diagram

①基本类型的值
抽象数据类型+面向对象编程基础
②对象类型的值
抽象数据类型+面向对象编程基础
③不可变对象:双线椭圆
抽象数据类型+面向对象编程基础
④可变对象
抽象数据类型+面向对象编程基础
⑤不可变的引用:双线箭头
抽象数据类型+面向对象编程基础

6.spec、precondition、postcondition

spec:

写在方法之前,只讨论输入输出的数据类型、功能和正确性、性能等,不讨论具体实现

应该包含前置条件、后置条件、和函数期望完成的行为。

@param 输入参数的含义

@return 返回参数的含义

@throws 抛出异常的含义

前置条件:

对客户端的约束,在使用方法时必须满足的条件

后置条件:

对开发者的约束,方法结束时必须满足的条件

前置条件满足,则后置条件必须满足。

前置条件不满足,则方法可做任何事情。

在涉及到可变类型等情况时,不要只依靠客户端和开发者的行为,要在规约里限定住。

7.行为等价性

定义:两个函数是否可相互替换?

①单纯的看实现代码,并不足以判定不同的implmentation是否是“行为等价的”

②需要根据spec判定行为等价性

③在编写代码之前先要确定spec如何形成、撰写。

8.spec强度

spec变强:更放松的前置条件,更严格的后置条件。

意味着实现更难,使用更轻松。

spec强的函数可以替换spec弱的。

9.ADT的四种基本操作

①构造器:t* -> T

创建对象,可能为静态函数或构造函数

②变值器:T+,t* -> void|t|T

通常返回void,但改变了内部的某些状态。

也可能返回非空类型。

③观察器:T+,t* -> t

返回内部某些状态

④生产器:T+,t* -> T

从旧对象中构建新对象。

10.表示独立性

内部实现如何变化,不影响客户端使用,也不影响规约。

如果没写前置、后置条件,就不能改变内部表示。

11.AF、RI

RI:

不变量,程序的某种“特性”,这种特性无论在什么时候都需要成立。

表示不变量,表示空间集合中的一个子集,包含了所有合法的表示值,或者说对于合法表示的描述。

和客户端无关,由ADT自身负责维持不变量。

如果出现了表示泄露,就不能保证不变量,也不能保证独立性。

ADT要保证不变性、不产生表示泄露。

checkRep()表示检查表示不变量的函数,要保证ADT的四个操作都要执行这个检查函数,并且在"null"的情况下不能通过检查。

R:表示空间,实际存入ADT中真实的值

A:抽象空间,使用ADT的客户端看到和使用的值。

AF:R→A的一个映射关系,是R中的值在A中的解释。

这个映射是满射,但未必是单射、双射,并且R中的一些值可能是非法的,在A中无对应。

同样的R、RI,但可能有不同的AF,即解释不同。
抽象数据类型+面向对象编程基础
抽象数据类型+面向对象编程基础

12.表示泄露

把R空间的东西泄露给了客户端

一旦泄露(将引用传递到客户端),内部表示可能被意外更改,无法保证RI

13.接口、抽象类、类

抽象数据类型+面向对象编程基础
抽象数据类型+面向对象编程基础
抽象数据类型+面向对象编程基础
抽象数据类型+面向对象编程基础

14.访问控制符:public,protected,default,private

①私有权限 private
private可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类)。被private修饰的成员,只能在定义它们的类中使用,在 其他类中不能调用。
②默认权限 (default)
类,数据成员,构造方法,方法成员,都能够使用默认权限,即不写任何关键字。默认权限即同包权限,同包权限的元素只能在定义它们的类中,以及同包 的类中被调用。
③受保护权限protected
protected可以修饰数据成员,构造方法,方法成员,不能修饰类(此处指外部类,不考虑内部类)。被protected修饰的成员,能在定义它们的类中,同包(最后一次重写该函数的位置)的类中被调用。如果有不同包的类想调用它们,那么这个类必须是定义它们的类的子孙类。
④公共权限 public
public可以修饰类,数据成员,构造方法,方法成员。被public修饰的成员 ,可以在任何一个类中被调用,不管同包或不同包,是权限最大的一个修饰符。

有关Java语言的修饰符,需要注意的问题有如下几个:
①并不是每个修饰符都可以修饰类(指外部类),只有public和default可 以。
②所有修饰符都可以修饰数据成员,方法成员,构造方法。
③为了代码安全起见,修饰符不要尽量使用权限大的,而是适用即可。比如 ,数据成员,如果没有特殊需要,尽可能用private。
④修饰符修饰的是“被访问”的权限。