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

    技术2025-09-17  10

    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。 ④修饰符修饰的是“被访问”的权限。

    Processed: 0.011, SQL: 9