黑马程序员技术交流社区

标题: 关于在内存中进行对象初始化的步骤问题 [打印本页]

作者: 黄昆    时间: 2012-7-5 15:38
标题: 关于在内存中进行对象初始化的步骤问题
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();
这两句在内存中的对象的初始化过程是什么样的呀?
作者: 孙飞    时间: 2012-7-5 15:45
这句话是建立一个父类的引用变量指向了子类的对象,在堆内存中开辟一块儿空间,用于储存new出来的对象,在栈内存中开辟一块内存储存父类的引用变量a,再把堆中对象的地址指向引用变量,注意的是,在编译时期是看的引用变量,引用变量要调用的方法必须是父类中存在的,运行行的时候要运行的是子类中重写父类的方法
作者: 杨锦    时间: 2012-7-5 16:03
Animal a = new Cat();
是父类引用指向子类对象,是多态。
由于cat是继承它的父类Animal,所以Animal类型的引用是可以指向cat类型的对象的,所以父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义的父类中没有有的方法是不能调用的,同时父类中的一个方法只有在父类中定义而在子类中没有重写的情况下才能被父类类型的引用调用。

以前是创建对象并指挥对象做事情。有了多态以后,我们可以找到对象的共性类型,直接操作共性类型做事情即可,这样可以指挥一批对象做事情,即通过操作父类或接口实现。毕姥爷的话
作者: dev    时间: 2012-7-5 18:40
程序中父类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();  //编译通过


作者: 陆强强    时间: 2012-7-5 20:40
给你个图

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

未命名.JPG





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2