【Java】java多态的理解

首先简要说明下程序运行时,内存的结构。堆区栈区,常量区,静态方法区和非静态方法区。
1.栈:存放基本类型的变量数据和对象的引用(也就是在new对象时左边那一块),但是对象本身不放在栈中,而是存在堆(new出来的对象)。栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失。
2.堆:存放new出来的对象。堆中的对象由垃圾回收器负责回收,因此大小和生命周期不需要确定。
3.常量区:存放字符串常量和基本类型常量。

代码示例:

class Fu
{
    void method1()
    {
        System.out.println("fu method_1");
    }
    void method2()
    {
        System.out.println("fu method_2");
    }
    static void method3()
    {
        System.out.println("fu method_3");
    }
}
class Zi extends Fu
{
    void method1()
    {
        System.out.println("zi method_1");
    }
    void method4()
    {
        System.out.println("zi method_4");
    }
    static void  method3()
    {
        System.out.println("fu method_3");
    }
}
class DemoDuotai
{
    public  static void main(String args[])
    {
        Fu aa=new Zi();//创建一个父类引用,指向子类。
        aa.method1();//发生动态绑定,打印子的
        aa.method3();//打印父的
    }
}

内存图简要示例
这里写图片描述

分析

 aa.method1()-->this.method1()-->(new Zi()).method1()
  1. 我们知道类的非静态成员函数,需要类对象来调用。aa是指向Zi类的对象,method1()在运行时一定是被对象调用执行,因为他打印的时候或者访问的时候是访问对象中的那些数据。
  2. 而静态方法就不同了,他本身不访问对象特有数据。当Fu类和Zi类被加载到内存的时候,静态方法区就已经在里面啦,并且绑定在类上,所以可以直接采用类名调用,也就是所谓的静态绑定。他找的是静态区的方法,不参考右边的对象。所以aa.method3();只参考这个引用型变量aa是哪个类的。

总结

  1. 编译时期:参考应用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。
  2. 运行时期:参考对象(new出来的对象)所属的类中是否有调用的方法。(动态绑定)。
  3. 多态中,成员变量的特点:无聊编译运行,都参考左边(引用型变量所属的类)。
  4. 多态中,静态函数的特点:无聊编译运行,都参考左边。(静态绑定)

java编译和运行时的区别

举个例子来说明编译时(javac)和运行时(java)的区别,代码如下:

class Demo
{
    private int num;
    Demo(int num)
    {
        this.num=num;
    }
    public boolean equals(Object d)
    {
        Demo a=(Demo)d;
        return this.num==a.num;
    }
}
class Person
{

}
public class object_equals
{
    public static void main(String[] args)
    {
        Demo a=new Demo(3);
        Demo b=new Demo(4);
        Person c=new Person();
        System.out.println(a.equals(c));
    }

}

结果:编译通过,运行挂掉

分析:equals方法是超类Object中的方法,我们把他复写,调用equals时,参数 Object d=new Person()这里发生了向上转型,接着Demo a=(Demo)d 编译的时候是不会出错的,因为此处的d引用变量是绑定的Object这个类;而运行时,发生动态绑定也就绑定到了Person类上,把Person类的对象转化成Demo类的对象,出现类型转换错误。

改正:加上以下判断即可.

if(!d instanceof Demo) return ;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值