创建子类时父类构造方法中调用其他方法

探讨了在Java中创建子类时,父类构造方法如何调用被子类覆盖的方法,解析了对象创建过程中的方法调用顺序及原因,包括子类方法覆盖的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建子类时父类构造方法中调用其他被子类覆盖的方法


笔试遇到一个这样的题:


public class Parent {

	private static String city = "东莞";

	public Parent ()
	{
		this.print();
	}
	public void print (){
		printCity();
	}
	private static void printCity (){
		System.out.println("parent:"+city);
	}
	
	static class Child extends Parent{
		private static String city ="深圳";
		public Child ()
		{
			//super.print();
		}
		public void print (){
			printCity();
		}
		public static void printCity (){
			System.out.println("Child:"+city);
		}
	}
	
	public static void main(String[] args) {
		Parent p = new Child();
	}
}

//输出结果:Child:深圳

通过调试找到了调用的顺序:
new的时候会调用loadClass类加载器,调用父类无参构造器,父类无参构造器中调用了其他方法print(),在此过程中执行的对象都是子类对象,且子类中有print()函数,所以此处调用的print()为子类的print()方法。所以输出的是Child:深圳。

在删去子类的print()方法后,由于子类没有print()方法,所以调用父类的print()方法,输出:parent:东莞。

package inherited;

public class Parent {

	private static String city = "东莞";

	public Parent ()
	{
		this.print();
	}
	public void print (){
		printCity();
	}
	public static void printCity (){
		System.out.println("parent:"+city);
	}
	
	static class Child extends Parent{
		private static String city ="深圳";
		public Child ()
		{
			//super.print();
		}
//		public void print (){
//			printCity();
//		}
		public static void printCity (){
			System.out.println("Child:"+city);
		}
	}
	
	public static void main(String[] args) {
		Parent p = new Child();
	}
}
//输出:
parent:东莞

在网上又找到了一串这样的代码

class Supper {
    int i = 10;
    public Supper() {
        //System.out.println("111111");
        print();
        i = 20;
    }
    int j;
    public void print() {
        System.out.println("Supper==="+i);
    }
}

class Sub extends Supper {
    
    public Sub() {
        //System.out.println("222222");
        print();
        super.print();
        i = 40;
    }
    int i = 30;
    public void print() {
        System.out.println("Sub==="+i);
    }
}

public class Test {
    public static void main(String[] args) {
        new Sub();
    }
}
/*
输出:
Sub===0
Sub===30
Supper===20

*/

第一个输出Sub为0,是因为调用的父类构造器中的print(),调用的是子类的print()方法,此时子类还没有初始化 i ,所以 i 的值为0。第二次调用print()是子类构造器中的print(),此时 i 已被赋值,所以输出 i 为30。

new时,先调用类加载器——初始化父类的成员变量——调用父类构造器——构造器中调用了子类的print()(此时子类中的成员变量还没初始化,为默认值 0 )——父类构造器结束——初始化子类成员变量——调用子类构造器——子类构造器中调用了print()——输出 i 为初始化的30

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值