java中子类转父类和父类转子类

本文深入探讨了Java中父类与子类之间的转换机制,包括子类到父类、父类到子类的转换过程及注意事项,特别关注了ClassCastException异常的触发条件。

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

前提概要

已经有父类和子类如下所示:

// 父类
public class Parent {}

// 子类
public class Son extends Parent {}

// 女儿类
public class Daughter extends Parent {}

子类转父类

子类的引用指向子类转父类对象

Son son = new Son();
Parent parent = (Parent) son;

结果

运行没问题

父类的引用指向子类转父类对象

Parent son = new Son();
Parent parent = (Parent) son;

结果

运行没问题,这种肯定也是可以的

父类转子类

父类的引用指向父类转子类对象

Parent parent = new Parent();
Son son = (Son) parent;

结果

运行有问题会报 ClassCastException

父类的引用指向子类转子类对象

Parent parent = new Son();
Son son = (Son) parent;

结果

运行没有问题

父类的引用指向子类转另一个子类对象

Parent parent = new Son();
Daughter daughter = (Daughter) parent;

结果

运行时报出 ClassCastException 的异常

### Java 中子父类传递参数的方法 在 Java 中,当创建一个子类的对象时,默认情况下会先调用父类的无参构造函数。然而,在实际开发中经常需要带参数来初始化父类中的属性。这可以通过显式地使用 `super` 关键字来完成。 #### 使用 super 调用父类构造函数 为了使子类能够向父类传递参数,可以在子类的构造函数里利用 `super()` 来指定要调用哪个版本的父类构造器,并提供相应的实参列表[^2]: ```java class Parent { String name; public Parent(String name) { // 父类中有参构造函数 this.name = name; System.out.println("Parent Constructor Called, Name is " + name); } } class Child extends Parent { public Child(String childName, String parentName) { super(parentName); // 显式的调用了父类的有参构造函数 System.out.println("Child Constructor Called, Child's own property not initialized yet"); } } ``` 在这个例子中,每当实例化一个新的 `Child` 对象时,都会自动执行带有两个字符串参数的构造函数。该构造函数内部的第一条语句即为对父类构造函数的调用,它接收来自子类的一个额外参数用于设置父类的数据成员。 #### 注意事项 - 如果父类只有含参构造而没有无参构造,则子类必须在其构造函数内通过 `super(...)` 或者间接地经由其他方式确保能访问到合适的父类构造形式。 - 当定义了一个自定义构造函数之后,即使它是私有的或者是受保护级别的,编译器也不会再为你合成默认(无参)构造函数了;因此在这种情形下如果不主动声明任何构造函数的话,将会导致无法隐式调用父类构造的情况发生。 #### 完整示例程序 下面给出一段完整的代码片段展示上述概念的应用场景: ```java public class MainApp { static class Parent { private final int value; protected Parent(int v){ this.value = v; System.out.printf("Parent constructor called with %d\n",v); } @Override public String toString(){ return String.format("Value from Parent: %d",this.value); } } static class Child extends Parent{ private final double factor; public Child(double f,int pVal){ super(pVal); // 此处传入pVal作为父类构造函数的参数 this.factor=f; System.out.printf("Child constructor called with %.1f and inherited value of %s\n", f,new Parent(pVal)); } @Override public String toString(){ return String.format("%s * Factor=%.1f=%g",super.toString(),factor,value()*factor); } private float value(){return (float)this.factor*(int)(Math.random()*10);} } public static void main(String[] args) { new Child(2.789,45).toString(); } } ``` 此段代码展示了如何在一个继承体系结构中有效地让子类父类传递必要的配置信息以便于后者可以正常工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

abcnull

您的打赏是我创作的动力之一

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值