平时只要一提起来面向对象编程OOP的好处,随口就能说出来,不就是封装、继承、多态么,可他们的含义是什么呢,怎么体现,又有什么非用不可的好处啊。可能平时工作中天天在用OOP,仅仅是在用OOP语言,就是一时半会说不出来有什么非用不可的好处,通常是茶壶里煮饺子 —— 倒不出。

  其实回忆一下编程历史,就能知道一些非用不可的理由来了,在面向对象编程出来之前,人们是用面向过程编程来实现软件的各种功能,典型的如VB(非VB.NET),面向过程编程就是一步一步来,先做什么,然后做什么,按照顺序来做,并且不能互换顺序。比如说做饭,面向过程就是一道蛋炒饭,先炒米饭,然后鸡蛋放在一起炒,面向过程呢,就类似盖浇饭,米饭和各类菜都是分开制作,吃的时候,想吃香菇肉片,直接浇上去就行了,不用等上个工序做完。这样一来就各司其职,一方面是节约了时间,另一方面是分离开来,比方说蛋炒饭做好了,客人突然不想吃了,想吃火腿炒饭,那就只能把蛋炒饭倒了,重新开火炒。而盖浇饭呢,直接换想要的菜浇到米饭上就行了,米和菜相互分离,不会说是一次性的买卖,这就是体现了面向对象的易用性、可扩展、易于维护。由于米饭和菜分开了,相当于各司其职,封装起来他们各自的实现,细节不耦合,就体现了高内聚、低耦合的特点,更加灵活多变了,自然就更好开展工作了。面向对象编程说白了就是代码的“管理艺术”,同样的功能,面向过程也能实现,只不过代价更大,改动更不方便,人们当然是怎么方便怎么来,怎么“懒”、怎么省事怎么来(以后更省事)。

  封装就是打包,把相同功能,相似实现的都打包在一起,成为一个类,封装也就是“面向对象”里的“对象”(其实是类,但总不能说面向类编程吧),把一类东西形象化,放在一起,产生关联。和现实生活中的物品对应起来,比如说人就是一类,共同点就是有眼耳口鼻手等,会跑说话等。当然,你在现实生活中,见到的都是人的每一个个体(即实例),如张三、李四等,你肯定说是没有见过人这个东西(非张三李四等任何一个有名有姓的人,而是所有的人),这就是抽象。我们在现实生活中,见到的都是实例化的每个个体,是继承自抽象的类,类只存在于概念中,看不见摸不着,因为类本身就是人们为了方便而分类出来的概念化,属于认知范围,人是抽象化,是一个类,那么张三就是具象化,是一个实体、实例。

  面向对象的抽象,指的是abstract等抽象类,比如人作为一个抽象类,然后有中国人、日本人两个类继承自人这个抽象类。这样一来,人类有眼耳口鼻手等,会跑说话等,那么中国人、日本人两个类只要继承自人类,就有这些属性,如果将来人类发生变异,或者说进化,会飞了,那么只需要在人类这个抽象类加入属性、方法等,中国人、日本人两个类不需要单独去声明、各自增加飞行这个功能了,因为这两个类继承自人类,就有了飞行这个功能、这个方法了,方便快捷,马上就会飞了。

  继承,就是先有abstract等抽象类,然后其他类继承自抽象类,父类的字段、属性、方法等,子类不需要单独去声明添加就有这些。记忆比较深的是类似 张三 is 人类 这样的操作,既体现了面向对象,又体现了继承。

  多态,不同的类,都有继承自父类的字段、属性、方法等,但是在细节上,可以实现不同的表现。比如同样都是继承自人类,中国人和日本人都会说话,但是具体的说话语言,却不一样,中国人说汉语,日本人说日语,这样一来就实现不同的功能。比如一个中国的公司,平时都是面向中国人做生意,有一天需要扩展业务到日本了,要在当地设立分公司,那么不需要让公司的原有的中国人都去学日语再派过去工作,只需要找一些日本人就行了,这就是可扩展性,不修改已有,而是增加。不用修改已有的类,只需要拓展一下,平行添加子类,让子类实现不同的功能,对外展示多态属性。

  多说下两个SOLID的原则。

  里氏替换原则(LSP),子类必须能够替换掉它们的父类,这一条属于正确的废话,为什么呢,子类继承自父类,必然要实现父类的所有属性、方法(可继承的、对外的“接口”),自然能够替换掉父类。

  依赖倒置原则,高层模块不应该依赖于低层模块,两个都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖抽象。还是要解耦,依赖“接口”。里氏替换原则和依赖倒置原则,使OCP成为可能,一个是因为子类可替换父类,子类在外观上,有父类的所有外观,所以可以替换父类,二个是因为高、低层模块不互相依赖,而都依赖于抽象,这样一来有功能变动、增加,就可以平行拓展,而不是修改已有代码。典型的如简单工厂模式、工厂模式等。

  《大话设计模式》中,面向对象的例子,画的类图,动物到狗到猫牛养猴猪,推己及人:

OOP、封装、继承、多态,真的懂了吗?的更多相关文章

  1. 第四课 OOP封装继承多态解析,接口抽象类选择 2019-04-21

    父类 xx = new 子类(); xx.method(); 1 普通方法由编译时决定(左边) --- 提高效率 2 虚方法(virtual)  由运行时决定-- -多态,灵活 3 抽象方法由运行时决 ...

  2. OOP三大核心封装继承多态

    OOP支柱 3 个核心:封装 继承 多态 封装就是将实现细节隐藏起来,也起到了数据保护的作用. 继承就是基于已有类来创建新类可以继承基类的核心功能. 在继承中 另外一种代码重用是:包含/委托,这种重用 ...

  3. 浅谈学习C++时用到的【封装继承多态】三个概念

    封装继承多态这三个概念不是C++特有的,而是所有OOP具有的特性. 由于C++语言支持这三个特性,所以学习C++时不可避免的要理解这些概念. 而在大部分C++教材中这些概念是作为铺垫,接下来就花大部分 ...

  4. java面向对象(封装-继承-多态)

    框架图 理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程强调的是功能行为 面向对象将功能封装进对象,强调具备了功能的对象. 面向对象是基于面向过程的. 面向对象的特点 ...

  5. Java三大特性(封装,继承,多态)

    Java中有三大特性,分别是封装继承多态,其理念十分抽象,并且是层层深入式的. 一.封装 概念:封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据 ...

  6. php面向对象 封装继承多态 接口、重载、抽象类、最终类总结

    1.面向对象 封装继承多态  接口.重载.抽象类.最终类 面向对象 封装继承多态  首先,在解释面向对象之前先解释下什么是面向对象? [面向对象]1.什么是类? 具有相同属性(特征)和方法(行为)的一 ...

  7. Java基础——面向对象(封装——继承——多态 )

    对象 对象: 是类的实例(实现世界中 真 实存在的一切事物 可以称为对象) 类: 类是对象的抽象描述 步骤: 1.定义一个类 (用于 描述人:) ( * 人:有特征和行为) 2.根据类 创建对象 -- ...

  8. Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态)

    Python 入门 之 面向对象的三大特性(封装 / 继承 / 多态) 1.面向对象的三大特性: (1)继承 ​ 继承是一种创建新类的方式,在Python中,新建的类可以继承一个或多个父类,父类又可以 ...

  9. python面向对象(封装,继承,多态)

    python面向对象(封装,继承,多态) 学习完本篇,你将会深入掌握 如何封装一个优雅的借口 python是如何实现继承 python的多态 封装 含义: 1.把对象的属性和方法结合成一个独立的单位, ...

  10. java四大特性理解(封装继承多态抽象)

    封装: 封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口.面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治.封装的对象,这些对象通过一个受保护的接口访问其他对象.封装是一 ...

随机推荐

  1. STL——容器(Set & multiset)之 仿函数(函数对象)functor 的用法

    Set/multiset 中元素的存储数据总是会按照从大到小或者从小到大排列,这个是怎么实现的?这就要说 "仿函数" 这个概念了. 仿函数概念 1. 尽管函数指针被广泛用于实现函数 ...

  2. STL—— 容器(vector)元素的删除

    1. clear() 将整个 vector 都删除 使用 vectorname.clear() 可以将整个vector 中的元素全部删除,但是内存不会释放,如下代码: 1 #include <i ...

  3. 容器编排系统之Kubernetes基础入门

    一.kubernetes简介 1.什么是kubernetes?它是干什么用的? kubernetes是google公司用go语言开发的一套容器编排系统,简称k8s:它主要用于容器编排:所谓容器编排简单 ...

  4. sql注入之union注入

    联合查询注入利用的前提: 必须要有回显 联合查询过程: 判断是否存在注入点 判断是什么类型注入(字符型or数字型) 判断闭合方式 查询列数个数(order by) 5, 获得数据库名 获得表名 获得字 ...

  5. 正交实验法之 Allpairs电商项目用例设计实战

    一.正交实验法概述 正交实验法是研究多因素多水平的一种方法,它是通过正交表挑选部分有代表性的水平组合试验替代全面试验.这些有代表性的组合试验具备了"均匀分散,整齐可比"的特点.正交 ...

  6. Java 8 新特性:日期处理

    1.  Java 8 日期处理新特性 Java 8基于ISO标准日期系统,提供了java.time包来处理时间日期,且该包下的所有类都是不可变类型而且线程安全. 2.  关键类 Instant:瞬时实 ...

  7. feign代码自动生成插件

    简介 feign对微服务之间的http调用做了一层封装,如果B项目想调用A项目的一个web服务,只需要编写对应的接口并标注FeignClient注解.但如果接口发生了变更,对应的Feign代码往往会忘 ...

  8. f12 Network的解析

    Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Network面板.Timeline面板.Profiles面板.Application面板.Sec ...

  9. vue 修改数据

    通过数组中的方法改变数据 变异方法(改变原数组) push() pop() shift() unshift() splice() sort() reverse() 替换数组(生成新数组) filter ...

  10. ES6中的Promise和Generator详解

    目录 简介 Promise 什么是Promise Promise的特点 Promise的优点 Promise的缺点 Promise的用法 Promise的执行顺序 Promise.prototype. ...