day01_面向对象五大原则_1.单一职责原则&2.里氏替换原则

单一职责原则:Single Responsibility Principle (SRP)

一个类,只有一个引起它变化的原因。应该只有一个职责。每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起。这会导致脆弱的设计。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起,会影响复用性。例如:要实现逻辑和界面的分离。

T负责两个不同的职责:职责P1,职责P2。当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障。也就是说职责P1和P2被耦合在了一起。

原因是职责扩散:因为某种原因,某一职责被分化为颗粒度更细的多个职责了。

例如Iphone接口,打电话分为四个过程,拨号,通话,回拨,挂机。

这样子貌似没错,但是仔细想一想扩展性和变更,你会发现,如果将来升级,要转化为数字电话,那么通话要重新写,拨号也是。

这样一来的话,需要一种更好的设计,不管一种方法如何变化,另一种不管。这就是职责单一原则。

思路如下: Iphone这个接口有俩个职责,一个是协议管理,一个是数据传输。

一个负责传输数据,不管什么数据,基于什么版本,而另一个负责拨号和挂机,拨号只负责能接通就行。

这样的好处: 协议管理和数据传送分开,如果将来科技进步,那么就减少了因为变更而引起的工作量。可维护性和可读性提高了。

再来一个例子:  修改信息

修改后:

里氏替换原则: Liskov Substitution Principle,LSP

继承的优缺点

优点:代码共享,重用性,可扩展性

缺点:降低了代码的灵活性,增加了耦合性(父变子则变)

悟 : 父类就是为了解决子类们基础问题而存在,好比父类就是大地,而子类就是大地上所有植物,父类就解决了土地,水的问题。

 

1.子类继承父类的成员变量

  当子类继承了某个类之后,便可以使用父类中的成员变量,但是并不是完全继承父类的所有成员变量。具体的原则如下:

  1)能够继承父类的public和protected成员变量;不能够继承父类的private成员变量;

  2)对于父类的包访问权限成员变量,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

  3)对于子类可以继承的父类成员变量,如果在子类中出现了同名称的成员变量,则会发生隐藏现象,即子类的成员变量会屏蔽掉父类的同名成员变量。如果要在子类中访问父类中同名成员变量,需要使用super关键字来进行引用。

  2.子类继承父类的方法

  同样地,子类也并不是完全继承父类的所有方法。

  1)能够继承父类的public和protected成员方法;不能够继承父类的private成员方法;

  2)对于父类的包访问权限成员方法,如果子类和父类在同一个包下,则子类能够继承;否则,子类不能够继承;

  3)对于子类可以继承的父类成员方法,如果在子类中出现了同名称的成员方法,则称为覆盖,即子类的成员方法会覆盖掉父类的同名成员方法。如果要在子类中访问父类中同名成员方法,需要使用super关键字来进行引用。

  注意:隐藏和覆盖是不同的。隐藏是针对成员变量和静态方法的,而覆盖是针对普通方法的。(后面会讲到)

  3.构造器

  子类是不能够继承父类的构造器,但是要注意的是,如果父类的构造器都是带有参数的,则必须在子类的构造器中显示地通过super关键字调用父类的构造器并配以适当的参数列表。如果父类有无参构造器,则在子类的构造器中用super关键字调用父类构造器不是必须的,如果没有使用super关键字,系统会自动调用父类的无参构造器。

原则1:子类必须完全实现父类的方法

就如上面所说的,假如大地的子类玉兔,这个东西既不需要土地和水,却继承了大地,那么这是不合理的。子类必须完全实现父类的方法就是为了代码复用。

原则2:子类可以有自己的个性

在子类出现的地方,父类未必可以胜任。

子类在继承的同时可以扩展出其他方法和属性。万物生长,基于大地。

原则3:覆盖式实现父类的方法时输入参数可被放大

首先理解重写和重载的区别:

重载:方法名相同,参数不同。

重写:方法名相同,参数相同。

分析:覆盖式实现父类方法其实就是重载,如果子类中输入参数被放大,那么父类那部分代码就没有浪费,这句话说的很晦涩,的确刚刚学的时候想了好久,后来再看了一下原则就释然了,代码重用!每个方法必须有所用处,父类中的参数范围虽然没有子类的大,子类的重载是为了扩展,弥补了父类的不足。一般来说,是不会去重载的。

如果反过来,如果子类的参数范围比父类要小,相当于子类方法中有俩个方法,一个是父类的方法,一个是子类的,父类参数范围大,子类范围小。有父类的地方子类却不能使用,这个已经违背了原则。

悟 : 重载就是将父类的类名称改为子类名,再加一个方法名相同,参数不同的方法。

重写就是将父类的类名称改为自类名,再修改一下被重写的方法。

例子:

Father 类

public class Father {
 public Collection doSomething(Map map){
  System.out.println("父类:Map 转集合");
  return map.values();
 }
}

Son 类

public class Son extends Father {
 public Collection doSomething(HashMap map) {
  System.out.println("子类:Hashmap 转集合");
  return map.values();
 }
}

测试类

public static void main(String[] args) {
  Son f=new Son();      //俩个方法 一个
  HashMap h=new HashMap();
  f.doSomething(h);  //子类
 }

结果:

子类:Hashmap
转集合

参考书籍:

《设计模式之禅》

参考文章:

http://www.cnblogs.com/dolphin0520/p/3803432.html

http://www.cnblogs.com/xiaoao808/archive/2008/03/11/1100886.html

我是菜鸟,我在路上。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-09 02:21:21

day01_面向对象五大原则_1.单一职责原则&2.里氏替换原则的相关文章

面向对象五大原则_1.单一职责原则&2.里氏替换原则

单一职责原则:Single Responsibility Principle (SRP) 一个类.仅仅有一个引起它变化的原因.应该仅仅有一个职责.每个职责都是变化的一个轴线.假设一个类有一个以上的职责,这些职责就耦合在了一起.这会导致脆弱的设计.当一个职责发生变化时,可能会影响其他的职责.另外,多个职责耦合在一起,会影响复用性. 比如:要实现逻辑和界面的分离. T负责两个不同的职责:职责P1.职责P2.当因为职责P1需求发生改变而须要改动类T时.有可能会导致原本执行正常的职责P2功能发生问题.

面向对象设计原则三:里氏替换原则(LSP)

里氏替换原则(LSP)定义:在任何父类出现的地方都可以用它的子类类替换,且不影响功能.解释说明:其实LSP是对开闭原则的一个扩展,在OO思想中,我们知道对象是由一系列的状态和行为组成的,里氏替换原则说的就是在一个继承体系中,对象应该具有共同的外在特性,使用LSP时,如果想让我们的程序达到一个父类出现的地方都可以用它的子类来替换且不影响功能,那么这个父类也应该尽量声明出子类所需要的一些公共的方法,父类被子类替换之后,会比较顺利,那么为什么说它是对开闭原则的一个扩展呢?因为我们在开闭原则中说尽量使用

深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP

前言 Bob大叔提出并发扬了S.O.L.I.D五大原则,用来更好地进行面向对象编程,五大原则分别是: The Single Responsibility Principle(单一职责SRP) The Open/Closed Principle(开闭原则OCP) The Liskov Substitution Principle(里氏替换原则LSP) The Interface Segregation Principle(接口分离原则ISP) The Dependency Inversion Pr

面向对象编程6大设计原则:单一职责原则

单一职责原则(Single  Responsibility Principle)简称SRP原则. 定义 应该有且仅有一个原因引起类的变更. 优点 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多: 提高类的可读性,提高系统的可维护性: 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响. 说明 单一职责原则不只是面向对象编程思想所特有的,只要是模块化的程序设计,都适用单一职责原则: 单一职责原则要根据项目的实际情

面向对象设计原则:单一职责原则(The Single Responsibility Principle)

热爱生活.享受娱乐.专注技术,欢迎关注微信公众号QGer,我们一起见证成长! 什么是单一职责原则? - 官方解释:一个类应该只有一种改变的原因 - 通俗解释:一个类被修改.拓展的时候,应该只能因为一种职责(功能)的扩展,而不应该有第二种职责导致类的修改,一个也不能有另一种职责存在. 为什么遵循单一职责原则? 降低类的复杂度,一个类负责一种职责,逻辑上也变得直观简单. 使代码变得灵活,提高系统的维护性. 变更的风险降低,有需求就会有变更,单一职责原则可降低变更的影响面. 保持松耦合,提供内聚. 如

【设计模式】单一职责 开-闭 依赖倒转 里氏替换原则

几个设计模式的原则,简单了解了一下 单一职责 类的功能应该单一,就一个类而言,应该仅有一个引起它变化的原因,否则就要拆分. [大话设计模式]里大鸟和小菜用的DV的摄像功能和手机的摄像功能的比较,DV的功能单一,手机的功能多而复杂,小菜在看到UFO的时候赶紧拿出手机来录像,结果发现录的很不清楚,如果是DV的话,小菜应该来得及摆一个牛逼的姿势,把UFO给录进去. 开闭原则 可以很简单的总结为一句话:对扩展开放,对修改关闭. 对一个功能的修改应该是通过增加代码的方式,而不是通过修改代码的方式.(内心独

面向对象原则之一 里氏替换原则

原文:面向对象原则之一 里氏替换原则 前言 面向对象有人分为五大原则,分别为单一职责原则.开放封闭原则.依赖倒置原则.接口隔离原则.里氏替换原则. 也有人分为六大原则,分别为单一职责原则.开放封闭原则.依赖倒置原则.接口隔离原则.里氏替换原则.迪米特法则. 现在我们来介绍里氏替换原则 里氏替换原则 1)概念 其概念是子类对象能够替换其基类对象被使用. 听上面的概念好像很简单,不就是父类实现的方法就能被子类实现,父类在外部的调用,替换成子类也可以嘛. 这么理解就错了,这里的概念虽然说得简单,但是其

深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP

前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http://freshbrewedcode.com/derekgreer/2011/12/31/solid-javascript-the-liskov-substitution-principle/ 开闭原则的描述是: Subtypes must be substitutable for their ba

里氏替换原则详解--七大面向对象设计原则(2)

里氏替换原则来源: 我们都知道面向对象有三大特性:封装.继承.多态.所以我们在实际开发过程中,子类在继承父类后,根据多态的特性,可能是图一时方便,经常任意重写父类的方法,那么这种方式会大大增加代码出问题的几率.比如下面场景:类C实现了某项功能F1.现在需要对功能F1作修改扩展,将功能F1扩展为F,其中F由原有的功能F1和新功能F2组成.新功能F由类C的子类C1来完成,则子类C1在完成功能F的同时,有可能会导致类C的原功能F1发生故障.这时就有人提出了里氏替换原则.里氏替换原则这项原则最早是在19