Java子类new对象时执行顺序的问题

父类Meal,子类ProPreLunch ,当new ProPreLunch ()时,代码执行顺序为:父类静态块/静态变量(按代码的先后顺序执行)→子类静态块/静态变量(按代码的先后顺序执行)→父类非静态代码块/非静态变量(按代码的先后顺序执行)→父类构造方法→子类非静态代码块/非静态变量(按代码的先后顺序执行)→子类构造方法
代码如下:
父类:public class Meal {

			static{  //父类静态代码块
				System.out.println("Meal_aaa");
			}
			private static Cheese che = new Cheese();   //父类静态变量(静态域)
			
			
			private Cheese cheese = new Cheese();  //父类非静态代码块
			{
				System.out.println("Meal_bbb");  //父类非静态变量(静态域)
			}
			
			
			public static void Mead() {     //父类静态方法,调用才会执行,new对象时不会执行
				System.out.println("Meal_ccc");
			}
			
			public Meal() {  //父类构造方法
				System.out.println("meal()");
			}
		}

子类:
public class ProPreLunch extends Meal{

		private static Bread bread = new Bread();  //子类静态变量(静态域)
		static{   //子类静态代码块
			System.out.println("ProPreLunch_aaa");
		}
		
		
		{   //子类非静态代码块
			System.out.println("ProPreLunch_bbb");
		}
		private Lettuce lettuce = new Lettuce();  //子类非静态变量(静态域)
		
		
		public static void Mead() {  //子类静态方法
			System.out.println("ProPreLunch_ccc");
		}
		
		
		ProPreLunch(){   //子类构造方法
			System.out.println("ProPreLunch()");
		}
		
		
		public static void main(String[] args) {
			new ProPreLunch();
		}
	}

其它类:
public class Bread {
public Bread() {
System.out.println(“Bread()”);
}
}
public class Cheese {
public Cheese() {
System.out.println(“Cheese()”);
}
}
public class Lettuce {
public Lettuce() {
System.out.println(“Lettuce()”);
}
}
结果:Meal_aaa
Cheese()
Bread()
ProPreLunch_aaa
Cheese()
Meal_bbb
meal()
ProPreLunch_bbb
Lettuce()
ProPreLunch()

<think>好的,用户想了解Java中父类new子类对象的概念。首先,我需要明确用户的问题是否正确。因为实际上,在Java中,父类不能直接实例化子类对象,但可以通过父类引用指向子类实例。可能用户误解了这个概念,我需要澄清这一点。 接下来,我应该先解释基本概念,比如父类和子类的关系,以及对象实例化的语法。用户可能对多态和向上转型不太熟悉,所以需要详细说明。例如,Parent obj = new Child();这种情况,说明父类引用可以指向子类对象,但只能访问父类中声明的方法和变量,除非子类重写了父类的方法。 然后,需要区分声明类型和实际类型。声明类型是Parent,实际类型是Child。这候调用方法的话,会执行子类重写后的方法,这体现了多态的特性。同,成员变量的话,还是以声明类型为准,这可能是一个容易混淆的地方,需要特别指出。 用户可能想知道这种用法的应用场景,比如多态、扩展性、接口编程等。举例说明工厂模式或者方法返回父类引用,可以增加代码的灵活性。同,也要提到限制,比如无法直接调用子类特有的方法,除非进行强制类型转换,但转换前需要用instanceof检查,避免ClassCastException。 还需要注意常见的误区,比如父类本身不能直接创建子类对象,必须通过构造方法。还有内存分配的问题,虽然引用是父类类型,但实际对象占用子类的内存空间。这可能涉及到JVM的对象内存结构,但不需要太深入,点到为止即可。 最后,总结关键点,强调多态的优势和注意事项,确保用户理解正确的使用方式和潜在的问题。可能需要检查是否有遗漏的知识点,比如构造方法的执行顺序,或者静态方法的情况,但用户的问题可能不需要那么深入,保持回答简洁明了即可。</think>在Java中,父类通过`new`创建子类对象的现象称为 **向上转型(Upcasting)**,这是面向对象多态特性的重要体现。以下是逐步解析: --- ### 一、基本语法 ```java 父类类型 变量名 = new 子类构造方法(); ``` 示例: ```java Animal dog = new Dog(); // Animal是父类,Dog是子类 ``` --- ### 二、核心特性 1. **声明类型 vs 实际类型** - **声明类型**:左侧的`父类类型`(编译类型) - **实际类型**:右侧的`子类对象`(运行类型) - 例如: ```java List<String> list = new ArrayList<>(); // 声明类型List,实际类型ArrayList ``` 2. **方法调用规则** - 优先调用 **子类重写的方法**(动态绑定) - 若子类未重写,则调用父类方法 ```java class Animal { void sound() { System.out.println("动物叫"); } } class Dog extends Animal { @Override void sound() { System.out.println("汪汪"); } // 实际调用此方法 } ``` 3. **成员变量访问** - 以 **声明类型** 的变量为准(静态绑定) ```java class Parent { int value = 1; } class Child extends Parent { int value = 2; } Parent obj = new Child(); System.out.println(obj.value); // 输出1(而非子类的2) ``` --- ### 三、应用场景 1. **多态实现** ```java public void feed(Animal animal) { animal.eat(); // 可接受所有Animal子类对象 } ``` 2. **扩展性提升** 新增子类无需修改父类引用代码: ```java Animal animal = new Cat(); // 直接替换子类 ``` 3. **接口编程** 面向接口而非实现: ```java Map<String, Integer> map = new HashMap<>(); ``` --- ### 四、关键限制 1. **无法访问子类特有方法** 若子类有额外方法,需强制转型: ```java if (animal instanceof Dog) { Dog realDog = (Dog) animal; realDog.bark(); // 调用子类特有方法 } ``` 2. **构造方法链** 创建子类对象,会先调用父类构造方法: ```java class Parent { Parent() { System.out.println("父类构造"); } } class Child extends Parent { Child() { System.out.println("子类构造"); } } // 输出顺序:父类构造 → 子类构造 ``` --- ### 五、常见误区 - ❌ 错误理解:父类"变成"子类 本质是 **父类引用指向子类对象**,对象实际类型始终是子类 - ❌ 错误用法:直接`new 父类()`无法获得子类特性 例如`Animal animal = new Animal()`不会具有Dog类的行为 --- ### 六、内存图解 ``` 栈内存 堆内存 +------+ +---------------+ | animal | --> | Dog对象实例 | | (引用) | | - Animal字段 | +------+ | - Dog特有字段 | +---------------+ ``` 通过这种设计,Java实现了 **代码解耦** 和 **运行期动态绑定**,是面向对象灵活性的核心机制之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值