这年头,越来越多的人离不开网络了。现在上网已经不是非得看新闻或是淘宝京东买东西了,大家把目光更多地投到了网络学习和娱乐方面。于是这几年网络上催生出了一种人,这种人在某一领域要么相貌出众,要么成就非凡,要么与众不同,他们有一个统一的名字 - 网红。无论是这两年火的直播,还是一直以来的微博微信运营,网红的粉丝都是好几百万上千万,热热闹闹的。那咱们就用网红来讲下面的知识。
刚才说了,网红是一类人。王思聪是网红,papi酱是网红,咪蒙也是网红。但反过来说行么?网红就是王思聪,他倒愿意,papi酱和咪蒙大大就不干了。类似这种例子还有很多,你说牛是动物,但你不能说动物就是牛,你问过猪的意思么?你说c罗是球星,那球星就只有c罗吗?梅西内少该不服了对吧?所以,我们说网红是一个概念,一个名称,一个种类,或者说是抽象的,是大而全的,在java里我们给它起个名字叫作类;而那一个个人名才是实实在在的具体的个例,我们称之为对象。不是搞对象那个那个对象,是实体、实例的意思。
和变量一样,类和类实例也是需要声明定义的。咱们先来看类的声明格式:
这里有个关键字叫class。有些人可能马上会说,这怎么那么眼熟呢?咱们一直以来写的程序一开始不都用class么?而且格式也差不多,是不是有什么联系?没错,咱们从一开始到现在写程序都是写在一个类里的。咱们还拿网红举例,声明一个类的方式就是:
注意,按照java的规范,类名的首字母一定是大写的。你说小写可不可以?可以,能编译,但内行一看就觉得你不专业。首字母一定要大写。刚定义的类是空的,我们需要完善这个类。但是,括号里面不能随便写,是有要求的。按照咱们以前的例子,这里边就应该写public static void main(){}了对吧?java第一篇里咱们就说过,这句话代表程序的入口,程序从这儿开始执行。但我暂时先不写,一会儿讲为什么。
我第一个要写的就是属性。什么是属性?你玩的游戏里人物是不是总说攻击力,防御值什么的?是不是都管它们叫属性?网红也一样。假设每个网红都有一个个人信息资料,个人资料里都有自己的姓名,年龄,爱好,这些就是他们的属性。它们在程序里是以变量的方式写出来的:
这里我声明了姓名、年龄、爱好三个属性。年龄没什么讲的,是整数,所以用int变量; 但姓名和爱好我用了一个我们暂时还没讲的String类型声明。String翻译过来是字符串的意思。我们之前讲Java变量和类型转换时讲了变量的基本类型,但还没讲复杂类型。而string就属于复杂类型,也是我们以后单独要介绍的知识点。现在先预热一下吧:字符串,跟羊肉串一样,串就是一组、一堆的意思,所以字符串也就是一组字符的意思。你看之前我们写的Happy New Year,这就是一组字符。空格也是一种特殊字符。同理,这个例子中名字和爱好都只能是字符串,谁的名字也不能是一个数吧?叫你250你干吗?肯定得打我吧。所以我把这两个属性都声明成字符串类型。先理解到这儿,更多细节以后再讲。
因为这些属性变量都是一个类里的成员,所以我们管它们叫作成员变量,又叫做字段。写到这儿一个类就算创建好了。现在怎么着都得写程序的入口了吧?不写入口怎么执行程序呢?好,我先把入口写上:
有人问了,创建这个类是干嘛用的呢?一句话,它们的作用就是被对象访问!对嘛,没人在乎一个网红类有啥属性,大家更在乎的是王思聪papi酱咪蒙这些一个个具体的网红的信息。一个类脱离开具体信息也没什么意思。我们一点一点来讲,这里涉及的概念越来越多了,慢慢开始变复杂了,不过不难,只需要用心理解。实例化一个对象的格式如下:
在咱们这个例子里就是Wanghong w = new Wanghong();这个格式看起来陌生,咱们一点一点来,先说什么是实例化对象。Wanghong w = new Wanghong()其实和咱们之前学的int i = 10很像。有人说你这不胡说八道么?这两个哪儿像啊?别急,一边看下面的图,一边看我解释:
int是整型,而Wanghong虽然不是整数/小数/字符,但它也是一种类型,叫类类型,和String字符串一样,也是复杂类型。i的类型是整型,w的类型是Wanghong型,本质是类类型。整型对应变量名,类类型对应对象引用(一会儿讲什么是对象引用)。等号左边的原理相同。
不同的是等号右边。咱们讲声明变量的时候,我总爱说在内存里开辟一块空间。对于整型来说,int i = 10时在内存里开辟一块空间存i值10。可你不能随便开辟,得在一个特定的区域才行。这个区域就叫做栈。变量i在栈区内创建,然后再把10作为值存在这个变量i里,整个过程就完了。浮点型字符型同理:
正因为存的是具体的数值,这些基本类型又被叫作值类型。而对于对象或类实例来说,它们也在栈区里被创建,但是同时计算机马上在内存的另一个区域,也就是一个被称为堆的区域又开辟了一个空间,存什么呢?存Wanghong()这个东西。Wanghong()其实是什么啊?是不是就是刚刚在类里定义的那三个属性?存好Wanghong()最后把Wanghong()的地址存在w里。也就是说,因为是Wanghong类型,是类类型,所以它里面不再存一个值,而是一个地址,谁的地址?Wanghong()的地址。其实也叫值,只不过是一个地址值罢了。它的图就是这个样子:
这个Wanghong()就是刚才所谓的对象,也就是一份实实在在的网红信息。可以理解成它就是王思聪的信息,就是papi酱的信息,就是咪蒙的信息。所以现在明白什么叫实例化对象了吧?你一旦写"new",就意味着创建了一个类的实际对象,就像一个类的例子一样,承载着该类的所有属性。而我们管w叫作对象的引用,它存着他们的信息地址,通过w就可以找到他们的个人信息。正因为这个原因,类类型又被叫作引用类型。还记得之前介绍java变量和类型转换时说的宾馆理论么?说变量相当于一个个客房,变量值就是这个客人。你要是想找客人直接敲门就行了:
而对于对象来说,对象也是客房,但里面装的不是客人,而是一张写着另一间客房地址的字条。这个客人装b,其实订了两个房间,他自己在另一个房间。你如果想要找到客人得先闯进第一个屋里拿了字条看到地址才能去第二个屋找客人:
值类型存值,引用类型存地址,这么记就行。现在我们把w改成wsc,代表王思聪,程序就变成了:
再写一个Wanghong mm = new Wanghong();代表咪蒙:
注意,虽然这两句后边都是Wanghong(),但由于wsc和mm这两个引用名称不同,证明是两个不同的引用,也就意味着它们存的地址是不同的。王思聪的个人信息和咪蒙的个人信息是放在不同的堆空间里:
我们从内存图里发现,现在Wanghong类里的属性姓名,年龄,爱好都没赋初值。那咱们就给它们赋上初值。问题来了,姓名、年龄、爱好是成员变量,它们只属于Wanghong类,你直接为它赋值行不行?就用咱们学过的,比如年龄直接写age = 30; 然后打印它们行不行?那你这个30指代的是王思聪的年龄还是咪蒙的年龄?指代不明。所以,为类的成员变量赋值的方法就变成了对象引用.成员变量 = 值。前面用对象引用指明是谁,这样为谁的成员变量赋值一清二楚。中间的点代表访问,整句代码的意思就是用对象引用访问某个成员变量这种方式来赋值。
以年龄为例,我们加上wsc.age = 30; mm.age = 25; :
王思聪88年的,今年是2018年,30了。至于咪蒙,女生嘛,永远18。所以咱们这两个年龄值就有了。以此类推,我们可以给姓名和爱好赋值:wsc.name = "王思聪" mm.name = "咪蒙" wsc.hobby = "打游戏" mm.hobby = "写文章" 这样是不是更清楚了?注意,对象引用指向的其实就是对象本身,如果整个程序你只声明了一个对象,比如只有王思聪,那你写new Wanghong().age = 30没任何问题,只是出于区分的原因我们需要把对象赋给对象引用。所以,业内直接就说用对象调用成员变量,“引用”这个词就不说了。但大家要知道,wsc.age=30里边的wsc是对象引用,并不是对象本身。
王思聪天天打游戏,咪蒙夜夜写文章,没毛病。内存图再完善一步:
其实上面这个内存图还是有一点毛病,因为类里年龄这个属性也是值类型,按理说应该也是在栈区创建出来,但再画就很复杂了,毕竟它也是属于类实例的产物,所以我就把它归在堆中了。赋完值后就可以直接打印出来了:
最后结果如下:
和普通变量一样,成员变量也可以随意更改值。比如你不同意王思聪天天打游戏,你觉得他平时还要当老板管理公司,你后面还可以写wsc.hobby = "管理公司"。然后再打印出来就是新的值了。
这篇文章只介绍了类和成员变量这两个概念,以后还要介绍几个,东西一多容易混淆,所以我画了一张类的结构图,以后每说一个我们就把它加进去:
这就是类的介绍以及类中成员变量的声明及访问的方式。简单总结一下:
1. 类是一个抽象的概念,而类中的对象则是具体的一个东西;
2. 一个类中可以有多种属性,一但被创建则每个对象都拥有这些属性;
3. 不同的对象可以有不同的属性值。
这篇文章的源代码在OOP1中。