之前复习面向对象的时候整理的,丢出来一起分享一下。因为复习得很赶,只是大致的整理,且大部分图片来自老师的ppt,可能不是很准确。如果要详细了解其中的某个知识点请另外搜索。
但是老师不讲武德啊,明明提纲给了不按提纲考,还从开卷变成闭卷。大意了,当时就不应该报啊。
(1)客观事物是由对象组成的,对象是在原事物基础上抽象的结果。
(2)对象是由属性和操作组成的,其属性反映了对象的数据信息特征,而操作则用来定义改变对象属性状态的各种操作方式。
(3)对象之间的联系通过消息传递机制来实现。
(4)对象可以按其属性来归类。
(5)对象具有封装的特性,可达到软件复用的目的。
Ps:面向对象的三大特性是"封装、“继承”、“多态”
五大原则是"单一职责原则"
“开放封闭原则”:对扩展是开放的,对修改是封闭的
“里氏替换原则”:子类应当可以替换父类,并能出现在父类能出现的任何位置上
“依赖倒置原则”:抽象不能依赖于具体,具体应该依赖于抽象
“接口分离原则”:使用多个专门的接口,而不使用单一的总接口,即类不应该依赖那些它不需要的接口
1.面向过程方法首先关心的是功能,强调以模块(即过程)为中心,采用模块化、自顶向下、逐步求精设计过程,系统是实现模块功能的函数和过程的集合。
2.面向对象方法是一种运用对象、类、继承、聚合、关联、消息、封装等概念和原则来构造软件系统的开发方法。
3.面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
4.面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。
类(Class)是面向对象的基础。
对象(Object)是具有明确语义边界并封装了状态和行为的实体,由一组属性和作用在这组属性上的一组操作构成,是构成软件的一个基本单位。
类是对具有相同属性和操作的一组对象的统一抽象描述。
对象是它所属的类的实例。
类和类之间的关系主要有继承、实现、依赖、关联、聚合和组合、(细化)。
继承和实现:子类和父类
依赖:A使用B
关联:强依赖\引用关系,类A中的某个属性的类型是类B
聚合:聚合关系表示的是一种整体和部分的关系,聚合是一种较弱的关联关系,部分与整体可相互独立存在。
组合:也表示一种整体和部分的关系。组合是一种较强的关联关系,部分与整体“共存亡”。
实现:类指向接口。
就是类里面的所有东西,包括成员变量和成员函数
构造函数到析构函数
对象只能通过消息进行通信,而不允许在对象之外直接地访问它内部的属性,这是由封装原则引起的。
消息必须直接发给特定的对象,消息中包含所请求服务的必要信息,且遵守所规定的通信规格说明。一条消息的规格说明至少包括:消息名、入口参数、可能返回的参数。一个对象可以是消息的接受者、发送者和参数。
抽象是指从事务中舍弃个别的、非本质的特征,而抽取共同的、本质特征的思维方式。在面向对象方法中、对象是对现实世界中事务的抽象,类是对对象的抽象,一般类是对特殊类的抽象。
多态性是指一般类和特殊类可以有相同的属性或操作,但这些属性或操作,但这些属性和操作具有不同的含义,即具有不同的数据类型或表现出不同的行为。针对同一个消息,不同的对象响应所做出的行为是不同的。
作用:
吴小竹:显示了信息的结构,同时描述了系统的行为。是定义其他图的基础
1.描述了系统的类的集合,类的属性和类之间的关系,可以简化人们对系统的理解。
2.类图为系统分析和设计阶段的重要产物,是系统编码和测试的重要模型。
3.作为最常用的UML图,显示出类、接口以及它们之间的静态结构和关系。
4.类图图示了所构建系统的所有实体、实体的内部结构以及实体之间的关系。
5.它是构建其他设计模型的基础,也是面向对象编程的起点和依据。
定义:一幅由参与者、用况以及这些元素之间的关系组成的图。
主要的作用:(1)描述了待开发系统的功能需求;(2)将系统看作黑盒,从外部执行者的角度来理解系统;(3)驱动了需求分析之后各阶段的开发工作,不仅在开发过程中保证了系统所有功能的实现,而且被用于验证和检测所开发的系统,从而影响到开发工作的各个阶段和 UML 的各个模型。
定义:是一种详细描述对象之间以及对象与参与者之间交互的图,由一组相互协作的对象或参与者实例以及它们之间发送的消息组成,强调消息之间的顺序。
作用:1.把用例表达的需求,转化为进一步、更加正式层次的精细表达。2.用例常常被细化为一个或者更多的序列图。同时序列图更有效地描述如何分配各个类的职责以及各类具有相应职责的原因。
序列图是由对象、生命线、激活、消息、分支与从属流等元素构成的
生命线(Lifeline)是一条垂直的虚线,用来表示序列图中的对象在一段时间内的存在激活。
激活(Activation)表示一个对象直接或通过从属操作完成操作的过程。在UML图中通过一个窄长的矩形来表示,矩形的高度表示对象存在的过程。
定义:是描述动作、动作的执行顺序以及动作的输入与输出的图,由动作结点和边组成
动作:是可执行的基本功能单元,用以描述系统中的状态转换或活动,是原子性的和实时的。
活动:是一组相互协作的动作构成的行为单元,在执行中可被事务中断。
作用: (1)描述复杂过程的算法。(2)活动图对用例描述尤其有用,它可建模用例的工作流,显示用例内部和用例之间的路径。它可以说明用例的实例是如何执行动作以及如何改变对象状态。(3)活动图对理解业务处理过程十分有用。活动图可以画出工作流用以描述业务,有利于与领域专家进行交流。(4)描述一个操作执行过程中所完成的工作。说明角色、工作流、组织和对象是如何工作的。发送信号接收信号
定义:描述了一个对象在其生命周期内因响应事件所经历的状态序列以及这些事件所做出的反应。主要由状态和状态间的转移构成。
事件的定义:指时间上和空间上可以定位并具有实际意义、值得注意的所发生的事情。
UML中把事件分为
信号事件:一个对象对一个信号实例的接受,特征标记放在由它触发的转移上。
调用事件:对操作的调用的接受,导致一个调用事件,由接受事件的对象实现事件。
改变事件:用布尔表达式描述的指派条件变为真。
状态的定义:对象在其生命周期内满足特定条件,进行特定活动或等待特定事件的状况。
要解决的问题、结构(uml类图)、优缺点
开-闭原则:要求一个系统的设计能够允许系统在无需修改的情况下,扩展其功能。
由一个工厂对象决定创建出哪一种产品类的实例。
解决的问题:
专门负责将大量有共同接口的类实例化。
结构:
优点:
1.客户端则可以免除直接创建产品对象的责任,而仅仅负责“消费”产品。
2.对于消费者角色来说,任何时候需要某种产品,只需要向工厂角色(下订单)请求即可,而无需知道产品创建细节。
3.实现了客户端类与产品类的解耦。
缺点:对“开-闭”原则的支持不够,因为如果有新的产品加入到系统中去,就需要修改工厂类,将必要的逻辑加入到工厂类中。
工厂方法模式将定义一个创建产品对象的工厂接口,将实际创建功能放到具体工厂子类中。
对简单工厂模式加以改进,使得新增产品时依旧符合开放-封闭原则。
Creator:工厂 ConcreteCreator:具体工厂 Product:产品 ConcreteCreator:抽象产品
工厂方法模式的核心是一个抽象工厂类,而简单工厂模式把核心放在一个具体类上。
工厂方法模式可以允许很多具体工厂类从抽象工厂类中将创建行为继承下来,从而可以成为多个简单工厂模式的综合,进而推广了简单工厂模式。
工厂方法模式退化后可以变得很像简单工厂模式。如果确定一个系统只需要一个具体工厂类,把抽象工厂类合并到具体的工厂类中去。将工厂方法改成为静态方法,这时候就得到了简单工厂模式。
如果系统需要加入一个新的产品,那么所需要的就是向系统中加入一个这个产品类以及它所对应的工厂类。没有必要修改客户端,也没有必要修改抽象工厂角色或者其他已有的具体工厂角色。对于增加新的产品类而言,这个系统完全支持“开-闭”原则。
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
用于资源管理器对多个设备的管理。在一个系统要求一个类只有一个实例时才应当使用单例模式。反过来说,如果一个类可以有几个实例共存,那么就没有必要使用单例类。
public class EagerSingleton
{
private static final EagerSingleton m_instance =new EagerSingleton();
//私有的默认构造子
private EagerSingleton() { }
//静态工厂方法
public static EagerSingleton getInstance()
{
return m_instance;//对方调用时实例化
}
}
与饿汉式单例类相同之处是,类的构造函数是私有的。与饿汉式单例类不同的是,懒汉式单例类在第一次被引用时将自己实例化。
类图:
package com.javapatterns.singleton.demos;
public class LazySingleton
{
private static LazySingleton m_instance = null;
//私有的默认构造子,保证外界无法直接实例化
private LazySingleton() { }
//静态工厂方法,返还此类的惟一实例
synchronized public static LazySingleton getInstance()
{
if (m_instance == null)//第一次引用就实例化
{
m_instance = new LazySingleton();
}
return m_instance;
}
}
通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。
public class Client
{
private Prototype prototype;
public void operation(Prototype example)
{
Prototype p=(Prototype)example.clone();
}
}
抽象原型角色声明了一个clone()方法
pubilc interface Prototype extends Cloneable
{
Object clone();
}
具体原型角色实现clone()方法
public class ConcretePrototype implements Prototype/** 克隆方法*/
{ public Object clone()
{try
{ return new ConcretePrototype(); }
catch( CloneNotSupportedException e)
{ return null; }
}
}
客户端(Client)角色:向原型管理器提出存储或提取对象的请求。
抽象原型(Prototype)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体原型类所需的接口。
具体原型(Concrete Prototype)角色:被复制的对象。此角色需要实现抽象的原型角色所要求的接口。
原型管理器(Prototype Manager)角色:管理记录每一个被创建的对象。
优点:1.简化了对象的创建过程。2.在有大对象或多个对象的复制时,可提高系统性能。
缺点:1.每个类必须额外增加一个克隆方法。2.深复制的实现较复杂。
分为类的适配器模式(类的结构模式)和对象的适配器模式(对象的结构模式)
(1)系统需要使用现有的类,而此类的接口不符合系统的需要。
(2)想要建立一个可以重复使用的类.用于一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有很复杂的接口。
把一个类的接口变换成客户端所需要的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。
被适配的类的API转换成为目标类的API,其静态结构图如下图所示。
目标(Target)角色:这就是所期待得到的接口。
源(Adaptee)角色:现有需要适配的接口。
适配器(Adapter)角色:适配器类是本模式的核心,把源接口转换成目标接口。不可以是接口,而必须是具体类。
public interface Target
{
void sampleOperation1(); //源类的方法
void sampleOperation2(); //源类没有的方法
}
public class Adaptee
{
public void sampleOperation1() { }
}
public class Adapter extends Adaptee implements Target
{
/** 由于源类没有方法sampleOperation2,因此适配器类补上这个方法 */
public void sampleOperation2()
{
// Write your code here
}
}
对象的适配器模式不是使用继承关系连接到adaptee类,而是使用委派关系连接到Adaptee类。
Adapter的源代码如下:
public class Adapter implements Target
{ private Adaptee adaptee;
public Adapter(Adaptee adaptee)
{ super();
this.adaptee = adaptee;
}
public void sampleOperation1()
{ adaptee.sampleOperation1();
}
public void sampleOperation2()
{ // Write your code here
}
}
1.合成模式将对象组织到树结构中,可以用来描述整体与部分的关系。
2.合成模式可以使客户端将整体对象与部分对象同等看待。
(1)需要描述对象的部分和整体的等级结构
(2)需要客户端忽略掉整体对象和部分对象的区别。
抽象构件(Component)角色:这是一个抽象角色,给参加组合的对象规定一个接口。这个角色给出共有的接口及其默认行为。
树叶构件(Leaf)角色:代表参加组合的树叶对象。没有下级的子对象。定义出参加组合的原始对象的行为。
树枝构件(Composite)角色:代表参加组合的所有包含子对象的对象,并给出树枝构件对象的行为。
1.透明方式
透明式的合成模式要求所有的具体构件类,不论是树枝还是树叶,均符合一个固定的接口。
优点:所有的构件类都有相同的接口 缺点:不够安全
2.安全方式
安全式的合成模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中。
优点:很安全 缺点:不够透明,树叶类和合成类将具有不同的接口
eg:安全模式
public abstract class Graphics
{
public abstract void draw();
}
public class Picture extends Graphics
{
private Vector list=new Vector(10);
public void draw()
{
for (int i=0;i< list.size();i++)
{
Graphics g=(Graphics)list.get(i);
g.draw();
}
}
public void add(Graphics g)
{
list.add(g);
}
public void remove(Graphics g)
{/*删除一个子构件 */
list.remove(g);
}
public void getChild(int i)
{/* 返还一个子构件 */
return (Graphics)list.get(i);
}
}
public class Line extends Graphics
{
public void draw()
{
//write your code
}
}
透明模式
abstract public class Graphics
{
public abstract void draw();
public void add(Graphics g);/* 聚集管理方法,增加一个子构件 */
public void remove(Graphics g);/* 聚集管理方法,删除一个子构件 */
public Graphics getChild(int i);/* 返还一个子构件 */
}
package com.javapatterns.composite.drawingtransparent;
import java.util.Vector;
public class Picture extends Graphics
{
private Vector list=new Vector(10);
public void draw()
{
for (int i=0;i< list.size();i++)
{
Graphics g=(Graphics)list.get(i);
g.draw();
}
}
public void add(Graphics g){
list.add(g);
}
public void remove(Graphics g){
list.remove(g);
}
public Graphics getChild(int i){
return (Graphics)list.get(i);
}
}
public class Line extends Graphics
{
public void draw(){//do nothing }
public void add(Graphics g){//do nothing }
public void remove(Graphics g){//do nothing }
public Graphics getChild(int i){//do nothing }
}
代理(Proxy)模式给某一个对象提供一个代理,并由代理对象控制对原对象的引用
抽象主体角色(Subject):声明了真实主体和代理主体的共同接口
代理主体(Proxy)角色:内部含有对真实主体的引用;供一个与真实主体角色相同的接口;负责在需要的时候创建真实主体对象(和删除真实主体对象),在将客户端调用传递给真实的主体之前或之后,都要执行某个操作
真实主体角色(RealSubject)角色:定义了代理角色所代表的真实对象。
Package com.javapatterns.proxy;
Abstract public class Subject
{
abctract public void request();//抽象请求方法
}
Public class RealSubject extends Subject
{
public RealSubject(){}
public void request(){//具体请求方法}
}
Public class ProxySubject extends Subject
{
private RealSubject realSubject;
public ProxySubject(){}
public void request()//实现请求方法
{ preRequest();//请求先先进行的操作
if (realSubject==null)
realSubject=new RealSubject();
realSubject.request();
postRequest();//请求后进行的操作
}
private void preRequest()//请求前的操作
{
//something you want to do before requesting
}
private void postRequest()//请求后的操作
{
//something you want to do before requesting
}
}
以对客户端透明的方式扩展对象的功能。是继承关系的一种替代方案。
抽象构件(Component)角色:给出一个接口,以规范准备接收附加责任(扩展功能)的对象。
具体构件(Concrete Component)角色:定义一个准备接收附加责任的类。
装饰(Decorator)角色:持有一个构件的实例,并定义与抽象构件接口一致的接口。
具体装饰(Concrete Decorator)角色:负责给构件对象“贴上”附加的责任。
Public interface Component
{
void sampleOperation();//某业务逻辑方法
}
Public class Decorator implements Component
{
private Component component;
public Decorator(Component component)
{
this.component = component;
}
public void sampleOperation()/** 业务方法,委派给构件*/
{
component.sampleOperation();
}
}
Public class ConcreteComponent implements Component
{
public ConcreteComponent() {//Write your code here}
public void sampleOperation() {//Write your code here}
}
Public class ConcreteDecorator extends Decorator
{
public void sampleOperation()//进一步增强功能
{ super.sampleOperation(); }
}
1.可以提供比继承更多的灵活性.
2.通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同的行为的组合.
1.产生出较多的对象;
2.比继承更易出错;
一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
解决的问题:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
抽象主题(Subject)角色:把所有对观察者对象的引用保存在一个聚集里;提供接口,可以增加和删除观察者对象。
抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。
具体主题(Concrete Subject)角色:将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。负责实现对观察者引用的聚集的管理方法。
具体观察者(Concrete Observer)角色:实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题 的状态相协调。
所有具体主题管理聚集的方法都相同,因此可以将它移到抽象主题中.
第二种实现方案和第一种实现方案的主要区别就是代表存储观察者对象的聚集连线是从抽象主题到抽象观察者.
1.观察者模式在被观察者和观察者之间建立一个抽象的耦合。2.观察者模式支持广播通信。
缺点
1.如果一个被观察者有很多的观察者,将所有的观察者都通知到会花费很多时间。
2.如果在被观察者之间有循环依赖,被观察者会触发它们之间进行循环调用,导致系统崩溃。
3.虽然观察者随时知道所观察的对象发生了变化,但是观察者模式没有相应的机制使观察者知道所观察的对象是怎样发生变化的。
请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。请求的一方和接收的一方独立开来。
客户端(Client)角色:创建了一个具体命令(ConcreteCommand)对象并确定其接收者。
命令角色(Command):声明了一个给所有具体命令类的抽象接口。
具体命令(ConcreteCommand)角色:定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法。
请求者(Invoker)角色:负责发出一个请求。
接收者(Receiver)角色:任何一个类都可以成为接收者;实施和执行请求的方法叫做行动方法。
public class Invoker
{ private Command command;
public Invoker(Command command)
{
this.command=command;
}
/* 行动方法 */
public void action()
{
command.execute();
}
}
public class Receiver
{
public Receiver()
{ }
public void action()
{
System.out.println(“Action has been taken.”);
}
}
public interface Command
{ void execute(); }
Public class ConcreteCommand implements Command
{
private Receiver receiver;
public ConcreteCommand(Receiver receiver)
{
this.receiver=receiver;
}
public void execute()
{
receiver.action();//调用接受者的接受方法
}
}
public class Client
{ public static void main(String[] args)
{ Receiver receiver=new Receiver();
Command command=new ConcreteCommand(receiver);
Invoker invoker=new Invoker(command);
invoker.action();//发出请求
}
}
1.命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。
2.命令类与其他任何别的类一样,可以修改和扩展。
3.可以把命令对象聚合在一起,合成为合成命令。
4.由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
1使用命令模式会导致某些系统有过多的具体命令类。
模板方法模式是所有模式中最为常见的几个模式之一。模板方法模式是基于继承的代码复用的基本技术,模板方法模式的结构和用法也是面向对象设计的核心。
模板方法模式为设计抽象类和实现具体子类的设计师之间的协作提供了可能:一个设计师负责给出一个算法的轮廓和骨架,另一些设计师则负责给出这个算法的各个逻辑步骤。
解决的问题:一些方法通用,却在每一个子类都重新写了这一方法。
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
一些方法通用,却在每一个子类都重新写了这一方法。
1、封装不变部分,扩展可变部分。
2、提取公共代码,便于维护。
3、行为由父类控制,子类实现。(即好莱坞原则)
每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得他们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
何时使用:
1.如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为。
2.一个系统需要动态地在几种算法中选择一种。
3.一个系统的算法使用的数据不可以让客户端知道。
4.如果一个对象有很多的行为,
环境(Context)角色:表示策略的使用环境,它持有一个Strategy对象的引用。
抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
1、算法可以自由切换。
2、避免使用多重条件判断。
3、扩展性良好。
1、策略类会增多。
2、所有策略类都需要对外暴露。
(ppt无)
java语法:
继承:extends class A extends B接口:implements eg: class A implements B
浅复制:
被复制对象的所有变量都含有与原对象相同的值,而所有的对其它对象的引用都仍然指向原来的对象。浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深复制:
被复制对象的所有变量都含有与原对象相同的值,除去那些引用其它对象的变量。那些引用其它对象的变量将指向被复制过的新对象。深复制把要复制的对象所引用的对象都复制了一遍,而这种对被引用到的对象的复制叫做间接复制。