MyException - 我的异常网
当前位置:我的异常网» J2SE » 子类对象是包含整个父类对象仍是仅仅拥有父类对象的

子类对象是包含整个父类对象仍是仅仅拥有父类对象的引用?

www.MyException.Cn  网友分享于:2015-01-22  浏览:0次
子类对象是包含整个父类对象还是仅仅拥有父类对象的引用??
子类为C,父类为F;
---------------------------------------------------------
C实例化之前会先实例化F
那么
最后得到的C对象是包含了F对象
还是
仅仅在C对象中包含了F对象的引用??如果是这种情况,是不是说:实例化一个子类对象,会把他所有的父类实例化并且保存下来,这样是不是会很浪费内存,毕竟好多类是有很多父类的。

问题应该也可以等同于
当通过C对象调用没有被覆写的方法时,是直接调用了C对象中的方法?
还是通过引用调用了F对象的方法?
------解决思路----------------------
C实例化之前会先实例化F  意思是说创建子类对象之前先创建父类对象吗?
创建子类不会创建父类对象吧!详情http://liujinpan75.iteye.com/blog/785136
------解决思路----------------------
子类为C,父类为F;
---------------------------------------------------------
C实例化之前会先实例化F
那么
最后得到的C对象是包含了F对象?
还是
仅仅在C对象中包含了F对象的引用??如果是这种情况,是不是说:实例化一个子类对象,会把他所有的父类实例化并且保存下来,这样是不是会很浪费内存,毕竟好多类是有很多父类的。

问题应该也可以等同于
当通过C对象调用没有被覆写的方法时,是直接调用了C对象中的方法?
还是通过引用调用了F对象的方法?
=====================================================================
首先,他们是继承关系!这里的继承和实例对象是两个维度,可以理解为代码的复用。所以子类实例化并不会实例化一个父类,而是会初始化父类,原因很简单他要复用父类的属性和方法。
第二,你所说的方法调用那么要从字节码class深入理解,你可以看一下生成的class文件,如果子类没有重写父类的方法,那么是不会包含父类的方法信息(就是说子类没有父类的方法代码),那么他是怎么调用的呢?很简单,字节码里边生成的时候有个所属父类索引信息,jvm执行的时候就是通过这些属性执行方法流程的,当然这个在编写java程序时不可见,楼主可以u看看jvm的深入理解便会明白很多。
------解决思路----------------------
ackage extendtest;

/**
 *
 * @author Administrator
 */
public class Test {
public static int Number=1;
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Child ppa=new Child();
    }
    
}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools 
------解决思路----------------------
 Templates
 * and open the template in the editor.
 */

package extendtest;

/**
 *
 * @author FathersFatherdministrator
 */
public class FathersFather {
    private String i;
    private static String s;
    {
        this.i="FathersFather";
        System.out.println(Test.Number+++"  "+i+"实例变量初始化");
    }
    static {
        s="FathersFather";
        System.out.println(Test.Number+++"  "+s+"类变量初始化");
    }
    public FathersFather() {
        System.out.println(Test.Number+++"  "+"FathersFather构造器调用");
    }
   
}

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools 
------解决思路----------------------
 Templates
 * and open the template in the editor.
 */

package extendtest;

/**
 *
 * @author Administrator
 */
public class Father extends FathersFather{
    private String i;
    private static String s;
    {
        this.i="Father";
        System.out.println(Test.Number+++"  "+i+"实例变量初始化");
    }
    static {
        s="Father";
        System.out.println(Test.Number+++"  "+s+"类变量初始化");
    }
    public Father() {
        System.out.println(Test.Number+++"  "+"Father构造器调用");
    }
}

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools 
------解决思路----------------------
 Templates
 * and open the template in the editor.
 */

package extendtest;

/**
 *
 * @author Administrator
 */
public class Child extends Father{
    private String i;
    private static String s;
    {
        this.i="Child";
        System.out.println(Test.Number+++"  "+i+"实例变量初始化");
    }
    static {
        s="Child";
        System.out.println(Test.Number+++"  "+s+"类变量初始化");
    }

    public Child() {
        System.out.println(Test.Number+++"  "+"Child构造器调用");
    }
    
}


运行结果:


1  FathersFather类变量初始化
2  Father类变量初始化
3  Child类变量初始化
4  FathersFather实例变量初始化
5  FathersFather构造器调用
6  Father实例变量初始化
7  Father构造器调用
8  Child实例变量初始化
9  Child构造器调用

=========================
结论:子类实例化必然伴随父类实例化,也就是说产生了父类的对象。但是父类对象的引用不可传递。也就是说只能通过super关键字从子类中访问父类的方法、字段。构造器等,当然,是在权限许可的情况下。但是无法将super赋值给新的引用变量。
------解决思路----------------------
引用:
Quote: 引用:

C实例化之前会先实例化F  意思是说创建子类对象之前先创建父类对象吗?
创建子类不会创建父类对象吧!详情http://liujinpan75.iteye.com/blog/785136


谢谢,被网上一些资料误导了。
那么:
实例化C后,F并没有实例化,而仅仅是初始化,那么F就没有形成对象了,这样F的成员变量也就不会分配内存空间是吧??
我做了一个小实验:C,F都有Private int id;   那么C的对象是可以对C和F的id进行Set和Get的。
那么是不是说,
在C实例化时,会把F的成员变量(比如id)给继承下来,即使名字一样,即使是private,也会进行处理保存??
而F的方法则是放在代码区,在C对象需要调用时会按照索引按步骤查找,1。如果方法在C的方法区(额,存放代码的地方,不知诌的对不对)里找到就执行C的,2。如果在C的方法中没有找到就会自动寻找它的父类的方法区3。以此类推


没错~你的理解是对的。
------解决思路----------------------
父类初始化是肯定的,同时父类的构造函数也会被调用,这就相当于实例化了父类,只是没有将其赋给一个引用变量而已。
------解决思路----------------------
1.对像和类是两个维度的东西,您以可将子类和父类看成完全不同的两个类,所以它们的实例化没有任何相干性。
2.子类的实例和父类的实例之前没有任合关系。
3.子类的对像只是和你类拥有相同的父类暴露出来的函数、常量值、成员变量名及初始化值,仅此而已。
------解决思路----------------------
对象的实例化和初始化是两个概念
对象初始化的时候如果发现父类没有被初始化,就会先初始化父类,依次类推,但是如果父类是接口则不会去初始化父类
类的初始化是由类被主动使用导致的,new是一种,Class.forName()是一种,还有就是调用一个类的方法、属性或延迟的常量(就像下面的例子)

public class InitialTest {

    public static void main(String[] args) {
        Entity e = new Entity();
        Good g = e.CONST;//此处注释就不会打印"Good initial!"
    }

    static class Entity implements Bean {

        @Override
        public void execute() {
            // TODO Auto-generated method stub

        }
        static{
            System.out.println("Entity initial!");
        }
    }

    interface Bean {

        Good CONST = new Good();

        void execute();
    }

    static class Good {

        static {
            System.out.println("Good initial!");
        }
    }
}



------解决思路----------------------
大多数类都有默认的构造方法,子类实例化时会先调用父类的构造方法。
因为是继承,所以子类继承了父类除构造方法以外的所有方法,实例化谁就调用谁里面的方法,也就是new后面的那部分。
------解决思路----------------------
从实现上来说,父子进程应该位于一个同样的内存起始地址,只不过对这片内存地址的引用和解释依赖于前面的类型,因为Java依赖于JVM,所以这个地方你可以借用下C++看下,OO的实现机制大体都是一样的,父子进程没道理布局在不同的内存区域上,因为这样在runtime时,势必降低效率
你看下C++的实现

#include <iostream>
using namespace std;


class A{
public:
    A(){
        this->value = 2;
    printf("Parent %p %p\n ",this, &(this->value));
    }

public:
    int value;
};


class B: public A{
public:
    B(){
        this->value = 0;
        this->mChildValue = 1;
        printf("Child %p %p\n\n", this, &(this->mChildValue));
    }
private:
    int mChildValue;
};

int main(int argc, char *argv[])
{
    B b;
    return 0;
}

Parent 0x7fff5fbffc88 0x7fff5fbffc88
 Child 0x7fff5fbffc88 0x7fff5fbffc8c
0x7fff5fbffc88 这个是父子进程的内存首地址,2者是一样的,构造的时候先构造了父类,接着在后面的内存区上构建子类 对应的java对象这个构建在堆上  0x7fff5fbffc8c 这个由于子类自己加了一个4字节的成员变量,可以看到子类和父类的field的偏移量就是这个4字节的对象
------解决思路----------------------
打错了  父子对象

文章评论

亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
那些争议最大的编程观点
那些争议最大的编程观点
我是如何打败拖延症的
我是如何打败拖延症的
为什么程序员都是夜猫子
为什么程序员都是夜猫子
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
代码女神横空出世
代码女神横空出世
程序员和编码员之间的区别
程序员和编码员之间的区别
中美印日四国程序员比较
中美印日四国程序员比较
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
一个程序员的时间管理
一个程序员的时间管理
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
程序员的鄙视链
程序员的鄙视链
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员都该阅读的书
程序员都该阅读的书
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
程序员必看的十大电影
程序员必看的十大电影
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
Java程序员必看电影
Java程序员必看电影
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
每天工作4小时的程序员
每天工作4小时的程序员
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
老程序员的下场
老程序员的下场
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
我的丈夫是个程序员
我的丈夫是个程序员
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
鲜为人知的编程真相
鲜为人知的编程真相
如何成为一名黑客
如何成为一名黑客
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
漫画:程序员的工作
漫画:程序员的工作
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
编程语言是女人
编程语言是女人
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有