引言
在OO的工作中,我们一定会涉及到类,抽象类和接口。那么类和抽象类以及接口到底扮演的什么角色?
本文主要是从人类社会的角度阐述类与抽象类以及接口的“社会”关系,从而让我们抛弃书上的那些死记硬背的概念,快速理解他们的区别与联系?
如果大家觉得还有必要把这块更新的更好,还请多多反馈。
如果觉的对您有用还请点击 “推荐”下,我会持续更新更多新的内容。
古老的传说
相传盘古开天劈地后,女娲一天在黄河边梳头时,突发奇想以泥土仿照自己抟土造人,创造并构建人类社会。后来又替人类立下了婚姻制度,经过一代又一代的繁衍生息,创造今天伟大的文明社会。
OO的诞生,虽然没有“女娲造人”这么传奇,但OOP是软件开发历程又一重要历程碑。并且它的诞生和“女娲造人”有着极其类似的思想(或者说如出一辙)。
下图所示变成语言发展简史:
回到本文的主题来!
对照人类社会的诞生传奇史,我个人认为这两个社会有着极其类似的社会元素和运作规律,请看下表:
人类社会 | OO的社会 |
人(抽象的人) | Class |
父母的角色 | Abstract |
职位或者岗位 | Interface |
具体怎么理解?让我们慢慢道来。
类(Class)
类和“女娲造人“中的人有着极其类似的相似,他们都是社会中的基本单元。社会中的一切活动最后都是有这些基本单元来完成的,当然这些基本单元又有自己的一些特性。
私有空间 private
每个人自己私有财产外,还有自己小性格(行为体现性格)。
类也一样有自己私有的(private)属性、字段和行为。
家族遗传 protected
人做为大家庭中的一员,必然可以从父类那里继承到一些财产,和行为习惯。
类也一样作为类家庭中的一员,会从父类那里继承到了一些受家族保护(protected)属性(或者字段)和行为。
社交空间 public
人作为社会的一员,必然有各种社交活动。为了更好协作,每个都会向别人提供了一些公开的东东。(有钱的出钱,没钱的出力)
类,作为OO社会的一员,为了完成各种功能。我们也都提供了一些必要的公开的(public)的属性和行为(字段不提倡公开)。
远亲不如近邻 internal
”远亲不如近邻“有生活阅历的人,一定深深懂得这句老话。
OO社会也是这个里。 如果一个类中定义一个(internal)的属性和方法,那么这些方法可以被在与其无父子关系的类中直接调用。(当然实例方法要通过实例来调用)
接口(Interface)
既然我们是人类社会中的一个普通人不是生活在武侠小说里的”大侠“,所以你为了养家糊口还必须找个差事。
差事有分为了好多类,每类差事就是一个工作岗位如“销售经理”,岗位职责定义了一系列岗位工作内容,同时他也可能始终权利的载体。赋予了“销售经理”这个职位的人就有了管理销售的职责和权利。
OO的社会中也一样,Interface就像一个岗位。同样定义了一些工作内容和权利(属性和字段),类通过实现接口(掌握相应的技能)来让自己满足该岗位的需求。因为岗位本身没有生命所以Interface自己不能被实例,只能创建实现了该接口的类。
为啥职责要毫无保留的公开?
既然 岗位职责所以你所有的内容都应该是公开(public)的,并且是毫无隐私的,没有一丁点灰色地带。因为既然你作为一个管理层且作为一个部门的接口人,那你的资源和职责首先得公告天下。藏着掩着别人就无法在遇到问题是找到合适管理层接口人去解决相应的问题。
为啥职位不能有私有空间?
既然是管理层那么难免会出现“权利寻租”的情形,在追求廉洁公正的社会里,就不应该让这种思想作恶。
所以在OO的世界里如果你是按职位去调用类的话,你的权利是被锁在笼子里的,OO内部机制会把具体的类先转换成接口类型,然后再执行接口内的的公共属性和方法。
高薪养廉
大家都知道,既然有“经理”的头衔,那么你的薪酬中自然会多出一块岗位薪金,用于支付你所在岗位付出的辛劳。
OO社会中也一样如果某个类 A 实现接口 IA
Interface IA{void Execute();}Class A:IA { void Execute(){…};}Class Program{A a1=new A();IA a2=new A();
a2.Execute();//
付出的代价更高,需要类似转换
a1.Execute();}
抽象类(Absctract)
“世界上最关心你的人是你的父母”-抽象类就像父母这个角色。不论是富二代,还是穷二代,父母都会不遗余力的帮助孩子。给你一定财富(property)同时还替你包办了一些工作,但他们再对孩子亲也有父母自己的私人空间。
私人空间 private
最亲近的人也有各自的私有空间。
OO社会也一样,子类不能访问到父类的私有(private)成员和方法。
孩子自己必须自力更生 abstract
父母对你再好也不能替孩子吃喝拉撒,这些事情必须亲历亲为。
OO社会中,父类通过定义抽象的(abstract)的属性或者方法,来强制子类必须实现某些属性和行为。
父母情愿包办 protected
父母是永远都是孩子最坚强的后盾。你上学父母给你送钱送粮还虚寒温暖,你结婚父母还在
因为在父母的眼里,孩子永远都是孩子,虽然他们已经有了自己的小家还有了自己的孩子。
OO社会中抽象类会有一些家族保护(protected)的属性和方法供子类直接使用。
父母更希望“青出于蓝而胜于蓝”virtual
有时候父母还觉的我们年轻,总想替我们做些事情。但他们更希望孩子自己去做必要的时候再来找父母帮忙。
OO中的Virtrual就是这样的。父类中的Virtual方法大部分的时候都会提供一些实现,如果子类没有特殊情况可以直接使用父类的方法,但如果子类的方法有特殊处理可以覆盖(override)掉父类方法,当然也可以通过base来调用父类同名的方法。
C++中的“乱伦”
C++中允许多继承。在语言设计的初期绝对只是考虑到了代码重用,但却不经意间造成这种”乱伦“情况。
所以学习和使用C++时我们还是尽量避免这种多继承的出现。让我们的代码更好维护。
小结
岗位职责(Interface)和 父母角色(侧重类型如:富一代父母,穷一代父母)(Abstract) ,他们可以被理解为一个抽象的东西,看不见摸不到但是的确存在。他们的存在一定(必须)借助具体的类来体现,自己无法在OO的社会中单独出现。所以接口和抽象类无法被直接实例化只有借助子类来实例化。
岗位职责(Interface)特殊之处,它只是一个让所有人知道的职责列表和其可以拥有资源列表,说到底它就是个清单没有实际的财富更没有实际行为能力,它不像父母将来可能要生儿育女,所以父母可以有自己的各种财产(各种类型(private,protected,internal,public)字段和属性)和各种各样的行为(方法)来为自己和子女的生存,生活来做准备。
父母总会为孩子多考虑一点,但岗位职责就只会给你一份职责清单。接口中没有Virtrual,而Abstract Class可能有virtual方法,来为子类提供公用的功能,如子类更希望独立,可以重写为自己的功能,当让你可以随时调用父类的相应功能,只需通过base来呼出(调用)。
有些更“关心”(溺爱)孩子的父母(当然也有实力如富二代,官二代等)会为孩子代劳。某些Abstract Class 会通过protected 修饰符实现的方法来为子类包办其功能,他们也算是OO中的富二代吧。
但纵然父母在“关心”孩子,有些事情还是必须让孩子自己完成的,那就是吃喝拉撒等。(Abstract Class中的abstract方法或者属性就必须让子类(非抽象类)实现)。
回顾下OO中定义
类
“唯我独尊,舍我其谁”--Class撑起了OOP世界的天。Class类是OO的基本单元,OO的世界都是通过一个一个的类协作完成的。
面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是一种,同时也是一种程序开发的方法。对象指的是(Class)的实例。它将作为的基本单元,将程序和其中,以提高软件的重用性、灵活性和扩展性。
类(Class)定义了一件事物的抽象特点。通常来说,类定义了事物的属性和它可以做到的(它的行为)。类有以下三个基本特性:
- 封装。
- 继承。
- 多态。
接口
接口定义了所有类继承接口时应遵循的语法合同。接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分。
接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
抽象类
抽象类对多个相似类的再次抽象,实现代码复用或者实现依赖注入。
接口与抽象类的异同
相同点:
1.他们都不能实例化自己,也就是说都是用来被继承的。
2.抽象类中的抽象方法和接口方法一样,都不能有方法体
不同点:
1.抽象类里可以有字段,接口中不能有字段.
2.抽象类中的普通方法可以有方法体,而接口方法没有方法体。
3.接口中的方法不能有访问修饰符,抽象类中的抽象方法被继承,需要override重写 .
4.接口更像是一种规范,一种约束。
5.一个子类只能继承一个抽象类,但却可以继承多个接口。
接下来是抽象方法和虚方法的异同:
其实可以把抽象方法看做是没有方法体的虚方法。
相同点:
1.抽象方法和虚方法都可以被重写。
不同点:
1.abstract 和virtual的关键字不同
2.抽象方法一定没有方法体,而虚方法可以有方法体。
参考
UPdate:2015-08-11 15:19:23 错别字修改 。(自立根生 -->自力更生)