精华内容
下载资源
问答
  • 永远记住:不管父类子类之间如何转换,永远是父类引用指向子类对象,子类引用指向父类对象,需要将父类对象强制转换为子类! 举例: public class Animal{} //父类 class Dog extends Animal{} //子类 public class...

    永远记住:不管父类子类之间如何转换,永远是父类引用指向子类对象,子类引用指向父类对象,需要将父类对象强制转换为子类!

    举例:

    public class Animal{}	//父类
    class Dog extends Animal{}	//子类
    
    public class Test{
    	public static void main(String[] args){
    		Animal a1=new Animal();	//父类引用指向父类对象,√
    		Animal a2=new Dog();	//父类引用指向子类对象,这是多态,√
    		Dog d1=new Dog();		//子类引用指向子类对象,√
    		Dog d2=new Animal();	//子类引用指向父类对象,×
    		a1=d1;					//父类引用指向子类对象,√
    		d1=a1;					//子类引用指向父类对象,×
    		d1=(Dog)a1;				//父类对象a1强制转换为子类对象,然后子类引用指向子类对象,√
    	}
    }
    

    朴实无华的分割框,下面是知识点框架梳理,上面时精辟要点!

    在这里插入图片描述

    展开全文
  • Java多态的三个必要条件:1、 继承2、 子类重写父类方法3、 父类引用指向子类对象然后看一个例子输出结果为:给出结论:Father c = new Child() 在c的眼里只能看到 child 里面的 father 属性!当满Java多态的三个...

    Java多态的三个必要条件:

    1、 继承

    2、 子类重写父类方法

    3、 父类引用指向子类对象

    然后看一个例子

    3da9af84292fa3fbdc438711179f0c53.png

    9b0dc028f1928f825d98a4c41d8b6ae3.png

    输出结果为:

    f7fb637ea3f5dcf8b6ebe89e3bec4418.png

    给出结论:Father  c  =  new  Child()    在c的眼里只能看到 child 里面的 father 属性!

    当满Java多态的三个条件时,可以发现c.eat()调用的实际上是子类的eat(是因为子类重写覆盖了父类方法),

    但c.age调用的还是父类的age(属性/变量不存在重写和覆盖),而c.play()则不会通过编译。

    bce5a2f786c39662f4c7921577fd817a.png

    e3fb38ce1c95a47704c0dca949669346.png

    但是在java的引用中Father不但指定了c以何种方式访问内存,也规定了能够访问内存空间的大小。

    我们看Father实例对象的大小是占两行,但Child实例对象占三行(这里就是简单量化一下)。

    所以虽然c指向的是Child实例对象,但是前面有Father修饰它,它也只能访问两行的数据,也就是说c根本访问不到Child类中的age!!!只能访问到Father类的age,所以输出40

    408c0a2dcecb62d0860aa27e24b6bada.png

    我们看到Parent的方法表占三行,Child的方法表占4行,c虽然指向了Child类的实例对象,

    而对象中也有指针指向Child类的方法表,但是由于c受到了Father的修饰,通过c也只能访问到Child方法表中前3行的内容!!!!

    然而前面说过,在方法表的形成过程中,子类重写的方法会覆盖掉表中原来的数据,也就是Child类的方法表的第三行是指向Child.eat的引用,

    而不是指向Parent.eat(因为方法表产生了覆盖),所以c访问到的是Child.eat。也就是子类的方法!!!这种情况下,c是没有办法直接访问到父类的eat方法的。

    展开全文
  • 继承和方法重写已经很熟悉了,这次主要验证一下,当一个父类引用指向一个对象的时候,它会调用子类的方法,而不是父类的。引用在栈内存中存在对象的内存地址。真正的对象(通过 new Student()创建的)存放在堆内存里...

    继承和方法重写已经很熟悉了,这次

    主要验证一下,当一个父类的引用指向一个对象的时候,它会调用子类的方法,而不是父类的。

    引用在栈内存中存在对象的内存地址。真正的对象(通过 new Student()创建的)存放在堆内存里。

    在这块堆内存区域内,存在的是子类的属性(包括自己特有的,以及通过super()构造方法中从父类获得的)

    和方法(继承父类但没有覆盖的,以及覆盖父类的方法和自己特有的),尽管引用是声明为父类的引用,

    但是它指向的子类的对象,在执行方法的时候,是通过引用指向的堆内存区域内执行的。也就是到底执行父类

    方法还是子类方法是由对象决定的,跟引用没有直接关系。

    演示代码如下:

    Person.java

    public class Person{

    private String name;

    public Person(){}

    public void setName(String name){

    this.name = name;

    }

    public String getName(){

    return this.name;

    }

    public void introduce(){

    System.out.println("Hello, I'm a Person object, and my name is "

    +getName());

    }

    }

    Student.java

    public class Student extends Person{

    public Student(){

    super();

    }

    public void introduce(){

    System.out.println("I'm a Student object and my name is "

    +getName());

    }

    }

    Test.java

    public class Test{

    public static void main(String[] args){

    Person p = new Student();

    p.setName("^-^");

    p.introduce();

    }

    }

    输出结果为:

    I'm a Student object and my name is ^-^

    展开全文
  • 下图是在java中,使用子类引用指向父类对象的情况​编译可以通过,因为对生成的Person对象做了一个强制转换,骗过了编译器,其本质上还是属于子类引用指向父类对象。点击运行,出现下图的报错情况。很明...

    在java、C++等面向对象的语言中,实现多态的方式就是使用父类引用指向子类对象,所以父类引用指向子类对象是没有任何问题的,但是,大家有没有想过,子类引用可以指向父类对象吗?答案是不可以!但是为什么呢?

    下图是在java中,使用子类引用指向父类对象的情况

    0f545c3ea38f7a3a306d787226437576.png

    编译可以通过,因为对生成的Person对象做了一个强制转换,骗过了编译器,其本质上还是属于子类引用指向父类对象。

    点击运行,出现下图的报错情况。

    94389c5cb36522c0d70853c62f7449e1.png

    很明显,java虚拟机在运行该行代码的时候进行了运行时检测,禁止子类引用指向父类对象。

    所以,这种操作在java里面是不允许的,接下来,我们把代码拷贝一下,在C++的环境再跑一下。

    236d73c794f49ee025ec1f8d96e7f985.png

    编译,运行,一切非常顺利。

    为什么java里面不允许这种操作,而C++却允许这种操作呢?我们接下来在C++的环境下,反汇编窥探一下这写代码究竟干了些什么事。

    首先,在执行这行代码的时候,先把一个4压入栈中,然后去调用operator new这个函数,很明显,这个4就是该函数的一个参数,它完成的任务就是,向堆空间申请4个字节的存储空间,为什么是4个字节?因为Person这个类里面只有age这一个属性,因此new出来的对象也只需要4个字节存储就够了。然后使用stu这个Student类型的指针指向这4个存储空间的首地址。

    4fbcc216d28f53306024f763c3cbacdb.png
    e89adb0a3125f6bf28993e63f969f408.png

    接下来,我们来看一下,下面两行的反汇编代码,因为Student类继承于Person类,因此Student类里面有age和stuId两个变量,又因为是公有的,所以stu可以访问这两个变量的地址,我们对这两个值进行赋值操作。

    这两个赋值操作的反汇编代码如下,可以明显看出,它们都是先找到stu指向的Person对象的堆空间首地址,然后当给age赋值为18时,是把12h(18的十六进制)塞给Person对象首地址位置开始的4个字节,当给stuId赋值为2时,是把2(2的十六进制)塞给Person对象首地址+4位置处开始的4个字节,

    ec6cebf40d8bec8888f7e606c534f013.png
    3e787f3f0a1ab99826ecf244e693d6bd.png
    625f3717d228d362a49c84e8c86a394e.png

    大家可以看到上图,很明显,相信大家就看出问题来了。。

    因为new Person()只申请了4个字节的存储空间,而你现在却越界使用了没申请到的后面4个字节存储空间,然后把2赋值给了这4个字节的存储空间中。

    这会导致什么问题?因为后面的这4个字节没有被你申请到,那么该4个字节可能是其他的一些数据,那么你的这个行为会覆盖掉别的数据,或者这4个字节还是空闲的,以后可能被其他的数据覆盖,所以这是一种不安全的行为。

    因此,无论在C++还是java中,都是应该禁止掉这种行为的,只是java做了运行时检测,而C++并没有而已。

    展开全文
  • 下图是在java中,使用子类引用指向父类对象的情况​编译可以通过,因为对生成的Person对象做了一个强制转换,骗过了编译器,其本质上还是属于子类引用指向父类对象。点击运行,出现下图的报错情况。很明...
  • //父类引用指向子类对象,超人提升为了人//父类引用指向子类对象就是向上转型System.out.println(p.name);p.谈生意();SuperMan sm = (SuperMan)p;//向下转型sm.fly();/*基本数据类型自动类型提升和强制类型转换*/int ...
  • 假设有父类Fu ,其子类为Zi ,从对象的内存角度,假设Fu类里面的变量占内存2M, ...因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就是说会先执行父类的构造函数.所以
  • C++ 子类对象当父类对象使用

    千次阅读 2017-11-15 15:35:20
    子类对象当父类对象使用1⃣️把子类对象直接赋值给父类对象(等号左边是父类对象,等号右边是子类对象) 子类对象赋值给父类对象,仅仅把继承自父类部分成员函数赋值给父类对象 ...2⃣️父类的引用指向子类
  • Java继承,子类与父类初始化的执行顺序,父类引用和子类引用调用子类对象的区别子类与父类初始化的执行顺序父类引用和子类引用调用子类对象的区别 父类代码 public class Father { String name = "父类"; static...
  • 赋值兼容规则永远不变,父类指针既可以指向父类对象,也可以指向子类对象;当父类指针指向父类对象时,访问父类的成员;当父类指针指向子类对象时,那么只能访问子类中从父类继承下来的那部分成员;不能访问子类独有...
  • 子类对象指向父类引用,先执行父类,又有如下的优先级关系, 静态代码块>普通代码块>构造方法 所以先执行父类静态代码快,子类静态代码块,父类构造函数,子类构造函数。 ab = new B(); 又新建对象,重新执行构造...
  •    ——把等号右边的子类对象,赋值给等号左边的父类对象时,仅仅是把子类中来自于父类的那一部分成员,赋值给等号左边的父类对象,而赋值完成后,等号左边的对象,依然是父类对象。   (2) 父类引用指向子类...
  • 1. 无论是泛型还是普通父类引用指向子类对象父类引用可见范围都是父类自己的变量或函数2. 说明见注释代码如下:父类package com.atguigu.spring.beans;public class Father {public String fatherName;public ...
  • 原文地址:关于C++的子类指针指向父类.作者:leon  1,直接用基类指针引用基类对象 2,直接用派生类指针引用派生类对象 3,用基类指针引用一个派生类对象,由于派生类对象也是基类的对象,所以这种引用是安全...
  • 创建子类对象,a指向的应该是一个Dog类的对象,a.bark(d); 调用的应该是Dog重载的bark方法才对,可为什么最终调用的还是接口Animal的方法呢。 ```java public interface Animal { default void bark(Animal a) ...
  • [size=13px]在实现多态的过程中,为什么不直接让子类引用指向子类对象,而要让父类引用指向子类对象,这样做好什么好处?谢谢[/size]
  • C++的子类指针指向父类

    千次阅读 2015-04-10 15:38:13
    1,直接用基类指针引用基类对象 2,直接用派生类指针引用派生类对象 3,用基类指针引用一个派生类对象,由于派生类对象也是基类的对象,所以这种引用是安全的, 但是只能引用基类成员。若试图通过基类指针引用...
  • 原文地址:关于C++的子类指针指向父类.作者:leon   1,直接用基类指针引用基类对象 2,直接用派生类指针引用派生类对象 3,用基类指针引用一个派生类对象,由于派生类对象也是基类的对象,所以这种引用是...
  • 父类引用子类对象,父类对象子类对象之间的引用关系和区别
  • 父类中的private变量和方法,父类本身的对象是无法直接调用的,自然指向子类对象父类引用也是无法访问父类中的private变量和方法。注意点2 子类扩展父类的变量和方法,该引用是无法调用的。public class Point { ...
  • 父类引用指向子类对象,要调用的就是父类的方法而不是子类的方法,比如说定义一个父类animal类,一个子类 鸟类,鸟类有个独有的方法飞行。现在的情况是 Animal animal = new Bird (); 你要调用 animal.fly();...
  • 例如父类Person指向子类Student:Person p = new Student(); 父类类型实例p可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的; 同时,父类中的一个方法只有在在父类中定义...
  • 1.从对象的内存角度来理解.假设现在有一个父类Father,它里面的变量需要占用1M内存.有一个它的子类Son,里面的变量...因为子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类,也就...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,891
精华内容 2,756
关键字:

子类引用指向父类对象