【HIT软件构造第四章复习】


本章:
软件构造的理论基础—ADT
软件构造的技术基础–OOP

在编程语言中的数据类型

变量:用特定数据类型定义,可存储满足类型约束的值
数据类型分成:基本数据类型和对象数据类型
在这里插入图片描述
将基本类型包装为变量类型
Boolen integer short long character float double

  1. 通常是定义集合类型的时候使用他们
  2. 一般情况下,尽量避免使用
  3. 一般可以自动切换

静态/动态类型检查

静态类型语言:所有变量的类型在编译时(在程序运行之前)是已知的,因此编译器也可以推断所有表达式的类型。
动态类型语言:在运行阶段进行类型检查
静态类型检查>>动态>>无检查
静态类型检查:可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性/健壮性
静态类型检查可以检查:语法错误、类名/函数名错误、参数数目错误、参数类型错误、返回值类型错误
动态类型检查可以检查:非法的参数值、非法的返回值、越界(对字符串使用负数或太大的索引)、空指针

静态检查:关于“类型”的检查,不考虑值
动态检查:关于“值”的检查

易变性和不变性

赋值:在计算机中,赋值是最拿难得问题之一,它相当于将一个计算结果放到一个存贮空间中,是一个存储过程
改变一个变量和改变一个变量的值的区别?
改变一个变量:将该变量指向另一个值的存储空间
改变一个变量的值:将该变量当前指向的值的存储空间中写入一个新的值
尽可能避免变化,以避免副作用

不变性

不变性:重要的设计原则
不变数据类型:一旦被创建,其值不能改变
如果是引用类型(指针),也可以是不变的;一旦确定其指向的对象,不能再被改变
如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分
所以尽量使用final变量作为方法的输入参数、局部变量。Final表明了程序员的一种“设计决策”
注意:
final无法派生子类
final变量无法改变值/引用
final方法无法被子类重写
被分配一次而从不重新分配的变量。要使引用不可变,请使用关键字final声明它

不变对象:一旦被创建,始终指向同一个值/引用
可变对象:拥有方法可以修改自己的值/引用
(string就是一个不可变类型的实例,一个字符串对象总是表示相同的字符串)
(StringBuild就是一个可变类型的例子,它有删除字符串的某些部分、插入或替换字符等的方法。此类具有更改对象值的方法,而不仅仅是返回新值)

两者有区别吗?最终的值都是一样的
当只有一个引用指向该值,没有区别
有多个引用的时候,差异就出现了
在这里插入图片描述
使用不可变类型,对其频繁修改会产生大量的临时拷贝(需要垃圾回收)
可变类型最少化拷贝以提高效率
使用可变数据类型,可获得更好的性能,也适合于多个模块之间共享数据(相当于全局变量)但是也具有全局变量的缺点

既然如此还要使用不可变类型的原因?
不可变类型更安全,在其他质量指标上面表现更好(可变性使您更难理解程序在做什么,也更难执行契约)

不应该使用Data类型

通过防御式拷贝,给客户端返回一个全新的Data对象。大部分时候该拷贝不会被客户端修改,可能会造成大量的内存浪费。如果使用不可变类型,则节省了频繁复制的代价。不变性可以比突变性更有效,因为不可变类型永远不需要防御式复制。

如何安全的使用可变类型:局部类型,不会涉及共享;只有一个引用
如果有多个引用(别名),使用可变类型就非常不安全

快照图

快照图作为代码级、运行时视图和力矩视图
用于描述程序运行时的内部状态
使用快照图的原因:

  1. 便于程序员间的交流
  2. 便于刻画各类变量随时间的变化
  3. 便于解释设计思路

不可变的引用:
用双箭头引用是不可变的,但指向的值确是可以变的
可变的引用,也可指向不同的值

我们存在一个对可变值的不可变的引用
如:final stringbuilder sb
在这里插入图片描述
我们还可以对一个不可变值进行可变引用,其中变量的值可以改变
类似string用list存储
在这里插入图片描述

复杂的数据类型:数组和集合

列表:
列表是一个接口
列表中的成员必须是一个对象
Set
S1.contains 测试该集合中是否包含一个元素
S1.containsAll(s2)测试是否s1包含s2
S1.removeAll(s2) remove s2 from s1
Map类似字典:键-值
– map.put(key, val) add the mapping key → val
– map.get(key) get the value for a key
– map.containsKey(key) test whether the map has a key
– map.remove(key) delete a mapping
在这里插入图片描述

使用Java集合,我们可以限制集合中包含的对象的类型
当我们添加项时,编译器可以执行静态检查,以确保我们只添加适当类型的项
然后,当我们取出一件物品时,我们可以确保它的类型是我们所期望的

我们不能创建一个基本类型的集合
例如:set<int>does not work
但是int有一个整数包装器,我们可以使用(eg.set<integer>numbers)

迭代器是一个可变类型
迭代器是一个逐步遍历元素集合并逐个返回元素的对象
Next()是可变的
hasNext()测试迭代器是否达到集合的结束

有用的不可变类型

基本类型及其封装对象类型都是不可变的。

围绕可变数据类型周围的不可变包装器
这种包装器得到的结果是不可变的:只能看
但是这种“不可变”是在运行阶段获得来的,编译阶段无法据此进行静态检查
Collections.unmodifiableList是构造一个不能修改的List
Arrays.asList()是个坑
在java语言中,把数组转换成List集合,有个很方便的方法就是 List list=Arrays.asLis t(“a”,“b”,“c”);
但你可能不知道这样得到的List它的长度是不能改变的。当你向这个List添加或删除一个元素时(例如 list.add(“d”);)程序就会抛出异常

不可修改的包装
不可修改的包装器通过拦截所有将修改集合的操作,并抛出一个不受支持的操作异常,从而剥夺了修改集合的能力。
不可修改的包装器有两个主要用途
如下:
-在集合构建后使其不可变。在这种情况下,最好不维护对备份集合的引用。这绝对保证了不变性。
–允许某些客户端只读访问您的数据结构。您保留对备份集合的引用,但分发对包装器的引用。通过这种方式,客户端可以查看但不能修改,同时您保持完全访问。
在这里插入图片描述

针对不可修改的集合的静态方法

要从某些已知值创建不可变集合,请使用List.of、Set.of和Map.of。
List a = List.of(“lion”, “tiger”, “bear”);
或者,使用List.copyOf(Java10)来创建不可修改的可变集合的浅层副本

用Snapshot图理解数据理解

用集合类表达复杂数据类型

总结

静态类型检验

  1. Safe from bugs静态检查通过在运行时捕获类型错误和其他bug,有助于安全。
  2. 易于理解。它有助于理解,因为类型在代码中显式地表示出来了。
  3. 已准备好更改。静态检查通过识别其他需要串联更改的地方,使更改代码更容易。
    例如,当您更改变量的名称或类型时,编译器会立即在使用该变量的所有地方显示错误,并提醒您同时更新它们。

可变性对性能和方便很有用,但它也会产生错误的风险,因为他要求使用对象的代码在全局级别上保持良好。
理解不可变对象(string)和不可变引用量(final)之间的区别
在快照图中,对象是值,在快照图中用圆圈表示,,不可变对象有一个双边框,表示它从不更改其值
引用时指向对象的指针,不可变引用时带有双箭头的箭头,表示箭头不能移动到其他对象

关键的设计原则是不可变:尽可能多地使用不可变对象和不可变引用

  1. Safe from bugs 不可变对象不容易受到由混叠引起的bug的影响。不可变引用总是指向同一对象。
  2. 易于理解。因为一个不可变的对象或引用总是意味着相同的东西,所以对于代码的读者来说,推理更简单——他们不必跟踪所有的代码来找到对象或引用可能被更改的所有地方,因为它不能被更改。
  3. 已准备好更改。如果一个对象或引用不能在运行时被更改,那么当程序发生更改时,就不必修改依赖于该对象或引用的代码了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值