教她写代码的那些日子 8 类和对象

你是否也有那么一段往事,一直尘封在心底,偶尔会因为一首歌或者一句电影台词,让那封印有所松动,一些影像慢慢浮现在脑海。你或许会觉得遗憾,会懊恼,会责问自己为什么不坚定一点,为什么不勇敢一点。人生大抵如此,失去了才明白,拥有的才是最珍贵的,故而才常听一句话:活在当下,珍惜眼前。

当赵雷的那首《成都》响起的时候,她脸上的笑容突然变得有些僵硬,我想这就是那首揭开她心底封印的歌吧。

”有些事过去了,就让它随风而去吧。“我不知道该如何安慰,这是我此刻唯一能想到的一句安慰人的话,所以我痛恨着我的直男癌。

“你知道我为什么要学写程序吗?”她突然问我。

“为了有一技傍身。”我记得她这样说过。

“这是一方面吧,更主要的是整天沉浸在理性的思维里,就不会去伤春悲秋,老是伤春悲秋不好。”

“哦?”我没想到学写程序尽然有如此功效,她的思想真是特别。

“你还真是个特别的人,全世界这样想的,估计也只有你一个人吧。”

“那倒未必只我一人。”她悠悠地说。

我正不知怎样接话,又听她说:“好了,不说这些了,今天我们学什么?”

她突然地转移话题,着实让我吃了一惊,不过,那些不开心的事,不去聊它也好。

既然这样,我也就顺势转到今天要学的内容上来:“今天我们开始真正的java学习。”

“真正?”她有些惊奇,“之前学的不是java?”

“那倒也不是,只是之前学的是怎么写程序,从今天开始,我们要学习怎么写java程序。”

“有什么不一样吗?”

“当然不一样,首先我们要明白一个概念,那就是面向对象,Java是面向对象的编程语言。”

“还是不懂。”她摇了摇头,显然我又是说了一句废话。

“面向对象是更高级的一种编程思想,相比较以前的面向过程的编程思想,它更接近现实世界。”

我想在她看来,我依然在喋喋不休地讲着废话,因为她的眼神依然是迷惑的。

“这么说吧,面向对象是站在上帝的视角来看待世间万物,而面向过程还是站在凡人的视角看事物。”我努力解释着什么是面向对象的编程思想,因为这很重要,这是学习Java的基础。

“所以Java是更高级的编程语言,就是因为它是上帝视角看待事物的?”她终于有所领悟。

“是的。”我肯定了她的想法,但我知道她还是没有明白什么是面向对象,于是我接着说:“你回想一下,你前面写程序是一个怎样的过程。”

“怎样的过程?”她挠挠头,回忆着学习编程以来,写过的程序,以及写程序的过程,“就是先想想怎么写,然后就按照一定思路去写就是了。另外,为了代码整洁一点,会把某些代码封装到一个方法中。”

“没错,这就是面向过程的编程思想,这时你一直在想的是要实现某个功能,程序的流程应该是怎么样的。”

“是呀,写程序不就是这样吗?”

“所以你需要忘记,忘记之前的一切,才能接收新的更好的事物。”

显然我这句话有些一语双关的意思,但她似乎没有听出来。

“我发现你也挺啰嗦的,你还是快讲什么是面向对象吧。”

“好吧。”我只好接着面向过程与面向对象的差别继续说,“之所以面向对象更高级,就在于,遇到问题,你不应该去想怎么设计程序的流程,而是应该去想怎样去创造一个人或者一个事物,让它去解决问题,这就是面向对象的上帝视角。”

“还是有点抽象啊,能否再具体?”

“这么说吧,面向对象是接近于现实世界的,你想想现实世界是怎么样的。”

说到这里,我停下来,看向她,让她去想一下现实世界的模样。

“是怎样的?”她居然想都不想,直接问我。

我有些惊愕,随即想到,她或许以为我只是自问自答,而她只是需要配合一下我而已,于是我接着说道:“你看,现实世界是不是由各种事物构成的,比如地球、各种植物、各种动物以及人类等等,这些事物各自按照自己的规律进行生长和运动就构成整个世界。”

听到我的描述,她想了想说:“确实是这样。”

“面向对象的编程思想也是这样的,所以在java中所有一切都是由一个个个体构成,这里的个体就是对象。”

她没说话,一双美目看向我,示意我继续,但我却向她提出一个问题:“如果你是上帝,你要怎么去创建这个世界呢?”

“我不知道。”她很干脆地回答。

“这么说吧,假如你是女娲,你要造人,你会怎么做?”

“不知道。”她依然简单直接地回答。

“好吧,那你是不是得先想想人应该是什么样的?”

“嗯,不用想啊,人就是那样啊,一个头,两只手,两条腿。”

“你这不就是在想了人是什么样的吗?”

“是吗?”她有些疑惑。

“好吧,那我们就按你的设想来造人。”我忽略掉她的疑惑,继续说:“首先我们就要对人进行一个归类定义,然后再按照这个定义进行个体地创建。这就是面向对象编程的做事流程,要创建对象,就得先有对象的归类定义,这个归类定义就是类。”

“还是来看例子吧。”我没等她说出怎么写代码的问题前就拿过她的笔记本电脑开始敲代码。

第一个例子:

编译运行:

“看到没,我们要创建人这个对象,首先我们先定义了人这个类。定义一个类是用关键字class来标示的,在class后面的大括号里面的内容就是对一个类的定义。”

“嗯,了解了。”她看着代码点了点头说。

“定义一个类有3个部分可选,它们分别是:表示事物特征的属性,也叫成员变量;表示事物行为的成员方法;以及用来设置事物初始样子的构造方法。”说到这里我问她,“在我写的这个人类的定义中,哪些是属性,哪些是成员方法,哪些是构造方法?”

“这个很简单啊,你写了注释的嘛。”她一边看着代码一边说:“2到7行是属性,9到16行是构造方法,18到21行是成员方法。”

“完全正确。”我说,其实想来也是,这么简单的问题,而且我还写了注释,她要分辨不出来的话,那才是奇怪呢。

“看来你是懂了,那么你来写一个呢。”看她跃跃欲试的样子,我接着说。

“我也正有此想法,可是写什么呢?”她苦恼起写什么来。

“那你就创造几个女人吧。”我说,我也没想到什么作为例子的事物,想法还是停留在女娲造人上面。

“女人和人有什么不同吗?你都写了,让我照抄一个?”她显然没找到人和女人的不同。

“女人有一个很重要的属性就是颜值啊。”我提醒她。

“好像是哦。”她笑了,“那就看我的。”

说完,她拿过电脑开始写起代码来。

她写的代码:

编译运行:

“怎么样?”她开心地说。

“不错是不错,不过有点自恋啊,哈哈!”我笑了,因为我注意到那个叫小花的女人的颜值,她设置的是100分,小花是她的名字。

“难道我不美吗?”她眨巴着眼睛,尽力摆出妩媚的姿势,看着我说。

“美美。”我连声称赞,虽然故意做出敷衍的神情,但真心是觉得她很美的。

“哼。”她哼了一下,恢复了正常的坐姿,然后又说,“有一个问题,构造方法中这些this是干嘛的?”

“this用来指代当前对象。”我随口回答着。

“不懂。”她说,然后做出一副洗耳恭听的神态。

我没想到这对于java程序员来说几乎是常识的知识点,她却说不懂,但随即我又想到她并不是java程序员,她只是一个开始学习Java的小白,不懂是正常的,懂才有些不正常,于是我耐心给她讲:“this就是代表了你基于这个类创建的对象。因为类的对象,要在用new关键字创建后才存在,所以在类里面就用this来指代将来会被创造出来的对象。对了,你应该知道了,创建一个对象是用new这个关键字吧?”

“嗯,已猜到是这样。”她面无表情地说,我知道她在思考‘this’的问题。

“这么说吧,在创建对象的时候,其实是先创建了一个各属性的值都默认的对象,然后再调用构造方法,在构造方法中我们做了一件事,就是将参数的值赋值给对象对应的属性,你知道的等号就是赋值。”

“这样的话,我似乎懂了,其实这里可以这样写。”她说着,改了改代码。

她改过的代码:

编译运行:

“可以将对象属性的赋值写在创建对象之后,用点号来表示对象和属性的从属关系。而构造方法里面的赋值其实和写在创建对象之后属性赋值是一样的,只是在类里面不可能知道以后创建的对象的名字,所以就用this来代替。”程序正常运行后,她说出了她的理解,末了她还带了一句:“我说得对不对?”

“说得对极了。”我说,“还有一点,this是可以省略的,你知道吗?”

“哦,知道了。”

“那你知道,为啥之前我们写在构造方法里面的赋值语句中的this没有省略吗?”

“哈哈,想考我吗?这个还不明显,是因为我们定义的参数的名称和属性的名称一样了,如果不写this的话,就成参数自己赋值给自己了。”

“好吧,看来我小看你了。”

“变量的作用域和方法的参数我可是认真学了的,构造方法也是方法嘛,道理应该是一样的。”她得意地说。

“你厉害。”我尽无话可说了,只能说出这样一句赞赏的话来。

不过她却忽视掉了我对她的赞赏,自顾自地得意了一会儿,然后说:“类和对象就讲完了?应该不会就这么点内容吧?”

“当然不会只有这么点内容,这只是一个入门,你现在算是入门了。”

“哦,才入门啊?那你快讲吧,乘我现在正求知若渴。”她显然有些失望,不过很快又表现出强烈的求知欲望来。

“先问你一个问题,人和女人是什么关系?”我决定还是从一个问题开始。

“女人是人的一种啊,还有一种是男人嘛。”

“对,它们是从属关系。在java中,这种关系我们叫继承关系,也就是说女人是继承于人的,人叫女人的父类,女人叫人的子类,当然还有男人也是人的子类。”

“嗯,让我想一下。”她说完,陷入了一阵思考,而我也很知趣地没有去打扰她。

“那这样的话,有很多例子。比如,动物就是人的父类,人是动物的子类。”她突然抬起头来说道。

“对对,你说得很对。”

“哈哈。”她有些得意自己的聪明,没等我说什么,她又提出了她的疑问,“不过这和写程序有什么关系呢?”

“有关系的,这样的继承关系我们是可以用程序表达出来的,我还是写个例子,你看了就明白了。”

我写的例子:

编译运行:

“你看,其实很简单,用extends这个关键字来标识继承关系就好了。”我一边说着,一边给她看。

“哦,我记住了。”她说,“继承后,子类就拥有了父类的属性了,是不是?”

“一般情况下,是这样的。”她的观察能力果然没让我失望,我故意没说,她也看出来了,这里男人和女人这两个子类继承了人这个父类,所以这两个子类里面就有了name这个属性,也正是这样,在子类中就可以直接使用这个属性。

“哈哈,这样好,这样就不用重复写那么多代码了,这个继承很好。”她感叹着继承的好用,接着又提出对我说的一般情况的疑问,“一般情况能把父类的属性继承过来直接使用,那什么情况下不能呢?”

“这个就要说到java的访问控制权限了。”我说,“还记得在学方法时提到的public、protected、private这几个访问控制修饰符吗?”

“记得,不过不是很明白。”

“嗯,这样吧,我们先来看一个表格吧。”说着我在网上找到一个表格给她看。

网上找的表格:

看了这个表格,她抬起头来,茫然地看向我。

“好吧,先不管这个表格,我们先来说说包吧。”在她发问之前,我已明白她所茫然的是什么,“你有没有发现,我刚刚写的代码里面,定义的人这个类是用的Person,而不是之前的Human?”

“是呀,为什么?”

“因为之前的类已经用过了,也因为这两个类都在同一个包里面(都是默认包,即无名包),所以就冲突了,如果再以Human定义一个类的话,计算机就不知道你用的是哪个定义了,所以有了包这个概念后,就可以在不同包下面定义相同名字的类了。就像你在同一个文件夹下面不能放名字相同的文件,在不同文件夹下面就能有相同文件名的文件一样。而事实上类文件存放的文件夹也是和包名是一致的。当然,包和文件夹一样,可以对类进行归类,相关的类,一般是放在一个包下面。有了包以后,类就有了一个全名:包名.类名。比如系统包java.util下面的类Scanner的全名就是java.util.Scanner。”

我一口气说了一大段理论,从她的眼神中我看出来,她还有些似懂非懂,于是我决定写几个例子,这样她就能明白了。

“我写几个例子,你就明白了。”我说着,开始在电脑上敲起代码来。

代码文件目录结构:

代码:

com/luoye/Human.java:

com/luoye/Man.java:

com/luoye/Woman.java:

com/luoye/HumanWorld.java:

com/xh/Man.java:

com/xh/Woman.java:

com/xh/HumanWorld.java:

编译运行:

错误示例的编译:

“呀,报错了。”

“是呀,你知道错哪里了吗?”

“让我看看。”她说着,认真看着代码。

过了一会儿,她问我:“那个super是干什么的?”

我惊奇于她思维的跳跃,但也喜欢她这样不懂就问的性格,于是我说:“那个指代父类对象,和this有些相似。”

“哦。”她说。

我没能从这个字听出来她是懂了还是没懂,但这个问题似乎意会比言传更有用一点,所以我不再苦思怎么给她解释了,我相信她最终是能明白的。

“找到程序报错的问题了吗?”我决定回到程序的报错上面来。

“嗯,它不是报错说,Human的属性不是公共的吗,那改成公共的应该就可以了。”

“那么改一下看看呢。”

她改过的Human:

编译运行:

“果然是这样。”程序运行后,她有些小兴奋地说。

“那么,通过这些例子,是不是瞬间就明白我刚刚说的那一大段了?”我问她,我相信通过这几个例子,她能明白。

“嗯,大概明白了吧。”她想了想说。

“包的声明语句只能写在类文件的开头,而且在一个类文件中只能有一个包声明语句,也只能有一个访问控制权限是public的类。在使用不是本包定义的类时,需要用关键字import将类引入进来,可以引入一个类,也可以用*表示引入那个包下面所有的类。当然,如果出现名字冲突,我们也可以用类的全名来避免。”我怕她看不出这几个隐藏的知识点,特意强调道。

“知道了。”

“好了,明白了包的概念,那这个访问控制权限的表应该也看得懂了吧。”我翻出刚才百度出来的表,说道。

“嗯,也差不多看得懂了。”

“哈哈,聪明。”

“你就别夸我了,我现在脑袋都快爆炸了,一下子接收这么多知识,我要好好消化一下才行,今天就讲到这吧。”

“遵命,我...”我本想说我的女王大人,但突然觉得这几个字从我嘴里说出来显得有些轻佻了,故而将后面几个字生生地咽了回去。

然而,她似乎根本没在意我说什么,自顾自地思考和写代码去了。

 

 

ps:

这一节的几个关键点:面向对象、类、对象、继承、包、访问控制权限

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值