《面向对象》读书笔记2

第二章 似是而非:面向对象与现实世界

为什么面向对象和现实世界是似是而非(sì shì ér fēi,意思是好像是对的,实际上不对。出自《庄子·山木》)的呢?

2.1如果只理解概念,就容易混乱

面向对象不是“直接将现实世界表示为软件的技术”。

2.2对照现实世界来介绍面向对象

类(封装)、多态和继承

2.3类指类型,实例指具体的物

类(class)是面向对象的基本结构,与其对应的概念是实例(instance),二者的关系就相当于数学集合论中的集合和元素一样。
这样的关系在现实世界中也很常见。

狗:斑点狗、柴犬、中华田园犬、牧羊犬......
国家:中国、日本、美国、英国......
歌手:迈克尔·杰克逊、周深.....

下面介绍编程。
在面向对象中,我们通过定义类来编写程序,当程序运行时,从定义的类创建实例,他们之间互相作用,从而实现软件的功能。这与在现实世界中,通过人与物的相互作用完成工作的原理非常相似。

class Dog{
  String name;
  Dog(String name){
    this.name = name;
  }
  String cry(){
    return "汪";
  }
}

2.4多态让消息的发送方法通用

多态(polymorphism [ˌpɑˌliˈmɔrfɪzm] ),其英文含义为“变为各种形式”。
如果用一句话来表示该结构,就是“让向相似的类发送消息的方法通用的结构”,也可以说是“发送消息时不关心对方具体是哪一个类的实例结构”。
将该结构比作现实世界,可以做出以下说明:当向狗发送cry的消息时,会得到“汪”的响应;如果接收该消息的时婴儿,的会“哇”的哭;如果是乌鸦,则会发出“呱”的叫声。

class Animal{ //动物类
  abstract String cry(); //在此不定义具体的叫声
}

由于动物分为很多种,所以我们无法定义具体的叫声。因此这里只定义接收cry消息,而不定义具体的动作。

class Baby extends Animal {
  String cry(){
    return "哇";
  }
}

class Dog extends Animal {
  String cry(){
    return "汪";
  }
}

class Crow extends Animal {
  String cry(){
    return "呱";
  }
}

多态是一种方便消息发送者的手法。在上面的例子中,不管对方是谁,指示者都可以发出同一个只是cry。
下面我们来定义教练类(Trainer)

class Trainer {
  void execute(Animal animal){
    //让对方哭(叫),并输出结果
    System.out.println(animal.cry());
  }
}

仅此而已,非常简单。
这里的重点在于,execute方法的参数是Animal类的实例,这样一来,不管对方是婴儿还是狗、乌鸦,都没有关系。不仅如此,即使对方是相扑冠军、职业摔跤选手,或者是狮子老虎、鲸鱼、蛇,只要对方是动物,都可以对应。这就是可以对应所有动物的重继教练。

2.5 继承对共同点和不同点进行系统的分类和整理

用一句话来表示继承:系统的整理物的种类的共同点和不同点的结构。在面向对象中“物的种类”就是“类”,。因此换一种说法也可以:整理相似事物的类的共同点和不同点的结构。

2.6面向对象和实现世界是似是而非的

以上就是讲解面向对象结构的常见流程。
这样的优点是易于直观的理解,能在脑海中留下印象。不过,如果只是这样理解,那么在实际编写程序时就会很难以理解怎样编码更方便。另外,如果说“面向对象是以对象为中心的开发方法,与之前的思想完全不同”,或者说“需要经过多年学习才可以熟练掌握面向对象”等,那么第一次听到这些话的人一定会感觉很迷茫吧。
下面我们看看面向对象和现实世界有何不同。

2.7现实世界的人和物不是由类创建的

面向对象的世界中先创建类,然后再创建实例。
在现实世界中并不是如此。差异很大。
比如狗的生育,公狗和母狗在经过亲密接触以后,母狗怀孕生下小狗,而小狗并不是通过预先定义的“狗”类创建的。
在面向对象和现实世界中,对类的定义有很大的不同。在面向对象和中,类是用来创建实例的结构,实例只属于一个类。而在现实世界中,首先有具体的物(实例),然后再根据观察该物的人的立场和兴趣而采用不同的基准进行分类(类)。比如一个人再公司就是“员工”,与客户打交道时就是“技术人员”,而回到家就是“父亲”,走在街上时就是“路人”。
此外还存在其他不同之处。在面向对象的世界,实例固定属于某一个类,即使经过一段时间,也无法变为属于其他类。由婴儿创建的实例无论经过多少年,也无法成长为青年、中年和老年。
而现实世界中的人则是会成长的,少年、青年、中年、老年。
像这样,即使是类和实例这样最基本的结构,在面向对象和现实世界中也存在很大的不同。

2.8现实世界的人和物,并不只是根据消息来行动

现实世界中的人是根据自己的判断来行动的,虽然有时候也会根据指示,但是这只占很小一部分。
在面向对象的世界中,我们需要为所有的行动都准备好方法,并通过消息传递来调用方法,这样事物才会开始运作。在这个世界“不违背指示”是最基本的。
这样看来,“消息传递结构能够直接表示现实世界”的说法是稍微有些夸张了。

2.9明确定义为编程结构

实际上,类、多态和继承应该别明确定义为能够提高软件的可维护性和可重用性的结构。类用于将变量和子程序汇总在一起,创建独立性高的构件;多态和继承用于消除重复代码,创建通用性强的构件。另外,实例能够在运行时将实例变量在堆区展开,可以轻松地确保类地逻辑。通过熟练掌握这些结构,我们就可以创建出必以往更易于维护的、可重用地软件。
为了避免误解,这里明确一点,那就是仿照现实世界进行地讲解只是一种比喻,大家应该按照编程结构来理解。另外,关于这些结构在编程上地功能,我们将在第4章中详细讲述,关于运行时地结构,将在第5章具体介绍。

2.10软件不会直接表示现实世界

根据到目前为之地讲解,有的同学可能回想:“我现在明白面向对象和现实世界不一样了,但它们又的确非常相似,难道不能采用适当的形式来表示现实世界吗?”
实际上,这里还存在一个可以讨论地内容,那就是系统化的范围,即软件能够在多大程度上涵盖实现世界地工作。
从结论上来讲,几乎所有软件都只能涵盖人类工作地一部分。计算机擅长记忆工作和固定工作,能够记录并在瞬间提取出大量地信息,能正确地执行工资计算或者利息计算等具有固定地步骤地处理。由于软件涵盖这种性质地工作,所以即使使用了计算机,也需要由人来完成,计算机根本无法完全替代人来完成现实世界地工作,因此讨论面向对象是否会直接将现实世界表示为程序本身就是毫无意义的。关于该主题我们会在第九章中详细讨论。

2.11与现实世界地相似,扩大了可能性。

原文地址:https://www.cnblogs.com/ldbstart/p/14430743.html