宅男知识大补丸 学多态 认包包

java零基础入门-面向对象篇(十)  多态

面向对象的三大特征,封装,继承我们讲完了,这次来讲多态。

多态就是指一个引用变量,在编译时和运行时类型不一样的情况。那我们首先就要搞清楚一个概念,什么是编译时,什么是运行时

其实这个概念我在最开始就讲过,还记不记得我们讲HelloWorld的时候,用命令行工具编译并且运行了一个java类。不记得的赶紧去复习(老规矩 从HelloWorld 开始吧)。

编译时,就是指java文件通过javac编译器,翻译成class文件的过程。这时候还没有开始执行方法,代码没有被加载到内存中,仅仅是做了一个翻译的动作。

运行时,是指程序申请了内存空间,将变量指向的对象放进内存,运行方法的动作。

为什么我们使用eclipse写代码的时候没见使用过javac这个编译器?

其实这就是使用工具写代码的好处,我们不需要手动操作编译的过程,但是我们经常在写代码的时候,工具在某行代码下面画了条红线,告诉我们这里无法编译通过,并且提示我们为什么,这就是在编译前,eclipse做的语法检查。

编译错误


那eclipse在什么时候编译java文件呢?我们看看eclipse背着我们做了些什么事


eclipse编译的时机

每次写完一段代码,这时eclipse会自动帮我们把写好的代码编译成class文件,而当我们完成了代码,点击运行的时候,这个时候所有的代码都被加载到内存中,这个时候就是运行时。

比如我们运行一个main方法的时候,所有的对象变量都在内存中待着,等候召唤,这个时候就是运行时。

搞清楚了编译时和运行时,我们继续来往下走。

什么是多态

首先我们举个例子帮助我们了解多态的概念。

有一天,你的女王大人说 我要买包包,但是他并没有具体说哪个牌子哪个款式,所以她说的只是一个概念,是父类

Bag bag;  你的女王大人给你定义了一个包,这是编译时。


我要买包包

圣旨已下,我们为了让她们开心,必须精挑细选。这里看好了三个包包,定义三个类,每个类都继承Bag类,有自己的价格和描述,最后给女王自己选。

女王只要包,没说具体要什么包,所以我们给的时候只能给包,这个包满足女王的条件即可。所以可以将具体的包(子类)看做是包(父类)的一种,换句话说,就是我们可以将子类看做是一种特殊的父类。


多态

当我们确定了两个类的父子关系以后,就可以将一个新创建的子类对象,赋值给父类变量。这时候我们注意看 queen.buyBag(XXX) 这段代码,同样一个对象 queen ,同样调用方法 buyBag ,却打印出了不同的结果,这就表现出了多态的特征。

这里要注意一点,多态是指子类重写了父类的方法后,展现出来的,而不包括成员变量,成员变量是不具备多态性的。


成员变量没有多态性

这是什么奇怪的规定?为什么方法具有多态的特征,而成员变量不具有多态的特征呢?

是不是又准备开始死记硬背了?说好的,我们要用理解代替死记硬背。

那么我就用内存图来解释这个奇怪的规定。

内存里的多态

通过内存图看多态,我们前面储备了足够的知识,如果你认真读过我前面的文章,看这个完全没压力。


内存图

为什么成员变量没有多态的特性?左边的图大家非常熟悉,就是一个普通的对象创建。

我们看右边,我们讲继承的时候说过,创建子类对象的时候,会自动获得父类的成员变量,会在内存中开辟空间,保存父类的成员变量,用super来访问他们。再看代码,左侧是父类的变量 bag_bv ,他指向哪?他指向子类对象的 super。

好了说到这,肯定又有同学要问,为啥指向super不是指向this?我很喜欢这种打破砂锅问到底的精神。

因为编译时,变量 bay_bv 是父类型,但是他并不知道 “将来” (运行时) 会指向何种子类型的对象,这时候你让他怎么去决定指向那个子类的变量?这不是强人所难么,所以他只能指向将来那个对象的super,通过super找到父类的成员变量,所以成员变量不具备多态的特征。


杠精还没下线,那为啥方法不指向父类的方法而是子类的重写的方法呢?

回答这个问题排除2个情况

1.父类没有describe方法,子类有describe方法,这个时候调用的就是子类的方法,没有发生多态。

2.父类有describe方法,子类没有describe方法,这个时候调用的是继承于父类的方法,没有发生多态。

最后就是,父类有方法,子类也有方法,这个时候子类重写了父类的方法。如果是父类变量保持子类对象地址,则发生多态。

发生多态时,就是我们上面讲解的概念,编译时编译的是父类的方法,运行时创建了子类的对象,是运行的子类方法

验证一下 编译时编译的是父类的方法(这里容易绕晕,还是验证一下)


编译时编译父类中方法


这个时候,首先运行代码左边,Bag bag_bv 这个时候,因为父类和子类都有方法  describe,所以父类完全可以在编译时就确定这个没有问题,编译通过,然后在运行时,使用 bag_bv 这个变量去调用子类的 describe方法,方法展现多态特征。


静态成员的多态规则

Bag bag_bv = new BottegaVeneta();

bag_bv.describe();

多态发生在对象调用方法的时候,而静态变量,静态方法属于类,如果 describe 是静态方法,那么使用对象调用方法和使用类调用方法是一样的

bag_bv.describe()    就是   Bag.describe()  

所以静态成员也没有多态,都是调用父类方法。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容