A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

abstract class Animal
{
        public abstract void eat();
}
class Cat extends Animal
{
        public void eat()
        {
                System.out.println("吃鱼");
        }
        public void catchMouse()
        {
                System.out.println("抓老鼠");
        }
}
class DuoTaiDemo
{
        public static void main(String[] args)
        {
                Animal a = new Cat();//类型提升。 向上转型。
                a.eat();
        }
}
问题:
Person p = new Person("zhangsan",20);
对象初始化过程是:
1,因为new用到了Person.class.所以会先找到Person.class文件并加载到内存中。
2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
3,在堆内存中开辟空间,分配内存地址。
4,在堆内存中建立对象的特有属性。并进行默认初始化。
5,对属性进行显示初始化。
6,对对象进行构造代码块初始化。
7,对对象进行对应的构造函数初始化。
8,将内存地址付给栈内存中的p变量。

而:Animal a = new Cat();
这两句在内存中的对象的初始化过程是什么样的呀?

4 个回复

倒序浏览
这句话是建立一个父类的引用变量指向了子类的对象,在堆内存中开辟一块儿空间,用于储存new出来的对象,在栈内存中开辟一块内存储存父类的引用变量a,再把堆中对象的地址指向引用变量,注意的是,在编译时期是看的引用变量,引用变量要调用的方法必须是父类中存在的,运行行的时候要运行的是子类中重写父类的方法
回复 使用道具 举报
Animal a = new Cat();
是父类引用指向子类对象,是多态。
由于cat是继承它的父类Animal,所以Animal类型的引用是可以指向cat类型的对象的,所以父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义的父类中没有有的方法是不能调用的,同时父类中的一个方法只有在父类中定义而在子类中没有重写的情况下才能被父类类型的引用调用。

以前是创建对象并指挥对象做事情。有了多态以后,我们可以找到对象的共性类型,直接操作共性类型做事情即可,这样可以指挥一批对象做事情,即通过操作父类或接口实现。毕姥爷的话
回复 使用道具 举报
程序中父类Animal的引用a指向其子类Cat的对象,把程序Anima a = new Cat();
分成两部分看:
1、Animal a:这句会在栈内存中建立一个变量a
2、new Cat():在堆内存中创建一个Cat的对象,并把这个对象在内存中的地址赋给了
变量a。
其中,在new Cat()这一步时,会先去调用父类Animal的默认构造方法接着再调用
Cat自己的默认构造方法。


注意:
1、程序中a调用eat()方法,程序正常输出“吃鱼”,因为子类覆盖了父类的eat()
方法,而如果想调用自己特有的catchMouse()方法,必须强制类型转换才可以使用,
否则编译失败。
例:
Aimal a = new Cat();
a.catchMouse();   //编译失败


Aimal a = new Cat();
Cat c = (Cat)a;
a.catchMouse();  //编译通过

评分

参与人数 1技术分 +1 收起 理由
黑马张扬 + 1

查看全部评分

回复 使用道具 举报
给你个图

未命名.JPG (39.68 KB, 下载次数: 29)

未命名.JPG

评分

参与人数 1技术分 +1 收起 理由
黑马张扬 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马