一、抽象数据类型(ADT)
1.定义:抽象数据类型(Abstract Data Type,ADT)是计算机科学中具有类似行为的特定类别的数据结构的数学模型;或者具有类似语义的一种或多种程序设计语言的数据类型。抽象数据类型是间接定义的,通过其上的可执行的操作以及这些操作的效果的数学约束(与可能的代价)。
2.一个抽象数据类型定义了:一个数据对象、数据对象中各数据元素之间的关系及对数据元素的操作
3.意义:抽象数据类型体现了程序设计中问题分解、抽象和信息隐藏的特性。抽象数据类型把实际生活中的问题分解为多个规模小且容易处理的问题,然后建立一个计算机能处理的数据模型,并把每个功能模块的实现细节作为一个独立的单元,从而使具体实现过程隐藏起来
二、面向对象编程(OOP)
1、概念:面向对象的编程方法/语言应该具有类的概念作为中心概念。语言应该能够为类和它的特征提供断言(即规范:前置条件,后置条件和不变量)和异常处理,依靠工具生成这些断言中的文档,并且可选地在运行时监视它们 时间。
2、OOP特征分别是封装、继承、多态:
封装:封装是指将对象信息状态通过访问权限修饰符隐藏在对象内部,不允许外部程序直接访问,如果外部程序要访问对象内部,可以调用内部提供的get或set方法。
继承:子类继承了父类所有的成员方法和属性,并且可以拥有自己特性。继承解决了代码的重用问题
多态:父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。
3、核心概念:
①静态类型:一个定义良好的类型系统应该通过强制执行一些类型声明和兼容性规则来保证它接受的系统的运行时类型安全。
②泛型(Genericity):用于“准备改变”和“为/重用设计”:应该可以编写具有表示任意类型的正式泛型参数的类。
③继承(Inheritance):应该可以将一个类定义为从另一个继承,以控制潜在的复杂性。
④多态(Polymorphism):在基于继承的类型系统的控制下,应该可以将实体(表示运行时对象的软件文本中的名称)附加到各种可能类型的运行时对象。
⑤动态分派/绑定(Dynamic dispatch / binding):在一个实体上调用一个特性应该总是触发与所附加的运行时对象的类型相对应的特性,这在调用的不同执行过程中不一定是相同的。
三、ADT与OOP
(一)基本数据类型和对象引用数据类型
基础数据类型 | 对象引用类型 |
---|---|
int, long, byte, short, char,float, double, boolean | Classes, interfaces, arrays, enums,annotations |
只有值,没有ID | 既有ID,也有值 |
Immutable 不可变的 | Some mutable, some not 可变/不可变 |
On stack, exist only when in use 在栈中分配内存 | On heap, garbage collected 在堆中分配内存 |
无法实现表达的统一 | Unity of expression with generics |
代价低 | 代价昂贵 |
(二)可变性和不可变性
改变一个变量:将该变量指向另一个值的存储空间。
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值。
重要设计原则:不变性,变化是“罪恶”,但程序不能没有变化,尽可能避免变化,以避免副作用
不变数据类型:一旦被创建,其值不能改变
如果是引用类型,也可以是不变的:一旦确定其指向的对象,不能再被改变指向其他对象
(三)复杂数据类型
1.迭代器
迭代器是一个对象,它遍历一组元素并逐个返回元素 ,for(…:…)形式的遍历,调用的是被遍历对象所实现的迭代器
迭代器(iterator)的两个方法:
next() returns the next element in the collection — this is a mutator method!
hasNext() tests whether the iterator has reached the end of the collection
2.空引用的危害
-
在Java中,对对象和数组的引用也可以接受特殊值Null,这意味着该引用不指向对象。空值是Java类型系统中一个不幸的漏洞。
-
基本数据类型不能为空,编译器将拒绝这样的带有静态错误的尝试:
-
int size = null; //illegal
-
无法调用任何方法或使用具有这些引用之一的任何字段(抛出Null指针异常)
-
null与空字符串“”或空数组不相同
-
在参数和返回值中隐式地不允许使用空值。如果一个方法允许一个参数的空值,它应该显式地声明它,或者如果它可能因此返回一个空值,它应该显式地声明它。但这些通常都不是什么好主意。避免设置为空。