文档章节

理解多态AND理解父类引用指向子类对象

张悟空
 张悟空
发布于 2014/08/28 15:19
字数 1460
阅读 48
收藏 2

假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,它里面的变量需要占用0.5M内存.

现在通过代码来看看内存的分配情况:

Father f = new Father();//系统将分配1M内存.

Son s = new Son();//系统将分配1.5M内存.


因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.

由于s中包含了父类的实例,所以s可以调用父类的方法.


Son s1 = s;//s1指向那1.5M的内存.(可以理解为就是:子类引用指向子类对象)


Father f1 = (Father)s;//这时f1会指向那1.5M内存中的1M内存,即是说,f1只是指向了s中实例的父类实例对象,所以f1只能调用父类的方法(存储在1M内存中),而不能调用子类的方法(存储在0.5M内存中).


Son s2 = (Son)f;//这句代码运行时会报ClassCastException.因为f中只有1M内存,而子类的引用都必须要有1.5M的内存,所以无法转换.


Son s3 = (Son)f1;//这句可以通过运行,这时s3指向那1.5M的内存.由于f1是由s转换过来的,所以它是有1.5M的内存的,只是它指向的只有1M内存.

 


示例:

class Father{

void print(){};

}


class Son extends Father{

void print(){System.out.println("子类中!");}

void show(){System.out.println("show 中!");}

}


class Demo{

public static void main(String args[]){

Father obj=new Son();

obj.print();

obj.show();  //这个调用会报错!

}

}


1 .如果你想实现多态,那么必须有三个条件,父类引用,子类对象,方法覆盖

你这里如果Fathor类有一个show()方法,那么形成方法覆盖,那么此时就可以这么写:obj.show(),此刻形成了多态.

2. 没有方法覆盖,那你这里只能解释为父类引用去访问一个子类的方法,当然,父类引用没有这么大范围的权限,当然会报错

PS:多态实际上是一种机制,在编译时刻,会生成一张虚拟表,来记录所有覆盖的方法,没有被覆盖的方法是不会记录到这张表的.

若一个父类引用调用了没有覆盖的子类方法,那么是不符合该表的,那么编译时刻就会报错.

在执行程序的时候,虚拟机会去这张虚拟表中找覆盖的方法,比如引用中实际上存的是一个子类对象引用,那么就会去找子类中的相应的覆盖的方法来执行

定义一个父类类型的引用指向一个子类的对象既可以使用子类强大的功能,又可以抽取父类的共性。

所以,父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;

同时,父类中的一个方法只有在在父类中定义而在子类中没有重写的情况下,才可以被父类类型的引用调用;

对多态的理解:多态体现在继承中,所以需要有继承关系,然后子类要重写父类方法,最后父类指向子类(父类本身具有一些方法,这些方法被子类重写了,但调用这些方法时,会自动调子类重写的那些)。

多态具体表现在重写和重载,多态就是类的多种表现方式,比如同名不同参,子类重写父类。

看下面这段程序:

class Father{

    public void func1(){

        func2();

    }


    //这是父类中的func2()方法,因为下面的子类中重写了该方法

    //所以在父类类型的引用中调用时,这个方法将不再有效

    //取而代之的是将调用子类中重写的func2()方法

    public void func2(){

        System.out.println("AAA");

    }

}

 

class Child extends Father{

    //func1(int i)是对func1()方法的一个重载

    //由于在父类中没有定义这个方法,所以它不能被父类类型的引用调用

    //所以在下面的main方法中child.func1(68)是不对的

    public void func1(int i){

        System.out.println("BBB");

    }


    //func2()重写了父类Father中的func2()方法

    //如果父类类型的引用中调用了func2()方法,那么必然是子类中重写的这个方法

    public void func2(){

        System.out.println("CCC");

    }

}


public class PolymorphismTest {

    public static void main(String[] args) {

        Father child = new Child();

        child.func1();//打印结果将会是什么?  

    }

}


  
上面的程序是个很典型的多态的例子。子类Child继承了父类Father,并重载了父类的func1()方法,重写了父类的func2()方法。重载后的func1(int
i)和func1()不再是同一个方法,由于父类中没有func1(int i),那么,父类类型的引用child就不能调用func1(int
i)方法。而子类重写了func2()方法,那么父类类型的引用child在调用该方法时将会调用子类中重写的func2()。


    那么该程序将会打印出什么样的结果呢?

    很显然,应该是“CCC”。







变量是不存在重写覆盖的!

public class A { int a = 1; }

public class B extends A { int a = 2; }


测试类里调用了这个方法void compare(){

if(super.a == this.a)

System.out.println("not overrided");

else

System.out.println("overrided");}

控制台出来的是overrided

 类中的属性是没有多态性的,即你在引用上面使用属性时,系统只会去找引用的静态类型中的那个属性,而与它的实际类型无关。

静态方法也是没有多态性的。

本文转载自:http://www.blogjava.net/peiliangye/articles/365335.html

张悟空

张悟空

粉丝 8
博文 71
码字总数 20588
作品 0
郑州
程序员
私信 提问
第十二讲 面向对象基础——多态

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yerenyuan_pku/article/details/82081786 多态的概述 多态可以理解为事物存在的多种体现形态。例如,猫这个对...

李阿昀
2018/08/26
0
0
C++ —面向对象之多态的实现与应用

多态 大家应该都听过C++三大特性之一多态,那么什么多态呢?多态有什么用?通俗一点来讲-> 多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程...

Dawn_sf
2017/04/05
0
0
Java多态性详解——父类引用子类对象

面向对象编程有三个特征,即封装、继承和多态。   封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据。   继承是为了重用父类代码,同时为实...

LCZ777
2014/08/25
41
0
谈谈多态

概述 我们都知道面向对象有四个基本特性:抽象、封装、继承、多态。这四个特性,概括起来可以这么理解,抽象、封装、继承是多态的基础,多态是抽象、封装、继承的表现。多态,是Java中非常重...

Galy_绿
2016/07/11
37
0
Java中多态应当注意

一、多态的分类: 1、引用多态:父类的引用可以指向本类的对象,父类引用可以指向子类对象,子类引用不能指向父类对象; 2、方法多态:创建本类对象时,调用的方法为本类方法;创建子类对象时...

落叶-归根
2016/05/09
20
0

没有更多内容

加载失败,请刷新页面

加载更多

Rabbit MQ 延迟消息发送

为什么使用延迟消息? 不同于同步消息,有些业务场景下希望可以实现延迟一定时间再消费消息。 典型的场景有微信、支付宝等第三方支付回调接口,会在用户支付后3秒、5秒、30秒等等时间后向应用...

兜兜毛毛
8分钟前
2
0
【0918】正则介绍_grep

【0918】正则介绍_grep 9.1 正则介绍_grep上 9.2 grep中 9.3 grep下 一、正则介绍 正则是一串有规律的字符串,它使用单个字符串来描述或匹配一系列符合某个语法规则的字符串。 二、grep工具 ...

飞翔的竹蜻蜓
38分钟前
4
0
为什么要在网站中应用CDN加速?

1. 网页加载速度更快 在网站中使用CDN技术最直接的一个好处就是它可以加快网页的加载速度。首先,CDN加速的内容分发是基于服务器缓存的,由于CDN中缓存了不少数据,它能够给用户提供更快的页...

云漫网络Ruan
今天
8
0
亚玛芬体育(Amer Sports)和信必优正式启动合作开发Movesense创新

亚玛芬体育和信必优正式启动合作开发Movesense创新,作为亚玛芬体育的完美技术搭档,信必优利用Movesense传感器技术为第三方开发移动应用和服务。 Movesense基于传感器技术和开放的API,测量...

symbiochina88
今天
4
0
创龙TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA核心板规格书

SOM-TL437xF是一款广州创龙基于TI AM437x ARM Cortex-A9 + Xilinx Spartan-6 FPGA芯片设计的核心板,采用沉金无铅工艺的10层板设计,适用于高速数据采集和处理系统、汽车导航、工业自动化等领...

Tronlong创龙
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部