软件构造之抽象相关知识总结

抽象
1.抽象的概念

基础概念:从众多的事物中抽取出来的共同的、本质的特征,而舍弃其非本质特征的过程。
重点在于 共同 本质 特征

2.抽象方法和抽象类

(1)抽象方法:如果父类当中的方法不确定如何进行{}方法体的实现,那么这个就应该是一个抽象方法。格式:在返回值前加上abstrct关键字,然后去掉大括号(也就是不包括方法体),直接以分号结束。

例如:现在有一个父类(动物),定义一个吃东西的方法,在子类(狗、猫)中定义吃东西的方法,有具体的表现(狗吃骨头,猫吃鱼)。可以看出父类中是无法具体定义方法体的,但是具体到子类就可以,那么这时的父类就是一个抽象方法。

(2)抽象类:抽象方法所在的类必须是一个抽象类。也就是要在class之前加上abstract即可。

public abstract class Animal{ //抽象类
public abstract void eat(); //抽象方法
}
(3)如何使用抽象类和抽象方法

*不能直接使用new创建抽象类的对象。(抽象类也就是没有具体的类别,所以没办法创建一个具体的对象)

*必须使用一个子类来继承抽象类,然后通过子类来创建对象。

*子类必须覆盖重写抽象父类中的所有的抽象方法。(去掉abstract关键字,补上方法体实现的具体内容)

*创建子类对象进行使用。

(4)注意

*抽象类不能直接创建对象,只能通过其非抽象子类来创建对象。

*抽象类中可以有构造方法,是供子类创建对象时,初始化父类成员使用的。

*抽象类中,不一定包含抽象方法,也可以存在普通的方法,但是有抽象的方法的类一定是抽象类。

*抽象类的子类,必须覆盖重写抽象父类中的所有抽象方法,否则报错。除非子类也是抽象类。
§ Designing reusable classes 设计可复用的类
– Inheritance and overriding 继承与重写
– Overloading 重载
– Parametric polymorphism and generic programming 参数多态与泛型编程
– Behavioral subtyping and Liskov Substitution Principle (LSP) 行为子类型与
Liskov替换原则
– Composition and delegation 组合与委托
§ Designing system-level reusable libraries and frameworks 设计
可复用库与框架
– API and Library
– Framework
– Java Collections Framework
(an example)

How much are paid for reusing this asset? 复用的代价有多大?
– Cost to buy the asset and other mandatory libraries 搜索、获取
– Cost for adapting and extending it 适配、扩展
– Cost for instantiating it 实例化
– Cost for changing other parts of the system that interact with it 与软件其他
部分的互连的难度

A software asset with high reusability should:
– Brief (small size) and Simple (low complexity)
小、简单
– Portable and Standard Compliance
与标准兼容
– Adaptable and Flexible
灵活可变
– Extensibility
可扩展
– Generic and Parameterization
泛型、参数化
– Modularity
模块化
– Localization of volatile (changeable) design assumptions 变化的局部性
– Stability under changing requirements
稳定
– Rich documentation
丰富的文档和帮助
White box reuse 白盒复用:源代码可见,可修改和扩展
– Reuse of code when code itself is available. Usually requires some kind of
modification or adaptation 复制已有代码到正在开发的系统,进行修改
– Pro: You can customize the module to fit the specific situation, this allows
reuse in more situations 可定制化程度高
– Con: You now own the customized result, so it adds to your code
complexity. You requires intrinsic knowledge on component internals. 对其
修改增加了软件的复杂度,且需要对其内部充分的了解
§ Black box reuse 黑盒复用:源代码不可见,不能修改
– Reuse in the form of combining existing code by providing some “glue”,
but without having to change the code itself - usually because you do not
have access to the code 只能通过API接口来使用,无法修改代码
– Pro: Simplicity and Cleanliness 简单,清晰
– Con: Many times it is just not possible 适应性差些

委托和继承
首先明确,这两种模式提出的初衷都是为了提高代码的可复用性,而在具体实现上有所不同。

委托:一个对象需要另一个对象的功能,于是捕获该对象,并发送到另一对象中进行功能调用。
继承:获得一个基类的元素和方法。
举个例子:水果需要工厂进行榨汁,而水果本身不具有榨汁的功能,将榨汁的行为写给水果也不合适,于是我们把水果交给工厂(类)中的方法进行处理,这是委托(delegation)。
水果具有下落(fall)的行为,苹果也有下落的行为,在水果(类)中写“下落”这种行为,然后在苹果(类)中通过extends获得这个方法的复用,这是继承(inheritance)
Composition(组合):将委托类完全内部化的delegation。
在这样的关系中,委托类的实例化,功能,生命周期均取决于被委托类的指派,委托类作为被委托类的一个private属性,且没有向外部提供更改该属性的方法(一般使用new 方法实例化之后便不再对其进行操作)。
两个类之间存在的关系为a-part-of.
Aggregation(聚集):将委托类作为内部属性的delegation。
• 在这样的关系中,委托类也为被委托类的内部属性,但是脱离了被委托类的使用(比如将被委托类释放),此时委托类仍然存在,并具有部分意义。

LSP
所有引用基类的地方必须能透明地使用其子类的对象。
1、里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。

2、里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。

3、里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。
§ 1、子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法;
§ 2、子类中可以增加自己特有的方法。

Subtypes can add, but not remove methods 子类型可以增加方法,但不可删
– Concrete class must implement all undefined methods 子类型需要实现抽象
类型中的所有未实现方法
– Overriding method must return same type or subtype 子类型中重写的方法必
须有相同或子类型的返回值或者符合co-variance的参数
– Overriding method must accept the same parameter types 子类型中重写的
方法必须使用同样类型的参数或者符合contra-variance的参数
– Overriding method may not throw additional exceptions 子类型中重写的方法不
能抛出额外的异常 子类型规约更强
§ Also applies to specified behavior (methods): 规约不变或更强
– Same or stronger invariants 更强的不变量
– Same or weaker preconditions 更弱的前置条件
– Same or stronger postconditions 更强的后置条件

– Preconditions cannot be strengthened in a subtype. 前置条件不能强化
– Postconditions cannot be weakened in a subtype. 后置条件不能弱化
– Invariants of the supertype must be preserved in a subtype. 不变量要保持
– Contravariance of method arguments in a subtype 子类型方法参数:逆变
– Covariance of return types in a subtype. 子类型方法的返回值:协变
– No new exceptions should be thrown by methods of the subtype, except
where those exceptions are themselves subtypes of exceptions thrown by
the methods of the supertype. 异常类型:协变 (This is to be discussed in
Section 7-2)

Generics are type invariant
– ArrayList is a subtype of List
– List is not a subtype of List

A与B有关系,Box(A)与Box(B)没有关系

继承 委托
如果子类只需要复用父类中的一小部分方法, 可以不需要使用继承,而是通过委派机制来实现,可以不用继承全部方法,只用委托机制调用部分方法.避免大量无用方法

§ Dependency: a temporary relationship that an object requires other
objects (suppliers) for their implementation.
§ 依赖:对象之间的动态的、临时的通信联系
–use a
Association: a persistent relationship between classes of objects
that allows one object instance to cause another to perform an action
on its behalf. 关联:对象之间的长期静态联系——has a

Composition组成: 更强的association,但难以变化
不同于一般的Association,这里变成了其一部分属性,并且彼此不可分,在
内部创建。
Aggregation: 更弱的association,可动态变化
has_a 对象存在于另一个对象之外,是在外部创建的,因此它作为参数传
递给构造函数。
聚合:部分与整体的关系,但彼此可分——owns a
In composition组合, when the owning object is destroyed, so are the
contained objects.
In aggregation聚合, this is not necessarily true.
正则表达式

工厂类
当client不知道要创建哪个具体类的实例,或者不想在client代码中指明要具体
创建的实例时,用工厂方法。
定义一个用于创建对象的接口,让其子类来决定实例化哪一个类,从而使一个
类的实例化延迟到其子类。

异常
异常:程序执行中的非正常事件,程序无法再按预想的流程执行
如果子类型中
override了父类型中的函数,那么子类型中方法抛出的异常不能比父 类型抛出的异常类型更宽泛
子类型方法可以抛出更具体的 异常,也可以不抛出任何异常
如果父类型的方法未抛 出异常,那么子类型的方法也不能抛出异常。

Find an appropriate exception class 找到一个能表达错误的Exception类/
或者构造一个新的Exception类
– Make an object of that class 构造Exception类的实例,将错误信息写入
– Throw it 抛出它
一旦抛出异常,方法不会再将
控制权返回给调用它的client,因此也无需考虑返回错误代码
如果JDK提供的exception类无法充分描述你的程序发生的错误,可
以创建自己的异常类

有时,在某些情况下,您不想强制每个方法在其抛出子句中声明异常实现。在这种情况下,您可以创建一个扩展java.lang.RuntimeException的未选中的异常

§ LSP is a particular definition of a subtyping relation, called
(strong) behavioral subtyping
当异常抛 出时,方法中正常执行的代码被终止
如果异常发生前曾 申请过某些资源,那么异常发生后这些资源要被恰当的清理
无论是否捕获了异常,finally子句中的代码都将执行
可以使用不带catch子句的finally子句

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呆先森HIT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值