`
yfy_cpp
  • 浏览: 12870 次
  • 来自: 南昌
最近访客 更多访客>>
社区版块
存档分类
最新评论

面向对象主要概念(转)(文后附CSDN面向对象思想讨论贴)

阅读更多
原文地址:http://www.cnblogs.com/Autumoon/archive/2008/08/19/1271589.html

说实话,面向对象是个很大很广的概念,我可不敢在园子里瞎白活,以免“误入牛群深处,引来砖头无数”。但是作为面试常考的题,又不得不列举出来,在此,我主要是和大家一起回顾一下面向对象中的几个核心概念,温故罢了,绝无它意。

说到面向对象这个概念很大很广,其实我觉得也不必被这个“很大很广”吓着了,学习面向对象思想,切不可将其专门孤立为一门学科来学习,其实面向对象就在我们日常生活当中,随时随处都能见到,而不仅仅是软件开发。软件开发不过是把我们人类看待世界的思维方式总结抽象出来用到程序设计上,起了个名字叫“面向对象”,可千万别被专业术语给镇住了,IT人士有这毛病,喜欢故弄玄虚,其实例子太常见了,你家马桶就是面向对象的。

面向对象有三个要素:封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。把英文也写出来不是卖弄而是给大家伙儿提个醒,很多时候不错的公司面试往往会用英文,可千万别在词汇量上栽跟头,太不划算了。好,废话少说,接下来我们就来挨个儿探讨以上三个概念吧。

什么是封装?面向对象思想有个忌讳,那就是把对象自己的属性和内部实现细节暴露给别的对象,虽是代码但也应该享有隐私权。把不想或者不该告诉别人的东西封起来,把可以告诉别人的公开,这就是封装的基本概念。那什么是该封装起来什么是该公开的呢?很简单,我们来看看下面这段代码:

  
1: public class Person
   2: {
   3:     public string Name { get; private set; }
   4:     protected int age = 0;
   5:  
   6:     internal void SetName(string name)
   7:     {
   8:         if (String.IsNullOrEmpty(name))
   9:         {
  10:             return;
  11:         }
  12:  
  13:         this.Name = name;
  14:     }
  15: }

我们声明了一个Person类,里面有一个Name属性。注意,Name属性的访问器(get)是公开的,但设置器(set)是私有的,试想一个人如果走在大街上谁见了他都可以给他取个名字,那岂不乱了套了。但人又不能没有名字,所以有一个SetName的方法,前面说了名字不是谁都能取的,因此我们给这个方法加了一个internal访问修饰符,也就是说当前程序集里可以调用,我们把“当前程序集”设想成这个人所在的家庭,一个小孩子生下来,可能是爷爷奶奶给取名,也可能是爸爸妈妈取名。另外,还有个protected的age属性,女孩子的年龄往往是比较保密的,一个女的听到人家说:“啊,你都35了呀!”肯定不会开心的,所以保护起来,小心别让人知道为好。不论用什么访问修饰符,封装的目的就是根据类之间的关系与设计需要,把不该暴露出来包裹好,把可以让别的对象调用的公开,让对象在内存里活得井然有序。如果你有点儿拿捏不准什么是该暴露出来的什么是该封装起来的,那么你就联系到实际生活中的例子去想想。看看你家的马桶,放水的按钮是暴露出来的,但您按下按钮之后内部是如何运作把水放出来的,这就不用用户关心了,自然也就封装起来了,如果您还印象不够深,那就想想,马桶排水的管道应该暴露还是封装起来呢。

也许有朋友会问,既然女孩子的年龄是隐私,那么为什么不干脆用private呢,这样岂不是封装得更彻底?嗯,只要private了,除了自己,谁都甭想知道。这比较适合犯罪记录,比如“private int _killedPeopleAmount;”我们之所以把age属性设为protected的,就是考虑到面向对象的另一个概念:继承。

所谓“龙生龙,凤生凤,老鼠的儿子会打洞”。同类的事物,可以把公共的部分抽象出来放在基类中,子类去继承,就不用在每个子类中都单独声明了。如果把age设置为private,子类将不能继承,不符合面向对象的思想。请看下面这个类:

   1: public class Chinese : Person
   2: {
   3:     public object HuKou { get; set; }
   4: }

我们把上面的Person类当作人类的基类,其中的Name和age以及SetName方法都是人类共同的地方,因此声明Chinese的时候只需要继承Person类就可以获得这些属性和方法,没必要自己再去重新声明一遍。精力用在刀刃上,考虑Chinese类的属性和方法的时候只需要考虑那些具有中国特色的就行了,例如户口。

接下来我们来探讨探讨什么是多态。所谓多态,中国有句古话可以概括:龙生九子,种种不同。都是龙的儿子,又各有差别,不过这样说起来有点儿泛泛,只是辅助记忆而已,可千万别在这上面认死理儿。多态有两种表现方式,一是同一个类中有多个名字一样但签名不同的方法;二是子类改写父类中方法的内部实现。其实“龙生九子,种种不同”这个概括只能映射其中第二点表现方式,也就是virtual和override之间的关系。至于第一点嘛,可以追溯到多态的英文单词的起源,据说这个词来源于西方神话故事里一个叫Polymorph神,他具体从事什么工作不重要,关键是他有个特点,白天一个样晚上一个样,同一个人表现出不同的样子,人格分裂的典型临床症状,软件开发前辈将他抽象成面向对象中的“多态”,可以很好地解释方法重载。

首先我们来看看方法重载:

  
1: public class UserManager
   2: {
   3:     public object GetUser(int id)
   4:     {
   5:         // TODO: Find this user instance by id.
   6:         return new object();
   7:     }
   8:  
   9:     public object GetUser(string name)
  10:     {
  11:         // TODO: Find this user instance by name.
  12:         return new object();
  13:     }
  14: }

我们假设有UserManager这样一个工具类,提供了获取用户实例的机制,但又有两种方式,一是通过id另一种则是通过name,通过方法重载,我们只需要变动一下方法的入参数据类型从而改变了函数签名即可,没必要分别声明GetUserByID和GetUserByName两个方法,那样的话会让整个类在被调用时显得很臃肿,要不然像MessageBox.Show这样提供21种重载方式的方法,对于开发者和设计者来说岂不都是噩梦?

根据我的经验,面向对象在面试中主要考察的部分就是多态,而在多态中主要考察的就是virtual和override之间的关系。我们来看码说话吧:

  
1: public class Dragon
   2: {
   3:     public virtual void Fly()
   4:     {
   5:         Console.WriteLine("I'm flying.");
   6:     }
   7: }
   8:  
   9: public class DragonSonA : Dragon
  10: {
  11:     public override void Fly()
  12:     {
  13:         base.Fly();
  14:     }
  15: }
  16:  
  17: public class DragonSonB : Dragon
  18: {
  19:     public override void Fly()
  20:     {
  21:         Console.WriteLine("I can't fly.");
  22:     }
  23: }

这段示例代码比较浅显易懂。我们声明了一个Dragon类,它有一个飞行的方法,因此它可以在天上随意地飞,它的儿子也会从他那里继承到这个飞翔的方法,但又“种种不同”,有的龙恐怕并不会飞,例如DragonSonB。甭管龙的儿子是不是都会飞吧,这段代码主要是展示一下,在父类中有的方法虽然会被子类继承,但将来在子类使用时可能有不同的实现机制,这时候就需要在父类中声明该方法时加上virtual关键字,以表示将来是可以改写的,在子类中需要则使用override关键字,表示儿子自有主见。

很多时候面试官会围绕virtual和override问一些其它情况,例如如果父类里面的方法没有virtual关键字,光是子类里方法前有override关键字呢?这种情况不用多想,语法错误,就算面试官答应,编译器也不会答应的。需要注意的是,如果子类里继承的方法如果没有override关键字,会是怎样呢?当我们把DragonSonB.Fly方法前的override关键字去掉,这种情况编译器在编译的时候会默认在函数声明前面加上一个new关键字,这就阻断了继承链,也就是说DragonSonB.Fly和Dragon.Fly没有什么关系了,只不过方法名雷同而已。具体怎么体现呢?我们来试试下面的代码:

   1: static void Main(string[] args)
   2: {
   3:     Dragon dragon = new DragonSonB();
   4:     dragon.Fly();
   5:  
   6:     Console.ReadLine();
   7: }

调用dragon.Fly方法时,编译器会顺着继承链往下找,一直找到合适的那个方法体。如果DragonSonB.Fly方法有override关键字,则说明它是从Dragon那儿继承来的,因此dragon.Fly实际上调用的是DragonSonB.Fly,输出结果就是“I can’t fly.”。但如果DragonSonB.Fly去掉了override关键字或者换成了new关键字,那么就意味着这个Fly方法不再是从Dragon那儿继承来的了,因此在调用dragon.Fly方法时,继承链就不能到达DragonSonB.Fly方法而只能停留在它的上一级,也就是调用Dragon.Fly方法。

搞清楚了上面提到的概念,估计面试中面向对象尤其是多态部分问题就不大了,还请各位高手不吝赐教,多多补充完善!


========================================================================


附:CSDN中的一个面向对象讨论贴。
"到底什么叫做面向对象?" http://bbs.csdn.net/topics/220013605
分享到:
评论

相关推荐

    面向对象编程:C++与Java比较教程 英文版

    第3章详细讲述了“类”的概念,这是面向对象编程的核心之一,同时介绍了其他一些关键思想。 第4章探讨了字符串在C++和Java中的处理方式,包括字符串的定义、操作和相关函数。 第5章教授如何使用容器类,这些类是...

    面向对象与UML资料

    面向对象与UML 第一部分 软件开发活动 7 第一章 结构化的分析与设计 8 第一节 模型图 8 业务流程图 8 数据流图 11 功能结构图 12 功能树 13 网络结构图 14 程序流程图 15 第二节 需求分析 15 需求分析的任务 15 需求...

    数据结构(用面向对象方法与C++语言描述)课后答案

    《数据结构(用面向对象方法与C++语言描述)》是由殷人昆编著的一本经典教材,专注于讲解如何利用面向对象编程的思想和C++语言来实现和理解数据结构。这本书的第二版提供了深入的数据结构理论,同时也强调了实际编程...

    面向对象设计UML实践(第2版).pdf

    首先,面向对象设计(Object-Oriented Design,OOD)是一种基于对象概念的软件设计方法,它强调以类和对象为中心,通过封装、继承和多态性等原则来构建可维护、可扩展的系统。在书中,作者会详细介绍类的定义、对象...

    C++面向对象初学者教学 源程序大全

    这份资料涵盖了许多关键的C++面向对象概念,如类、对象、封装、继承、多态性、模板、运算符重载、输入输出流和异常处理。 首先,让我们详细讨论一下这些概念: 1. **类与对象**:C++中的类是定义数据结构和操作...

    软件工程思想 csdn 这个长度检查真垃圾!!!

    - 介绍了面向对象编程的基本概念及其在C++中的应用。 - 分析了类的设计、继承、多态等核心概念。 - 提供了具体的代码实例,帮助读者更好地理解和实践。 7. **第七章:测试与改错** - 讨论了软件测试的重要性...

    C++编程思想(第2版)

    - **第1章:对象导言**:介绍面向对象编程的基本概念。 - **第2章:对象的创建与使用**:讲解如何创建和使用对象,涵盖了现代面向对象设计的原则。 - **第3章:C++中的C**:介绍C语言的基本知识,为学习C++打下基础...

    C++编程思想 经典版

    《C++编程思想》是Bjarne Stroustrup所著的一部经典著作,它深入浅出地阐述了C++语言的核心概念和编程技巧。这本书以其全面性和深度深受程序员喜爱,对于学习和理解C++有着不可替代的作用。在本书中,作者不仅讲解了...

    CSDNVC.rar_visual c

    然后,理解面向对象编程思想,包括类、对象、继承、多态等概念。在CSDN的论坛中,你可以找到许多详细的教程,帮助你逐步构建这些基础。 进阶学习中,你需要掌握如何使用MFC进行Windows程序设计,理解消息循环、窗口...

    软件工程思想——值得下载的书籍

    8. **面向对象程序设计的特点** 9. **测试与改错的关键步骤** 10. **软件维护与再生工程的意义** #### 知识点详述 **1. 软件工程的历史背景与发展** - **起源**:软件工程概念起源于20世纪60年代,当时随着计算机...

    javascript 设计模式 电子书 英文版

    - **第1章:简介**:这一章主要介绍了面向对象编程的基本概念以及为什么JavaScript是一种适合进行面向对象编程的语言。 - **第2章:封装**:讨论了如何通过私有变量和方法来实现封装,保护内部状态不受外部干扰。 - ...

    Java学习路线(csdn)————程序.pdf

    面向对象的核心思想,如封装、类的设计、对象、属性和方法,以及构造器、对象管理、方法重载。 3. **继承与抽象**:讲解了继承的意义、规范、使用场景,以及访问限制、上转型对象、方法重写、super关键字。此外,还...

    Java语言程序设计-1-Java概述

    Java语言程序设计的学习涵盖了从基础概念、面向对象的方法、图形用户界面(GUI)设计等多个方面,是信息技术相关专业的基础课程之一。 计算机是可编程的设备,能够自动执行存储的指令集,进行数值计算和信息处理。它...

    thinking in c c编程思想

    1. **对象导向编程(OOP)**:C++是一种面向对象的语言,它强调封装、继承和多态性。书中通过实例解析了如何将现实世界的概念转化为程序设计中的类和对象,以及如何利用这些特性来构建可维护和可扩展的代码。 2. **...

    C嵌入式编程设计模式(pdf 压缩)

    《C嵌入式编程设计模式》是一本专为嵌入式系统开发者编写的书籍,它以C语言为基础,结合面向对象的思想,深入探讨了在有限资源的嵌入式环境中如何高效、灵活地进行软件设计。这本书的目标是帮助读者理解和应用一系列...

    Thinking In Java第四版(中文版)

    这本书深入浅出地介绍了Java编程语言的核心概念和技术,是理解Java面向对象编程思想的重要参考书。以下是对该书内容的一些关键知识点的概述: 1. **Java基础**:书中首先介绍了Java的基本语法,包括数据类型、变量...

    1 Modelica 3.2_介绍

    后续研究者在此基础上引入了“类”这一概念,用于封装物理系统的方程,这标志着面向对象统一建模思想的初步形成。1996年,欧洲仿真协会EUROSIM组织了多个国家的专家,共同探讨多领域物理统一建模技术,促成了...

    Java自学过程[收集].pdf

    首先,成为一名初级Java程序员的关键在于理解和运用面向对象的思想。面向对象编程(OOP)是Java的核心,你需要理解对象、类的概念,以及封装、多态、继承等核心特性。同时,抽象类和接口是实现模块化和扩展性的重要...

    设计模式java

    很多模式在Java等面向对象的编程语言中得到了广泛的应用。在本文中,将会介绍一些在Java中常用的设计模式,并结合Java的特性加以讨论。 首先,设计模式通常被分为三大类:创建型设计模式、结构型设计模式和行为型...

    Head first design pattern

    书中的案例代码多采用Java语言,但设计模式的原理和思想适用于任何面向对象的编程语言。 总的来说,这本书是理解设计模式、提升软件设计能力的绝佳读物。无论你是刚接触设计模式的新手,还是希望深化对设计模式理解...

Global site tag (gtag.js) - Google Analytics