哈工大 软件构造 学习心得3

一、 ADT

ADT:抽象数据类型,强调作用于数据之上的操作,并不关心数据具体是怎么存储的。

ADT可以有4种操作:

①构造器creator,输入一些其它类型的对象,创建一个该ADT对象。

②生产器producer,通过该ADT的旧对象,创建一个该ADT的新对象。

③观察器observer,通过该ADT本身的数据以及传入参数,计算得到其它类型的值。

④变值器mutator,作出“修改ADT内部数据”的行为,是可变对象与不可变对象的本质区别。

注意非静态方法(构造函数除外) 的输入参数还会隐含一个当前对象!

二、 类与接口

接口:规定了ADT所需的未实现的操作。可同时实现多个接口。

不管具体实例是什么类型的,客户端都可以通过接口调用统一的操作,相当于接口将具体类实现的ADT操作开放给了客户端。

基于static的工厂方法:不希望客户端得知具体类名,但客户端需要创建实例对象。

突然想为ADT增加一个新的方法,但又不希望修改已经实现的具体类:在接口中实现default方法

接口中的方法原则上是不应该private的,毕竟接口要把类定义的方法公开给客户端,但Java9开始可以,不过必须在接口中给出具体实现。

一个接口可以通过extends继承另一个甚至多个接口的方法,但显然不能implements。

三、方法规约

规约是客户端与实现者之间签订的“契约”,客户端的输入应当满足前置条件,实现者编写的程序应当给出满足后置条件的结果。规约描述了方法的功能以及接口(“能做什么”),不需要依赖(也不应该透露)方法的具体实现。

如果客户端故意违反前置条件,那么方法也就不需要满足后置条件,理论上干什么都行。

规约图:更强的规约表示为更小的区域(因为满足它的方法更少)。

更强的规约:前置条件更弱,后置条件更强。

四、 AF、RI、rep

对于ADT,客户端是无法看到其内部表示属性(rep)的,客户端只会看到ADT在表面上展现出来的东西,即,ADT做了一个由表示空间(R)到抽象空间(A)的映射AF。

不是所有表示属性rep都能映射到相应的抽象值的(即有一些rep是非法的),那么任何时刻ADT的rep都必须满足一定规则(合法),即表示不变量RI。

ADT对数据做了特殊的 “解读”,实现了AF。

客户端可以看到ADT的操作方法及规约,可以看到抽象空间以及抽象值,但就是不能看到rep、RI以及 AF,它们涉及到客户端不应该知道的与内部实现有关的细节。

对于不可变类型,它的抽象值一定是不能变的,但表示值可以改变,前提是改变后通过AF仍然映射到相同的抽象值。

五、 表示独立性与表示泄露

表示独立性:客户端使用ADT时无需考虑(也不应该知道,更不应该直接访问到)其内部如何实现,ADT内部表示的变化不应影响外部spec和客户端。

如果ADT不幸地让客户端得到了自己内部表示(可变对象)的引用,那么客户端就可以不通过ADT的操作,而可以通过非法后门修改ADT的内部表示,产生表示泄露。

实现者应该以注释的形式声明如何避免表示泄露,最基本最起码的保护方式是用private修饰成员变量。

六、 继承与重写

一个类child可以继承另一个类father的全部方法与属性,在运行时存在继承关系的类型对象可以互相转换。子类型也可以重写(override)父类的方法,替换为自己的实现代码。

对于一个表面类型为父类的引用变量a,通过a.b()调用方法时,在运行时将会动态地检查a是否实际指向一个子类型对象,子类型是否重写了b()方法,如果是那么则调用子类型的重写方法。这一机制实现了子类型多态,即同样的a.b(),可能调用不同的方法。

编译器在静态检查的时候知道一个引用表面类型, 但该引用具体指向的对象到底是什么类型,编译器并不能知道。

七、 ADT的等价性与equals()

ADT的等价性是对于客户端角度而言的,要么,两个对象通过AF映射到相同的抽象值,要么,两个对象能做出效果相同的行为。不一定非得让rep完全一致。

equals()与==不是一回事,后者仅仅判断两个引用是否指向同一对象。如果不重写Object.equals(),那么默认效果和==是一样的。(观察等价性)

对于可变对象,除了上述的“观察等价性”,还会有一种“行为等价性”,如果两个对象这个时刻等价,那么不管之后干了什么,这两个可变对象仍然是等价的。(一般和==一样,当且仅当是同一对象,例如StringBuilder,我们常用的除它之外的类一般都是观察等价性,如String、List)

八、 hashCode

Object.hashCode()计算对象的哈希值,将对象映射为一个整数,使得等价的对象具有相同的哈希值。好的哈希算法应当使得不等价对象的哈希值尽量不同。

hashCode()一般用在基于哈希表的集合类中(HashMap、HashSet)。查找一个对象时,先通过hashCode直接找到对象对应的桶,再在桶里一个个用equals比较。

Object.hashCode()默认直接返回对象的地址,即对象哈希值相同当且仅当为同一个对象(引用一样),当使用了自定义的等价规则时,需要重写hashCode。

九、 重载

重载(overload)机制使得同一个类中的多个方法可以有相同的名字,前提是它们有长度不同的参数列表,或者对应不同的参数类型,起码,得让编译器在进行静态检查的时候通过你调用时传入的参数判断实际上应该选择哪个方法。重载也可以发生在父类与子类之间(子类重载父类的方法)。

overload实际上属于特设多态 (ad-hoc),这种多态下,同一操作针对不同类型表现出不同的行为。

 重载函数的返回值可以没有任何关系。

十、 泛型

泛型是参数化多态的实现机制,它能够将类型作为类/方法的参数,使得操作与类型无关。

3种基本的多态:

①特设多态(同一操作,不同类型不同行为),重载

②参数化多态(操作与类型无关),泛型

③子类型多态(同一对象可能属于多种类型),继承/重写

泛型具有不可协变性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
fork是一个系统调用,用于创建一个新的进程。在哈尔滨工业大学的操作系统课程中,学生学习到了fork系统调用的使用和原理。 在操作系统中,每个进程都具有一个唯一的进程ID(PID)和一组资源。当调用fork时,当前进程会被复制,创建一个新的子进程。子进程和父进程具有相同的代码、数据和环境变量等。但是,子进程有自己的独立的内存空间。 fork调用返回两次,一次在父进程中返回子进程的PID,一次在子进程中返回0。这样,父进程可以根据返回的PID来判断fork是否成功,并根据需要进行相应的处理。 fork系统调用被广泛应用于多进程编程中。通过利用fork,可以实现并发执行,提高系统的资源利用率和效率。在操作系统课程中,学生通常学习如何使用fork创建子进程,并使用进程间通信机制进行进程间的数据交换和同步。 通过学习fork系统调用,学生可以了解进程的创建和管理,理解进程的概念和特点,并掌握进程间通信和同步的方法。此外,fork也是其他一些高级系统调用(如exec)的基础,对于学生进一步研究和学习操作系统提供了良好的基础。 总之,哈尔滨工业大学操作系统课程中的fork系统调用是学生学习并发编程和进程管理的重要内容,通过掌握这个系统调用,可以为学生提供丰富的编程经验和操作系统理论基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值