怎样理解封装,继承,多态!三者的区别?

zhangli0911 2008-12-18 03:07:08
越详细越好!~~大家一起探讨探讨!~~谢谢!~
...全文
4632 85 打赏 收藏 转发到动态 举报
写回复
用AI写文章
85 条回复
切换为时间正序
请发表友善的回复…
发表回复
tongji2008 2010-07-06
  • 打赏
  • 举报
回复
up up up
yanchenyu 2010-03-06
  • 打赏
  • 举报
回复
多态 应该是同一方法在父类子类中的不同实现 ?

子类的方法如果是从父类继承过来的,那这个不同实现是怎么样实现的,使用什么样的方法实现的,字面意思大概能了解,但是总觉得很冲突啊。希望大牛可以仔细的说一说多态。
yanchenyu 2010-03-06
  • 打赏
  • 举报
回复
学习啊,各自的解释都对,但是相互印证估计会有更深的体会。记得有人说过,面向对象,抽象很重要。大牛能不能帮忙着重解释一下。
jjvan 2009-10-22
  • 打赏
  • 举报
回复
学习,mark
微创社(MCC) 2009-10-18
  • 打赏
  • 举报
回复
順便囉嗦一下,磁於接口與類在繼承性上的區別:

接口類型和類類型可以同等對待,
較典型的案例可以看看下面的擴展方法:
System.Linq.Enumerable
在IEnumerable<T>上實現擴展,
這時候跟接口類型跟類類型沒啥區分。

不過在繼變動的層次上,兩者很不一樣。
接口對接口不會造成層次的擴張,
但理論上接口和類的繼層是可以混用的,
抽象基類+接口也是.net框架中的常見用法,
基類用於提供基礎設施建設,接口提供的是契約,
好外是什麼,接口可以切的很小,還可以隨意組合,
順便實現了多繼承,
我的理解是數據應單應當是有層次的,
方法應當是共享的,沒有層次最好,
這時靠的是什麼,是多態。
多態只是內部表現不同,在函數的表意上(把聲明看作一種接口不知對不對)對外的表現是一致的。
微创社(MCC) 2009-10-18
  • 打赏
  • 举报
回复
關於討論的語境:
討論OO時最好把自己置身於一個大環境,
小代碼小構造,無論怎麼折騰都體現不出實際的效果,
這時用繼承,用接口,用組合,
父親與兒子之類的說明不了問題,
只是討論兩種類型之間的關系,談不上OO,只是解決了表像,
這種關系上,看不出任何的價值。

關於濫用繼承:
继承属于牵一发而动全身
需要特別小心考慮父類特別是基類的構造,
这就是典型的“脆弱的基类”问题,
.net框架在有大量的ClassBase命名的基類存在,
继承對对外及子類暴露過多的信息,
謗種情況下可以考慮組合,
GOF的許多模式目的就是为了消除继承。
如何運用继承,重要法则是确定方法是否能够共享,
類說白了,還是數據+方法,
我們看到了過多的是數據上的繼承,
忽略的是方法的共享。
失敗案例:.net中的delegate委托類類,看看其醜陋的實現,
多了一個Mutil中間層次,壞了大事,據說是為了向後兼容性,微軟也後悔的。

關於類的層次
如果出於設計工具庫,框架的目的,
類的深度越小越好,層次越淺越好,結構越小越好,內緊外松,
接口有助於減少層次,
接口的繼承是扁平的,類的繼承是層次的,這是最大的區別。
.net中的集合類,最經典的接口應用,學習一下有助於理解。

關於抽象
OO除上封裝、多態、繼承,還有一個重要的抽象性,提的不多,
其實抽象非常重要,要設計一個基礎類型明,
一定要做到最合適的抽象,千方百計考慮其應用邊界,
不是越多越好,也不是越少越好,而是對環境中其它類的影響程度,
好的抽象:單一職責,高聚度,只暴露必要方法,參數的原子性,最短的似遞路徑,對邊界的影響性要小,
必要的情況下當然是少接口少,少繼承,
標准可以是慮契約的前置性判斷。

其它
分清:运用行为子类型/扩充行为子类型
面向对象的契约,动态环境下违反契约

可以全不信,不可能全信,否則後果自負。
only_lonely 2009-02-23
  • 打赏
  • 举报
回复
暂时是什么也看不明白,不过会快的
orain 2008-12-20
  • 打赏
  • 举报
回复
[Quote=引用 48 楼 sp1234 的回复:]
这其实也是一种很过时的说法。随着进15年OO的流行,过去大书特书“优先使用基于对象的组合,而不是类的继承来实现复用”那些人都掉头来写如何用继承来实现复用了。例如微软在推广COM+体系的时代,几乎所有专为微软推广编程开发语言的编程书都这么说。但是它自己发布了.net战略,大家可以看看.net framework中的实现,例如asp.net控件或者winForm控件体系,不正是使用到了继承了吗?从一个根本不直接支持继承的COM体系过度到支持单继承的.net体系,写微软的编程书的作者于是就改口了。道理很简单,这句话没有一个可操作的原则性,什么叫做“优先”,当被自己证明是可以改变的时候,他就失去了可信性。
[/Quote]
我并不赞同这种说法,软件设计的思想从初始的瀑布模型到增量迭代,再到现在热门敏捷开发,其实是一步一个脚印走过来的,或许一些概念已经变更,但某些思想仍然在继续传承。就像现在 C#、Java满天飞,但是对于基本的数据结构和算法,像语言表面那么热闹吗?你用 C# 实现一个冒泡排序,和用 C 甚至是 Javascript 实现在本质上有很大的区别吗?抛开这些繁华的表面,我们是否有引以为根的东西,我觉得这才是重要的。

我入行的时间不是太长,做到现在快满一年了,外面漂泊了许久,因为种种原因,最后操起了程序员这个职业,抽以在语言特性方面的理解上有些浅薄(呵,除对 .net 框架算是稍有了解之外,对于 COM 什么的纯粹是两眼一抹黑)。但是,我相信,即使在程序设计这个日新月异的行业内,仍然有些东西在很长时间内是不会改变的,而这些是程序设计所共通的,每种语言都不可能绕过的东西。

所以,我不认为一个很重要并且目前仍然很有用的原则会因为时间的流逝而打上过时的标签,从商业的手段来推导技术上的原则,是否有些不恰当呢?况且微软不是全部,更何况微软的控件体系中对对象组合的应用,远多于继承的方式,可以查阅一下 MSDN,几乎每个控件类的下面都有一长串所实现接口的列表,这些接口是用来做什么的呢?

其实我一直有个想法,就是对于需求的变更,尽量做到不更改原有的代码,而是通过增加新的代码,以一种插件的形式添加到原有系统中,这要怎么才能做到呢?必须设计良好的接口,那么就可以动态的用具有新功能的对象替换掉原有的功能模块对象,从而实现系统功能的变更,这其实也是基于一个典型的对象组合的应用。

类与接口在 OO 设计中是不同的概念,这在很多年前就已经是定论了,虽然它们具有类似的表述形式,在一些语言中,还是用抽象类的概念去描述接口。但是,我认为,类侧重的是代码,描述的是它如何实现这个功能,而接口,则侧重于表述一个对象应该实现什么样的功能,而并不关心如何实现,这正是对象能够组合的基础。如果都仅只是类型,.NET 还有 Java 为何要把接口单独定义出来,说接口是类型,那仅只是从编程的角度来理解,而不是 OO 的角度。
  • 打赏
  • 举报
回复
如果你抄袭来的OOPL编程教条中当把接口作为一种既可以当作抽象设计又可以到做组合设计的“万能”概念,从而在接结构化和面向对象双方面各靠一点谱,你会自欺欺人,其实你放弃了研究设计技术而在讨论具体OOPL了。

如果我们仅仅讨论设计,就不要去把class和interface分开,而还原成用来实现类型继承的本来面目。
  • 打赏
  • 举报
回复
实际上,我再重复很多遍大家都能抄来的东西。例如:

[Quote=引用 3 楼 meixiafeng 的回复:]
三。如何判断应该是设计类、子类、抽象类或接口呢?

(1)如果新类无法对其他的类通过IS-A测试时,就设计不继承其他类的类。

(2)只有在需要某类的特殊化版本时,以覆盖或增加新的方法来继承现有的类。

(3)当你需要定义一群子类的模板,又不想让其他人初始化此模版时,设计出抽象的类给他们用。

(4)如果想要只定义出类可以扮演的角色,使用接口。
[/Quote]

我所做的只是讲清:许多人会抄但是未必会理解,我帮你理解。
  • 打赏
  • 举报
回复
如果眼中只有编程语言,而没有设计语言,就很难看清方向。如果你使用c来实现纯粹OO的程序,你如何来实现类型继承?你能够因为此时你的程序中的父类子类是引用关系(因为c的编译机制并不像c++那样实现继承)于是就证明了面向对象设计是你的那种结构化编程的机械组合结果吗?

我在另一个帖子的回复(我给出了链接)中似乎说过:不同的OO语言实现继承的方式是不同的。或许有些语言在编译器实现时,在子类对象内部有一个private的指针指向子类对象独占地创建的一个父类对象实例,并且子类实现了父类的接口属性和方法并且将每一个属性以及方法操作都委派给这个内部父类对象实例。那么你就能够因此说OO继承就是这样的关系吗?这是错误的。OO设计不是如此,这只是某种OOPL这样实现罢了,其它OOPL就不一定这样实现。不论怎样在内部实现,其最终要达到的,就是“标识唯一性”,即这个所谓的父类对象或者所谓的子类对象只要你能够访问,你就会打印出来它们是“同一个”对象。而如果你从这个OOPL的实现机制中得到说“子类对象有一个指向父类对象的指针”,把这种观念用在设计上,就害了你的设计。

我在这个帖子中自始至终再谈滥用继承以及把设计上的继承庸俗化的危害问题。我看到那些仅仅从编程语言来解释OO设计的所谓对“继承、多态”概念解释,希望各位在看到这样的概念时知道它是很有可能滥用的。
qqlpp 2008-12-20
  • 打赏
  • 举报
回复
up
ppp7p 2008-12-20
  • 打赏
  • 举报
回复
学习。。。
  • 打赏
  • 举报
回复
所以,请搞清楚,当评论“A实现了IB接口”时,我是把它看作设计者想实现“A继承了B”类型来看待的,我是在讨论设计时怎样的关系是滥用继承的(韵此也就包括滥用interface)。

在考虑OO设计时没有什么绝对的Interface和class之分,不要以为interface什么都沾点边(又把它说成“表述一个对象应该实现什么样的功能,而并不关心如何实现”又把它说成是组合结构)就可以混淆设计。我实际上,正是要把这种纯粹从编程实现角度去偷换OO设计,最终不知不觉地滥用了概念之间的继承(也就是滥用了interface实现),的危害给讲出来。
  • 打赏
  • 举报
回复
你从编程代码来映射领域设计,多所谓的设计原则会得到很随意的解释。有一个事实,就算使用c的人也可以进行非常好的OO设计并且写出OO风格的程序,而用c++、c#的人可能不如他OO。而当一个人用c写出纯粹OO风格和执行机制的程序时,你纠缠于c语言的语法语句来评判他的程序是否OO(而不是抽象过的设计思想来评判),你得到的一套结论让我觉得跟OO设计没有太大关系。
iloveppmm 2008-12-20
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 greatverve 的回复:]
引用 8 楼 zhangli0911 的回复:
那你们都完全理解这些了吗??
你认为大家不理解吗?这些东西,只有用了先知道。
多态,你写过名称相同,参数不同的函数吗?
继承,你的所有aspx页面,不都是继承Page吗?
封装,你没有自己写过类吗?你类里没有封装方法吗?
[/Quote]

那叫函数重载 不叫多态

多态 应该是同一方法在父类子类中的不同实现

  • 打赏
  • 举报
回复
[Quote=引用 56 楼 orain 的回复:]
所以,我不认为一个很重要并且目前仍然很有用的原则会因为时间的流逝而打上过时的标签,从商业的手段来推导技术上的原则,是否有些不恰当呢?况且微软不是全部,更何况微软的控件体系中对对象组合的应用,远多于继承的方式,可以查阅一下 MSDN,几乎每个控件类的下面都有一长串所实现接口的列表,这些接口是用来做什么的呢?

其实我一直有个想法,就是对于需求的变更,尽量做到不更改原有的代码,而是通过增加新的代码,以一种插件的形式添加到原有系统中,这要怎么才能做到呢?必须设计良好的接口,那么就可以动态的用具有新功能的对象替换掉原有的功能模块对象,从而实现系统功能的变更,这其实也是基于一个典型的对象组合的应用。

类与接口在 OO 设计中是不同的概念,这在很多年前就已经是定论了,虽然它们具有类似的表述形式,在一些语言中,还是用抽象类的概念去描述接口。但是,我认为,类侧重的是代码,描述的是它如何实现这个功能,而接口,则侧重于表述一个对象应该实现什么样的功能,而并不关心如何实现,这正是对象能够组合的基础。如果都仅只是类型,.NET 还有 Java 为何要把接口单独定义出来,说接口是类型,那仅只是从编程的角度来理解,而不是 OO 的角度。[/Quote]

可能你没有仔细看我的帖子。在设计继承结构时,我没有去区分class与interface,也就是说不论是子类class继承父类class还是子类interface实现父类interface或者子类class实现父类interface,在设计上都是继承。这时候,在设计上只可能去讨论有没有滥用继承,“儿子类来实现父亲接口”是否合适。我专门在另一个帖子中讨论了class与interface的玩意,我上面给出了链接,可能你也没有看。从这个帖子和那个帖子可以看出,我没有把class和interface的区别上升为设计问题,我说的继承不是仅仅指class之间的继承。

“而接口,则侧重于表述一个对象应该实现什么样的功能,而并不关心如何实现,这正是对象能够组合的基础。”这是描述组合?这是偷换组合这个概念吧!
zhangli0911 2008-12-20
  • 打赏
  • 举报
回复
一起学习 一起进步。。。面向对象设计到的实在是太广!~需要很长时间的琢磨。谢谢大家的支持!~
a09 2008-12-20
  • 打赏
  • 举报
回复
强帖一个顶顶~~~~~~
a09 2008-12-20
  • 打赏
  • 举报
回复
强帖一个顶顶~~~~~~
加载更多回复(64)

62,074

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧