浅谈Java的面向对象

这一部分的内容是我曾经写过的一篇教程的一部分

Java程序的运行

Java是一门编程语言。

用Java编写应用的最大好处就是写一次就能在多个平台运行。
例如有些用户是Windows用户,有些玩家用的可能是苹果电脑,我们不至于为多个操作系统都单独做一份应用,即可做出各个平台下的产品。

我们的电脑一开始是没有Java程序的运行环境的(这个运行环境叫JVM),所以我们没办法运行Java程序。
Java写出来的程序与其他语言有所不同,最终的产品是class文件或者jar文件(其实jar就是一个压缩包里放了很多class),而不是我们所常见的exe格式的文件。

安装Java相当于给电脑里放了JVM,我们把class文件放进JVM里,程序就可以运行了。

面向对象

Java最大的特点是面向对象。
面向对象认为,计算机的世界由许多对象构成,计算机里的对象就是计算机里形形色色的数据。

如果你想理解这件事,那你先把编程这件事放一放。
可能你会纳闷,我学的是编程敲代码,我扯这些干啥。其实面向对象的思维贴近于生活,如果你把面向对象与现实生活联系起来,你看它会很自然。

我不想先用复杂的东西“下定义”,我先从思考的角度来解释一下它,诚心希望你听完我的讲述能有些许感悟。

什么是对象

我想先讲四件事,然后再总结一下面向对象的概念。

第一件事

我要讲的第一件事:假如路上突然钻出来一只猫和一只狗,你会觉得它们是同一个对象吗?

问题如上。我相信有能力阅读本文的读者都会给出很肯定的答案——当然不是同一个对象。那么为什么呢?
你可能会感觉更难以理解。猫就是猫,狗就是狗,你怎么能把一只猫和一只狗看作同一个对象呢?

我只能说你的感觉非常棒,如果一个对象是一只猫,一个对象是一只狗,那么它们显然就不是同一个对象了。
我们发现对象具有一个重要的特征——对象有它的类别这个概念。

在面向对象里,我们把“类别”叫做 类(Class)。对象是由类实例化出来的。

第二件事

我要讲的第二件事:假如路上突然钻出来两只猫在你面前,你会觉得它们是同一个对象吗?

你可能看完这个问题觉得我有病。猫和猫不一样,可能颜色不一样,一个是黑猫一个是白猫;还有的猫年龄2岁了,有的猫1岁大……
OK,你的这个观点也非常棒。我换个说法再把你的这句话说一遍:每个对象都有各种属性,比如猫都有毛色和年龄这两个属性,每只猫的这个属性可能是不同的。

我再来问个问题,假如路上钻出的两只猫年龄一样,毛色一样,它们还是同一个对象吗?
当然不是同一个对象啦。这也就是说,即使两个对象属性都一样,它们也不见得是同一个对象

第三件事

我想讲的第三件事:如果有一个机器人,你如何控制这个机器人说“你好”这个句子呢?

我问的这个问题本身就很笼统。如果我们用汉语的话,可以表示为机器人说你好这样的句子,对吧。
那么中文里都突出强调“主谓宾”的概念。我想向你讲述我如何看待机器人说你好这个句子:

  1. 这个句子的主体是机器人。我认为世界由“主语”这部分构成。如果我想操作什么东西,我要操作的主体是某个对象,而不应该是其他的东西
  2. 这个句子的谓语是。我们知道,不是任何对象都能做出这件事。我把应该是机器人的一种“能力”,或者看做技能之类的东西。
  3. 这个句子的宾语是你好。如果我只是说让机器人,它什么也做不了,因为它不知道说什么。如果我想让他我要指定这件事需要的“参数”,也就是说什么内容。这里你好就是这件事需要的参数。

有点乱吗?我再整理一下:我操作的主体是一个对象,这里是机器人是机器人自己的技能,这个技能不能直接发生,因为它需要参数“说话的内容”,你好就是我指定的参数。

那么我说这件事的目的是什么呢?

  1. 对于每个对象,它们都有自己的方法。方法就是它的“技能”,有的方法在调用时需要给定参数才能工作。我会在后面总结的时候,继续更深入一步说一说这个问题。
  2. 在万物皆对象的计算机里,如果操作一个数据,一个很自然的思路是找到这个对象,调用它的方法

那么我继续讲我想说的第四件事。

第四件事

我想讲的第四件事:你觉得猫和狗属于动物吗?

问题的答案是显然的,猫属于动物,狗也属于动物。
如果有一种类是动物,对于猫这种类和狗这种类而言,它们与动物这个类有显而易见的父子派生的关系。
这意味着,类有继承关系。猫继承自动物类,猫是动物类的一个子类。狗也同理。

那对于对象而言呢?你说一个猫对象是动物对象吗?你说一个狗类别是动物对象吗?显然也是。

我再换个例子。对于爬行动物这个类,所有的爬行动物都会爬,王八属于爬行动物,蛇也属于爬行动物。
这里有个问题:虽然这两种动物因为都是爬行动物,都会爬,你说它们爬的一样吗?
显然,蛇会爬,王八也会爬,但是它们在实现爬的时候实现方式是不一样的,这就是多态的一种体现,下面的总结里会详细解释这个问题。

总结一下我讲的事情

看起来我讲的都是一些废话对吧,其实我悄悄讲解了我自己理解的面向对象的重要的三个概念——封装、继承和多态

类和对象

在计算机中,数据都是一个个的对象 (Object),我们要操作一个数据,就是在操作一个对象。对象的类别简称为类 (Class)。

对于一个对象而言,我们关注它的两样东西,一个是它的属性,一个是它的方法。
方法(Method) 就是这个对象的“能力”、“技能”之类的东西。

封装

对于一个数据,我们提出了“对象”的概念。

如果你从计算机存数据和处理数据这件事的本质上来讲,属性就是要存的数据内容,方法就是我们对这个数据的操作。
那么从本质上来讲,我们把数据和对数据的操作包裹在了一起,这就是“封装”的基本概念了。

继承

还记得“猫”和“狗”都是“动物”的子类这件事吗?
我们可以说猫类是动物类的子类,也能说狗类是动物类的子类。这就是在描述继承关系,即猫类继承自动物类,狗类继承自动物类。

假如动物类有个属性叫“年龄”,有个方法叫“呼吸”,猫类继承了动物类,那么猫会不会也有“年龄”这个属性和“呼吸”这个方法呢?
答案是肯定的。这个角度我想告诉你的是继承的意义——减少了代码的冗余程度,让代码布局更合理。

多态

我上面说的事情里,我还提到了这么一件事。蛇和王八都属于爬行动物,爬行动物都会“爬”,按照我第一个角度的解释,王八和蛇也都应该继承“爬”这个方法。
而我们都知道,王八的爬和蛇的爬根本就不是一个实现方式。
我们可以发现,同样是爬行动物,却衍生出如此多种形态。这就是多态的含义。

多态的两种具体的表现就是方法的重写,就像上面说的“爬的不一样”说的一样。
第二种表现就是,一个猫对象也属于动物对象,一个狗对象也属于动物对象。如果有一个地方需要一个爬行动物对象,我既可以放上去一个蛇对象,也可以放一个王八对象,现在我让爬行动物对象爬,对于放上去的蛇而言调用的是蛇的“爬”方法,放上去的如果是王八那就是王八的“爬”。

类与对象的关系

你有没有留意一个问题,我在上面解释的时候,一直在有意模糊“方法”和“属性”究竟属于谁的事情。我一会儿说的是王八这个对象的“爬”方法,一会儿又说是王八的“爬”方法。
啊?我怎么说的乱七八糟的,看得让人晕乎,“爬”方法究竟是王八对象的,还是王八类的?
这部分内容我正是想好好解释一下这个问题。我还想在一个不同的角度再说说类和对象。

首先有这么一个概念:类是创造对象的模板。
在刚刚的讲述里,我提到了这么一句话“对象是由类实例化出来的”,这正是这个意思。对象不是凭空变出来的,它是由类作为模子从而实例化出来的。
我知道在实际生活中,并不是每只猫都会走路,并不是每条狗都会摇尾巴。但是我们研究的是宏观的整体,不考虑不太完整的情况。

也就是说,我们先用了代码编写了一个类,里面定义着这个类实例化后的对象应该具有的属性和方法。
在类里定义的方法还会描述方法的具体实现细节,也就是同一个类实例化出的对象可以有不同的属性,但是方法的具体实现方式是一致的。

因此,在上面的讲述中,我模糊了这个概念,原因是讨论属性和方法是谁的没有意义,其实本质是一码事。

后记

面向对象是Java的魅力所在。很多人觉得它不重要。它们可能在想 我来学编程,你咋给我看这个 ,进而不去看这部分的内容了。我发自内心的觉得这样真的很可惜,不去了解这些东西是绝对不能算学会Java的。

希望各位读者和各个dalao不会因为我把简单的概念讲的这么啰嗦而对它嗤之以鼻。我希望把一个东西讲的生动详细,这与简洁真的是背道而驰、无法兼得的。
衷心希望这部分的内容能带给读者一点启发。

下一篇