`
chenchuangfeng
  • 浏览: 79994 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

浅谈父类和子类构造器

    博客分类:
  • Java
阅读更多

      今晚师弟问了问题,关于子类和父类构造器的问题,做个分析总结:

 

运行代码:

 

package 左旋转字符串;


public  class A {
	public void testabstract(){
		System.out.print("父类方法  ");
		System.out.println("i = "+i);
	}
	A(){		
		System.out.println("palace 1");
		testabstract();
	}
	
	public static void main(String[] args) {
		cc cc = new cc();  
		System.out.println("palace 2");
		cc.testabstract();
	}

}
	
class cc extends A{
	private int i = 1;		
	public void testabstract(){	
		System.out.print("子类方法  ");
		System.out.println("i = "+i);
	}
	cc(){							
	
	}	

	
}

 结果:

 

 

palace 1
子类方法  i = 0
palace 2
子类方法  i = 1

 

 

 

cc cc = new cc();

这段代码,是实例化cc这个类的对象,会调用到cc的构造器

 

执行cc构造器是这样一个过程:

          1.最开始会隐式调用父类的构造器,对父类的非静态域进行初始化,执行父类A的构造器的时候,也会调用父类的构造器也就是Object类的构造器(这里会一层层往上级调用其构造器,知道最顶层的Object后才一层层返回到cc的构造器中来)。

          2.在父类A的构造器中调用到testabstract();方法,这个方法是父类的还是子类的?这里涉及到多台,testabstract()  是等价于  this.testabstract(); this代表当前对象,虽然该方法是在父类构造器中调用的,但是父类构造器是被子类调用,所以归根结底,this代表的是cc的当前对象,而不是父类对象,所以父类中调用的testabstract()是子类的重写后的方法,运行结果证明了这点。

 

为什么同样调用了子类的testabstract()方法  在place1 和 place2 打印出来的结果不同呢?

      这点关系到构造器对变量初始化问题,在执行构造器前系统已经为整个对象申请了内存了,对象的成员变量已经申请到内存,但是还诶初始化,所以系统是赋默认值 int 的为 0,进入构造器的时候,第一件事是调用父类的构造器,此时i还没被赋值,其值仍然是0,父类构造器中调用到子类的方法,故输出的值是 0;

      而在place2 再去执行testabstract() 则能输入想要的结果1.因为初始化已经全部完毕了

 

2
2
分享到:
评论
6 楼 chenchuangfeng 2013-04-01  
刘彦明 写道
哇。正好解决了我的问题。如果实例化写成A cc = new cc();是不是先调用父类后再子类呢?。

对 没错 子类构造器最开头会调用父类构造器
5 楼 刘彦明 2013-04-01  
哇。正好解决了我的问题。如果实例化写成A cc = new cc();是不是先调用父类后再子类呢?。
4 楼 chenchuangfeng 2013-03-20  
夏小士2010 写道
chenchuangfeng 写道
夏小士2010 写道
应该在A的testabstract方法中不能输出i值吧,我感觉应该那时候i都没有实例化,这点关系到构造器对变量初始化问题,在执行构造器前系统已经为整个对象申请了内存了,对象的成员变量已经申请到内存,但是还诶初始化,所以系统是赋默认值 int 的为 0,,你说的这段说不通吧,你的i都没有在父类A中定义,他应该是未定义的变量吧


我上面那个例子其实没调用到父类的testabstract 方法,两次都是调用子类的。


嗯 刚看出来来,你是用子类new的子类,父类的方法不会走,呵呵,我的原因,没看仔细!sorry

呵呵 没事!交流交流
3 楼 夏小士2010 2013-03-19  
chenchuangfeng 写道
夏小士2010 写道
应该在A的testabstract方法中不能输出i值吧,我感觉应该那时候i都没有实例化,这点关系到构造器对变量初始化问题,在执行构造器前系统已经为整个对象申请了内存了,对象的成员变量已经申请到内存,但是还诶初始化,所以系统是赋默认值 int 的为 0,,你说的这段说不通吧,你的i都没有在父类A中定义,他应该是未定义的变量吧


我上面那个例子其实没调用到父类的testabstract 方法,两次都是调用子类的。


嗯 刚看出来来,你是用子类new的子类,父类的方法不会走,呵呵,我的原因,没看仔细!sorry
2 楼 chenchuangfeng 2013-03-18  
夏小士2010 写道
应该在A的testabstract方法中不能输出i值吧,我感觉应该那时候i都没有实例化,这点关系到构造器对变量初始化问题,在执行构造器前系统已经为整个对象申请了内存了,对象的成员变量已经申请到内存,但是还诶初始化,所以系统是赋默认值 int 的为 0,,你说的这段说不通吧,你的i都没有在父类A中定义,他应该是未定义的变量吧


我上面那个例子其实没调用到父类的testabstract 方法,两次都是调用子类的。
1 楼 夏小士2010 2013-03-18  
应该在A的testabstract方法中不能输出i值吧,我感觉应该那时候i都没有实例化,这点关系到构造器对变量初始化问题,在执行构造器前系统已经为整个对象申请了内存了,对象的成员变量已经申请到内存,但是还诶初始化,所以系统是赋默认值 int 的为 0,,你说的这段说不通吧,你的i都没有在父类A中定义,他应该是未定义的变量吧

相关推荐

    浅谈Java中父类与子类的加载顺序详解

    在这个例子中,子类的"SubClass--变量"、"SubClass--初始化块"和"SubClass--构造器"会在子类构造器内部被执行。 4. **多次创建对象**: - 如果创建多个子类对象,父类的初始化只进行一次,因为静态变量和静态初始...

    总结一——浅谈Java的类与对象

    在上述代码中,`new Person()`是一个构造器调用,用于创建新的Person对象,并为其分配内存空间。每个对象都有自己的状态(属性值),并且可以独立执行其定义的行为。 类与对象的关系密切,类是抽象的概念,而对象则...

    浅谈java异常处理(父子异常的处理)

    2. 子类构造器必须抛出父类构造器的异常或其父异常 子类构造器在执行时会自动调用父类的构造器。因此,如果父类构造器声明了异常,子类构造器要么直接抛出相同的异常,要么抛出该异常的父异常。下面是一个示例: `...

    浅谈java 面对对象(抽象 继承 接口 多态)

    **super关键字**在Java中用于引用父类的实例变量、方法和构造器。`super`和`this`都是在构造函数中使用,它们的作用是调用构造方法。`this`引用当前对象,而`super`引用父类对象。例如,当子类和父类中有同名的成员...

    浅谈Java变量的初始化顺序详解

    接下来,当创建子类对象时,会先执行父类的非静态变量、初始化块和构造器,最后才是子类的相应部分。 总结一下Java变量初始化顺序的要点: 1. **静态变量与静态初始化块**:首先按照在类中定义的顺序初始化所有...

    设计模式浅谈24种.ppt

    在《设计模式浅谈24种》中,主要讨论了24种经典的GOF设计模式,这些模式被分为三大类:创建型、结构型和行为型。 创建型模式主要关注对象的创建,包括以下几个核心模式: 1. **Abstract Factory**(抽象工厂)模式...

    浅谈生成器在设计中的应用

    - **里氏替换原则**:子类可以替换父类,不影响系统行为。 - **依赖倒置原则**:依赖于抽象,而不是具体实现。 - **接口隔离原则**:接口应尽可能小且专用,避免庞大而通用的接口。 - **迪米特法则**:降低类...

    浅谈Javascript面向对象编程

    标题《浅谈Javascript面向对象编程》涉及了JavaScript语言在实现面向对象编程(OOP)方面的核心概念及其灵活运用。接下来,我们详细地梳理一下从给定文件内容中提取的关于JavaScript面向对象编程的知识点。 1. 数据...

    一篇文章快速了解Java中的继承与多态

    这必须是子类构造器中的第一条语句。 - **访问父类的非私有属性**:如果子类和父类有同名属性,子类可以使用`super.attribute`来访问父类的属性。 - **调用父类的非私有方法**:子类如果重写了父类的方法,可以...

    浅谈Java中各种修饰符与访问修饰符的说明

    注意,构造器方法(构造函数)不能有访问修饰符,且在创建新对象时,先调用父类构造器,然后执行实例变量和静态变量初始化器,最后执行自身构造器。如果构造器没有显式调用父类构造器,编译器会自动添加`super()`。 ...

    浅谈js继承的实现及公有、私有、静态方法的书写

    call/apply继承是另一种继承方式,它通过在子类构造函数中调用父类构造函数来实现。在源码中,`childTwo`的构造函数使用`parent.call(this);`来继承父类。这种方式允许`parent`构造函数在`childTwo`的作用域中执行,...

    java程序员初学20道题

    如果子类构造函数中没有显式调用父类构造函数,则默认会调用父类的无参构造函数。 - 子类可以通过`super()`显式调用父类构造函数。如果不这样做,默认情况下会使用父类的默认构造函数(如果没有参数的构造函数)。 ...

    传智播客扫地僧视频讲义源码

    07_课堂答疑什么时候子类的步长和父类的步长一样 08_抽象类基本语法 09_抽象类在多继承中的应用 10_面向抽象类编程_计算程序员工资 11_中午课程回顾 12_信息系统框架集成第三方产品案例_背景和需求 13_信息系统框架...

    JAVA面试指南

    - **覆盖(Override)**:子类重写父类的方法,方法名、参数列表和返回类型都必须相同。 - **4.11 Collection与Collections的区别:** - `Collection`是Java集合框架的基础接口,定义了集合的基本操作。 - `...

Global site tag (gtag.js) - Google Analytics