设计可重用的类

12人阅读 评论(0) 收藏 举报
分类:

如果q(x)是为一个关于T型对象x的属性,S是T的子类型,那么q(y)为S类型的对象y的属性是可以证明的。

行为子类型化和Liskov替代原则

行为子类型化

子类型可以增加方法,但不可删除原有的方法
子类型需要实现抽象类型中的所有未实现方法
子类型中重写的方法必须有相同或子类型的返回值
子类型中重写的方法必须使用同样类型的参数
子类型中重写的方法不能抛出额外的异常

具体体现为:
子类型具有更强的不变量
子类型的方法具有更强的规约

在编程语言中,LSP依赖于以下限制:
每个方法的前置条件不能强化
每个方法的后置条件不能弱化
每个子类型的不变量要保持
子类型的方法参数满足逆变要求
子类型的方法返回值满足协变要求
子类型的方法不应该抛出新的异常,除非这些异常本身是由超类型的方法抛出的异常的子类型。

协变和逆变

协变和逆变指的是宽类型和窄类型在某种情况下的替换或交换的特性。
协变就是用一个窄类型替代宽类型。
逆变则用宽类型覆盖窄类型。
数组是协变,考虑到子类型化的Java规则,类型T[]数组可能包含类型T的元素或任何T的亚型的元素。

泛型中的LSP

在实际运行中,我们会发现,ArrayList<String>是List<String>的子类型 ,List<String> 不是 List<Object>的子类型。这是因为在代码编译完成后,编译器会丢弃类型参数的类型信息;因此,此类型信息在运行时不可用。这个过程被称为类型擦除。Java的泛型机制是在编译级别实现的。编译器生成的字节码在运行期间并不包含泛型的类型信息。在编译之后,List<Object>和List<String>将变成List,Object和String类型信息对于JVM来说是不可见的。在编译阶段,编译器发现它们不一致,因此给出了一个编译错误。因此, List<Integer>不是 List<Number>的子类型,即使 Integer 是 Number的一个子类型. 给定两个具体类型A和B(例如,Number和Integer),MyClass<A>与MyClass<B>没有关系,无论A和B是否相关。

泛型中的通配符

未绑定的通配符类型使用通配符(?)指定,在java泛型中,?代表未知类型,<? extends Object>表示上边界限定通配符,< ? super Object>表示下边界限定通配符。比如List<? extends Person>表示任何泛型List类型,它的类型参数是Person以及Person的子类,如List<Student>。当使用上界通配符<? extendsT>时,只能get数据而不能set数据;而下界通配符<? super T>刚好相反,当使用下界通配符时,只能set数据而不能get数据。 

委派与组合

委托仅仅是一个对象依赖另一个对象来实现其功能的某个子集(一个实体将某个东西传递给另一个实体),它是复用的一种常见形式。委托模式是一个用于实现委托的软件设计模式,它依赖于动态绑定,要求给定的方法调用可以在运行时调用不同的代码段。

组合重用原则:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。
好处
新对象存取成分对象的唯一方法是通过成分对象的接口。
这种复用是黑箱复用,因为成分对象的内部细节是新对象所看不见的。
这种复用支持包装。
这种复用所需要的依赖较少。
每一个新的类可以将焦点集中到一个任务上。
这种复用可以在运行时间动态进行,新对象可以动态的引用与成分对象类型相同的对象。
缺点就是用组合复用建造的系统会有较多的对象需要管理。

委派的类型

临时性的delegation

使用类的最简单形式是调用它的方法;这种形式的两个类之间的关系被称为“使用”关系,即一个类使用了另一个类,却不将其作为自身的一个属性,而是作为类中某个方法的参数。 

永久性的delegation
一个类将另一个类的对象作为属性,它指定了一个类的对象与另一个对象的对象连接,而不表示行为。

组合

一个类拥有另一个类作为属性/实例变量——一个对象包含另一个对象,对象在类中创建。

聚合

对象存在于类的外部,是在外部创建的,需要作为一个参数传递给构造函数。

查看评论

Java笔记(三)类的重用

Java语言的重用机制,重用的形式可以是类的组合或继承。基于类和对象的重用比传统程序的重用更容易。 1.类的继承 (1)继承的概念(子类,超类) ...
  • LiuShuaiQ
  • LiuShuaiQ
  • 2016-06-10 14:05:42
  • 1726

可重用设计方法学

  • 2011年11月16日 11:11
  • 6.51MB
  • 下载

片上系统:可重用设计方法学(第三版).pdf

  • 2011年02月13日 09:42
  • 6.68MB
  • 下载

设计模式:可复用的面向对象软件元素

软件工程有两大核心,其一是数据结构与算法,其二就是设计模式。本篇博文分享的是设计模式,希望对所有关注设计模式的初学者有所帮助。 一、设计模式简介设计模式简介设计模式(Design pattern)代表...
  • exuejwa
  • exuejwa
  • 2016-06-12 20:46:58
  • 1880

向架构师进军-->可重用架构资源

软件架构有三个主要来源:拿取、方法以及直觉。拿取也就是可重用资源。对于一个标准的系统而言,可能包含80%的拿取、19%的方法和1%的直觉。而崭新的系统则包含30%的拿取、50%的方法和20%的直觉。由...
  • wyxhd2008
  • wyxhd2008
  • 2014-05-17 23:08:00
  • 1876

Python中的代码重用——Modules

      在Python中,可以使用Function来实现代码重用。如果需要重用一组function,则需要使用Modules。      对于Modules,可以使用两种方法编写。第一、也是最简单...
  • prince2270
  • prince2270
  • 2009-09-25 20:50:00
  • 1218

软件工程-可重用构件的特点

本文参考自自张海藩老师和牟永敏的《软件工程导论》 目标:在各种各样的软件系统中方便的重复的使用 需要满足的要求: 可靠  经过反复测试,被确认是正确的。具备一定的健壮性。 模...
  • time_hunter
  • time_hunter
  • 2013-12-19 22:39:59
  • 1055

代码重用和接口重用

在面试中,面向对象语言中经常会提到代码重用和接口重用的概念,有些同学会很疑惑,其实仔细翻阅下书本就不难发现,代码重用就是继承父类的方法,达到方法(代码)重用的目的,而接口重用就是在多态中能够通过父类指...
  • zsczsc1011
  • zsczsc1011
  • 2015-08-27 17:24:45
  • 1418

Java内部锁的可重用性(Reentrancy)

Java提供了强制原子性的内部锁机制:synchronized块。但是内部锁是可重入的,当线程试图获得它自己占有的锁时,请求会成功。简单的说,就是在一个synchronized方法内部调用本类的其他s...
  • haydenwang8287
  • haydenwang8287
  • 2010-08-25 15:38:00
  • 5011

socket重用

1.closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO...
  • killalarm
  • killalarm
  • 2011-04-08 11:40:00
  • 2798
    个人资料
    持之以恒
    等级:
    访问量: 300
    积分: 130
    排名: 116万+
    文章分类
    文章存档