Java子类与父类的转换

搬家后的博客链接: IT客栈 www.itkezhan.org

1、子类转换成父类
class A {
         public void func1() {
                   System.out.println("A func1 is calling.");
         }
         public void func2() {
                   func1();
         }
}
class B extend A {
         public void func1() {
                   System.out.println("B func1 is calling.");                 
         }
         public void func3() {
                   System.out.println("B func3 is calling.");
         }
}
class C {
         public static void main(String[] args) {
                   B b = new B();
                   A a = b;
                   callA(a);
                   callA(new B());
         }
         public void callA(A a) {
                   a.func1();
                   a.func2();
         }
}
编译器能够自动将类B的实例对象b直接赋值给A类的引用变量,也就是子类能够自动转换成父类类型。另外,程序可以直接创建一个类B的实例对象,传递给需要类A的实例对象作参数的callA()方法,在参数传递的过程中发生了隐式自动类型转换。子类能够自动转换成父类的道理非常容易理解。
2、父类转换成子类
如果知道callA方法中传递的参数a实际上就是子类B的一个引用对象,想在callA方法中调用子类的特有方法,如何做:
         public void callA(A a) {
                   a.func1();
                   a.func2();
                   a.func3();
         }
编译有问题,因为对编译器来说,它只分析程序语法,它只知道变量a的引用类型是类A,而类A又没有func3这个方法,所以编译不通过。代码改为:
         public void callA(A a) {
                   B b = a;
                   a.func1();
                   a.func2();
                   a.func3();
         }
编译还是有问题,因为编译器是不能将父类对象自动转换成子类的。
         public void callA(A a) {
                   B b = (B)a;         //强制类型转换
                   a.func1();
                   a.func2();
                   a.func3();
         }
 
-instanceof 操作符-
可以用instanceof判断是否一个类实现了某个接口,也可以用它来判断一个实例对象是否属于一个类
public void callA(A a) {
         if(a instanceof B){
                   B b = (B)a;
                   a.func1();
                   a.func2();
                   a.func3();
         } else {
                   a.func1();
                   a.func2();
         }
}
只要记住:一个男人肯定也是人,一个人却不一定是男人的道理,就非常容易理解父类和子类之间的转换关系了。
-Object类-
Object类是所有类的父类,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类就默认继承Object类。因此,Object类是Java类层中的最高层类,是所有类的超类。Java中任何一个类都是它的子类,由于所有的类都是由Object衍生出来的,所以Object的方法适用于所有类。
 
-面向对象的对态性-
当叫来一个中国人时,我们看到的是用筷子在吃饭,当叫来一个美国人时,我们看到的就是另外一番景象了,用的是叉子和刀子。同一段程序代码,却有两种截然不同的结果,这就是面向对象的多态性。特点:
  • 应用程序不必为每一个子类编写功能调用,只需要对抽象基类进行处理即可。
  • 子类的功能可以被父类的方法或引用变量调用,这叫向后兼容,可以提高程序的可扩充性和可维护性。
<think>好的,我现在需要回答用户关于Java子类作为父类内部类的用法和实现的问题。用户希望看到示例代码以及相关解释。首先,我需要回忆Java中内部类的基本概念,以及子类父类之间的关系。 首先,内部类是定义在另一个类中的类,可以访问外部类的成员,包括私有成员。而子类继承父类,可以重写父类的方法,或者添加新的方法。当子类作为父类的内部类时,可能需要考虑内部类的访问权限、如何实例化,以及如何访问外部类的成员。 接下来,我需要考虑用户提供的引用内容。引用[2]提到子类可以重写父类的方法,并使用@Override注解。引用[3]和[5]讨论了子类转换父类时的特性,比如父类引用无法访问子类特有的方法,但强转后可以。引用[4]展示了子类如何通过构造函数使用父类的依赖注入。这些引用可能对构建示例有帮助。 用户的问题涉及子类作为父类的内部类,所以需要构建一个外部类作为父类,内部类作为子类的情况。例如,父类Parent有一个内部类Child,Child继承Parent。或者,父类内部有一个内部类,而子类可能是在另一个外部类中,或者作为父类内部类的子类。这里可能需要明确结构。 可能的示例结构是: 1. 父类Parent,内部类InnerParent。 2. 子类Child继承Parent,并作为Parent的内部类。 或者,父类Parent有一个内部类Inner,而子类Child继承Inner,并可能也是内部类。 需要明确如何定义内部类,以及子类如何继承父类。例如,父类包含一个内部类,然后子类可以是另一个内部类或者外部类继承该内部类。或者,子类本身就是父类的内部类。 例如: public class Parent { class InnerParent { // 父类的内部类 } } public class Child extends Parent.InnerParent { // 子类继承父类的内部类,需要显式的外部类引用 public Child(Parent parent) { parent.super(); } } 这种情况下,Child继承自Parent的内部类InnerParent,并且需要在构造函数中传递Parent的实例,因为内部类的实例需要绑定到外部类的实例上。 或者,父类内部类自己作为父类子类作为另一个内部类: public class Outer { class Parent { // 父类的方法 } class Child extends Parent { // 子类继承父类,作为内部类 } } 这种情况下,Child作为Outer的内部类,继承自同为内部类的Parent。 需要构造一个示例,展示子类作为父类的内部类,并说明如何实例化和使用。 可能的示例步骤: 1. 定义外部类Parent,其中包含一个内部类InnerParent。 2. 定义子类Child,继承自InnerParent,并作为Parent的内部类,或者在另一个外部类中。 3. 展示实例化过程,包括可能需要的外部类实例引用。 4. 演示方法重写和访问权限的情况,比如子类重写父类内部类的方法,并访问外部类的成员。 同时,需要注意内部类的访问修饰符,如public、private等,以及是否需要外部类实例来创建内部类实例。 另外,用户提供的引用中提到子类转换父类时的行为,比如无法访问子类特有的方法,但在示例中可能涉及内部类的转换,需要说明这种情况。 可能的示例代码结构: public class Parent { // 父类的外部类 class InnerParent { void display() { System.out.println("父类内部类的方法"); } } // 子类作为父类的内部类 class ChildInner extends InnerParent { @Override void display() { System.out.println("子类内部类重写的方法"); } void specificMethod() { System.out.println("子类特有的方法"); } } public static void main(String[] args) { Parent parent = new Parent(); Parent.InnerParent inner = parent.new ChildInner(); inner.display(); // 调用重写的方法 // inner.specificMethod(); 错误,父类引用无法访问子类特有方法 if (inner instanceof Parent.ChildInner) { Parent.ChildInner child = (Parent.ChildInner) inner; child.specificMethod(); // 正确,通过强转调用 } } } 这样,ChildInner是Parent的内部类,继承自InnerParent(同为内部类)。在实例化时,需要先创建Parent实例,然后通过parent.new ChildInner()来创建内部类实例。当使用父类引用inner指向子类实例时,可以调用重写的方法,但无法访问子类特有的方法,除非进行强制类型转换。 这样的示例符合用户的需求,同时结合了内部类和继承的关系。需要注意内部类的实例化方式和访问权限,以及子类重写父类方法的注解使用,如@Override。 还需要检查是否符合用户提供的引用内容,比如引用[5]提到的父类引用无法访问子类特有方法,强转后可访问。在示例中,inner是InnerParent类型,无法调用specificMethod,但强转为ChildInner后可以。 另外,引用[4]提到子类通过构造函数使用父类的依赖,可能在内部类的构造中需要考虑外部类的引用,如Parent.this的引用。 总结,构建的示例应包含: - 父类作为外部类,内部类InnerParent。 - 子类ChildInner作为父类的内部类,继承InnerParent。 - 展示实例化过程,方法重写,类型转换,以及访问权限的问题。</think>以下示例展示Java子类作为父类内部类的实现方式,包含类型转换和访问权限的典型特征: ### 父类子类内部类实现 ```java public class OuterParent { // 父类内部类 class InnerBase { void commonMethod() { System.out.println("父类内部类的公共方法"); } } // 子类作为父类的内部类 class ChildInner extends InnerBase { @Override void commonMethod() { System.out.println("子类内部类重写的方法"); } void uniqueMethod() { System.out.println("子类内部类特有方法"); } } public static void main(String[] args) { OuterParent outer = new OuterParent(); // 子类实例向上转型为父类引用 InnerBase baseRef = outer.new ChildInner(); baseRef.commonMethod(); // 输出:子类内部类重写的方法 // baseRef.uniqueMethod(); // 编译错误:父类引用无法访问子类特有方法[^5] // 强制向下转型访问子类方法 if (baseRef instanceof ChildInner) { ChildInner childRef = (ChildInner) baseRef; childRef.uniqueMethod(); // 输出:子类内部类特有方法[^3] } } } ``` ### 关键特性说明 1. **嵌套关系** `ChildInner`作为`OuterParent`的内部类,继承自同为内部类的`InnerBase`。内部类的继承需要先创建外部类实例(`outer.new ChildInner()`)[^4] 2. **方法重写** 子类内部类使用`@Override`注解重写父类方法,确保类型安全(普通继承机制一致)[^2] 3. **类型转换限制** - 父类引用`baseRef`无法直接调用子类特有方法`uniqueMethod()` - 通过强制类型转换`(ChildInner)`恢复子类完整功能 4. **作用域访问** 内部类可直接访问外部类的私有字段: ```java class OuterParent { private int secret = 10; class InnerBase { void accessSecret() { System.out.println("访问外部类私有字段: " + secret); // 合法 } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值