背景
某一天,伙伴们聊到了设计模式再聊到了java的面向对象思想,不难哥给我们展示了他一贯教导方式,我觉得很有收获,特此记录。
不难哥在我们心目中是一位循循善诱的教育大师,善于用耐心与智慧引导我们探索知识的深奥之处。他总是可以通过细致入微的解释和生动的案例,让复杂的概念变得清晰易懂。
正文
... 跳过我们前面很多话题,不难哥和我们说面向对象思想是一个哲学思想,然后直接从什么是抽象开始聊。
不难: 抽象是什么?
07: 抽象就是把一些实际的方法或者技巧汇总成一种通用的知识体系。
不难: 抽象-是相对概念,其实你描述的所有事物,能被你描述。都是因为大脑做了抽象,只是你没有意识到。什么是抽象?就是从真实的无限细节和属性中提炼出来你关心的。比如:你想象一只真的猫,然后你来描述这只猫。try it~
07: 它橙色的,毛茸茸,眼睛大大的,胖嘟嘟,一看就知道抓不到老鼠。
不难: ok,它的胖瘦如何?他的眼睛是什么颜色的?眼睛的瞳孔是什么颜色的?瞳孔的大小是怎么样子的?瞳孔的的分布是什么样子的?你给我描述的时候 为什么不说这些特征?
07: 因为我想象不出来啊。 [自弃...]
不难: 一个物体,在你眼前实在的存在的物体,当你尝试用文字、语言描述的时候就做了抽象。不是你想象不出来,而是没有必要想。
07: 为啥呢?
不难: 因为在我叫你描述猫的时候 你的大脑建立的猫的模型只有这些特征。
07:是的。
不难: 一个真实存在的物体 存在无限的细节,也就是无限多的属性,而你描述的时候 你只从中截取了很少一部分属性,这个截取的属性的过程 就叫,叫什么?
07:抽象!
不难:没错,那么和抽象相对的叫具体 对吧?
07:嗯。
不难: 那么截取属性叫抽象 具体是在干什么?
07: 具体就是...(挠头中)
不难:兄弟,具体就是添加属性啊!
07:好深奥的话,[难过...] 。
不难:慢慢来,我再问你,猫变了没?
07:没有吧,不知道它掉毛没。(原谅我这种悟性...)
不难:当你描述"它橙色的,毛茸茸,眼睛大大的,胖嘟嘟,一看就知道抓不到老鼠" 和 "它橙色的,毛茸茸,眼睛大大的,蓝色的瞳孔,5根胡须,胖嘟嘟,一看就知道抓不到老鼠"。这两种描述,第一个属性少,第二个属性多,对吧?
07:是的。
不难:猫变了吗?
07:这题我懂,没变。
不难:是啊,猫没变,但是你的描述变了。这就是描述的层次不同。真实存在的猫,还是具有无限多的属性,哪怕一根毛,都能被描述成无限多的词语。对吧。
07:是的。
不难:但是你去描述的过程-就是选取你关心的属性 描述出这些属性的值,这些属性的集合,就叫模型。
不难:所以说,抽象 就叫建模(建立模型)。而这些你关心的属性的集合---就叫模型。明白了吗?
07:嗯~。
不难:那我们继续~ 听说过战国时候有个公孙龙吗?如果没听过 baidu下,了解下先。
07:了解了一下,他有个有个厉害的言论,白马非马。
不难:那么我们下面的讨论就是 白马 到底是不是马?
不难:当你描述"它橙色的,毛茸茸,眼睛大大的,胖嘟嘟,一看就知道抓不到老鼠" 和 "它橙色的,毛茸茸,眼睛大大的,蓝色的瞳孔,5根胡须,胖嘟嘟,一看就知道抓不到老鼠"。这两个论述描述的是不是同一种东西?
07:是的!都是猫。
不难:没错,橙色的猫 、大眼睛的猫、长尾巴的猫 都是猫吧?而且很可能是同一只猫。
07:对,是这样的。
不难:从咱们第一部分可以知道,猫这个概念和橙色的猫、大眼睛的猫、长尾巴的猫 这些概念相比,猫是更抽象的层次的,橙色的猫 、大眼睛的猫、长尾巴的猫 这些是更具体的层次。
07:是的。
不难:当然 抽象和具体是相对概念哦。橙色的猫 、大眼睛的猫、长尾巴的猫 也可以更具体`` 更更具体 直到无限细节对吧。
07:嗯。
不难:那么再讨论 向上去讨论。猫、老虎 和 狗 和 橙色的猫 、大眼睛的猫、长尾巴的猫 这些 是不是都是动物。
07:是。
不难: 猫、老虎 和 狗 和 橙色的猫 、大眼睛的猫、长尾巴的猫 、细菌、病毒、花草树木这些 是不是都是 生物。
07:是的。
不难:你看 一些东西能不能归一类 跟这些东西本身没有关系吧,只根你关心模型有关系,对不对?
07:对。 是和归类模型有关而已。
不难:所以 白马 是 马吗 ?
07:看它在哪个模型里。
不难:如果是马这个模型。
07:那就是马。
不难:看这句话 :猫、老虎 和 狗 和 橙色的猫 、大眼睛的猫、长尾巴的猫 这些 是不是都是动物。猫、老虎 和 狗 和 橙色的猫 、大眼睛的猫、长尾巴的猫 、细菌、病毒、花草树木这些 是不是都是 生物。我们可以看到 在你的模型里面 动物是不是比猫的细节少,关注细节少?
07:对,范围大了。
不难:关注细节少 就是抽象层次高。
07:确实。
不难:我们在建模的过程中 把抽象层次高的 称之为父。一个模型 描述了一个符合模型的集合 我们称之为类 。所以 抽象层级高的集合 称之为 父类。更具体的就叫子类。
07:对。
不难:但是你要知道 这些都是相对的。
07:嗯。
不难:真实的东西有无限的细节,你的描述--只是你当下关系的一些细节,你的代码---是不是一种描述呢?是不是一种建模呢?
07:是的。
不难:ok,第二阶段结束了,其实我讲了面向对象中的两个概念,但是没点名。
07:抽象模型的过程我理解就是封装。白马 和 马 、 猫 和动物的关系就是继承~
不难:那我们继续?
07:go on~
不难: ok,现在你很寂寞,你需要一个宠物。请问,我为了讨好你 可以送你一只猫吗?
07:可以啊。
不难:我可以送你一只狗、一个鹦鹉、一个小鱼吗?
07:可以啊,我的目的是取乐,和宠物品种无关。
不难:假如你现在饿了 想吃你妈亲手做的面,第一天你妈做了一碗面,里面加了一些青菜。第二天,你还是同样的需求 但是你妈做的是陕西的油泼面。这样行不行呢?
07:可以啊。
不难:再说一个例子,你说我们人类是不要小便?
07:要。
不难:那整体的来看 小便的表现形式有几种?
07:2种咯,男性站着,女性坐着。
不难:没错,结合三个例子看看。
不难:你需要宠物的时候,猫``狗都可以,你吃面的时候,汤面、干面都可以。人类小便的时候 可能是站着,可能是蹲着。你看这种关系。
不难: 宠物 --- 猫、狗、面 --- 汤面、干面、人 --- 男人、女人。从人的角度看 是相同的模型,那么再细节一点 加上性别的属性,是不同的模型。那么对于相同的行为,是不是表现了不同的形式?人的小便行为,表现了不同的形式。
07:是的。
不难:那么专业点,是不是父类的方法 子类可以有不同实现?
07:对。
不难:那这是啥?
07:多态!
不难: 同样是做面,做面的方法和辅料有很多种,对应起来-->同名函数,不同的参数签名和调用形式,这个叫重载,也是多态的表现形式之一。
07:噢~
不难:人的那个例子叫重写:男人和女人,重写了人的尿尿方法。所以,多态就是重载和重写。
07:666
不难:但是背后的逻辑 还是 抽象 和 具体 建模的逻辑,所以 面向对象 就是一门 抽象建模的哲学思想。
07:真强。
不难:然后看第一个例子,这个 是什么 呢?你需要一个宠物,宠物是不是都能陪伴主人,那么我转换成代码哈。

不难:有没有问题?playWithPeople 方法是不是体现了多态的特性?
07:没问题。
不难:这里声明的是啥?

07:我取乐的宠物。
不难:这是不是就是我给你讲的例子(我需要一个宠物陪我玩)的代码实现?

07:是的。
不难:进一步,继续以下代码:



不难:playWithMyPet 行为一样吗?
07:不一样。
不难:这是什么?
07:多态。
不难:是的,我这个代码 就是最简单的策略模式(设计模式中一种)。
不难:我们把Pet定义为抽象类,对吧。
07:是的。
不难:比抽象类更抽象 就是 接口。

不难:虽然定义是一样的,但是感觉不一样,比如:布娃娃。

不难:抽象类的感觉是 我这个东西的父类,细节更少的那个东西,接口是 只要能满足这个功能的 我都可以作为...。一个侧重行为, 一个侧重属性。修改这个People类,给你一个布娃娃,你也可以当宠物。


不难; 所以, 分析下 修改之前 People在乎的是猫 或者 狗吗?不是 他在乎的是宠物。修改之后 People在乎的是具体啥东西吗 ?不是而是可以让他 调用playWithMyPet的东西。任何东西只要有 playWithPeople(实现) 这个方法 都可以。这就是interface了,而不是咱们前端在react里面写个IProps。
不难:好了 三大特性到此为止 相信你差不多能领悟点了。
07:多少悟了点。
不难:别多少啊,你全得悟啊~兄弟。
07:还得细品。
不难:对了 还有一个有意思的:抽象这里哈,刚才不是说了么,真实的事物是不变的 有无限细节的 只是我们建模有一个角度 才让事物有了或多或少的所谓属性。
07:嗯。
不难:好 那么一只猫,我可以把他看作是动物吧?
07:可以。
不难:那么来了一只不知道是啥的动物,或者黑夜中 你在野外露营 感觉有个动物来了 两个眼睛放光 你这时候 能不能把这只动物看作猫?
07:看起来像估计会说像,类猫。
不难:你只看到了两个眼睛放光,万一是老虎呢,所以你不敢说对吧?
07:嗯。
不难:ok 把猫看成动物,把动物看成猫,这都叫强制类型转换,但是区别是:子类转父类 是 安全的,父类 转子类 是不安全的。安全的意思就是 子类一定是父类 但是 父类 可不一定是子类。
07:有意思有意思。
不难:品吧,理解下,多在生活中用这种思路去描述。这是OO观察世界的角度,核心就是你先理解抽象。
后话:
很感谢这种年代还能遇到这样的朋友,肯花心思和时间和你去讨论一个他早就掌握的点~respect