Java学习笔记11——内部类的继承与覆盖及总结

1、内部类的继承:

由于创建内部类对象的时候需要外部类的对象,所以在继承内部类的时候情况会比较复杂,需要确保内部类对象与外部类对象之间的引用正确建立,为了解决这个问题,Java提供了一种特殊的语法,来说明它们之间的关系。

package com.test;

class Outer {
    public class Inner{
        public void hello() {
            System.out.println("Hello,World.");
        }
    }
}

public class InheritInner extends Outer.Inner {
    //类InheritInner继承在Outer类中定义的内部类Inner
    //定义类类InheritInner的构造函数,传入参数类型为外部类对象
    public InheritInner(Outer ou) {
        ou.super();
    }
}

class Test3 {
    public static void main(String[] args) {
        Outer ou = new Outer();
        InheritInner ii = new InheritInner(ou);
        ii.hello();  //输出:"Hello,World."
    }
}

上面代码的理解:

(1)类InheritInner继承Outer类中定义的内部类Inner,为了建立内部类Inner的对象到外部类Outer的对象之间的关系,需要在子类InheritInner中定义一个特殊的构造方法,其参数是外部类Outer对象的引用,然后在子类的构造方法中使用“ou.super();”这种特殊语法的语句,来建立内部类对象到外部类对象的引用关系。

(2)在main方法中,依然是先建立外部类的对象,然后将该对象的引用传递给InheritInner类的构造方法。程序运行输出:"Hello,World.",说明成功运行,调用了InheritInner类继承自内部类Inner中定义的hello()方法。

2、内部类的覆盖:

编写一个类,从一个外部类继承,然后在类中重新定义外部类中的内部类,会发生什么情况呢?内部类是否会被重写呢?通过如下的代码可以更好理解。

package com.test;

class OneOuterClass {
    class OneInnerClass {
        public void foo() {
            System.out.println("1、这是一条定义在OneOuterClass类中的内部类OneInnerClass中的定义的foo()方法执行输出的信息。");
        }
    }

    // 定义外部类的构造函数,在构造函数内创建内部类OneInnerClass的对象,执行其foo()方法
    public OneOuterClass() {
        new OneInnerClass().foo();
    }
}

/**
 * OverrideInner类:继承Outer类
 */
public class OverrideInner extends OneOuterClass{
    class OneInnerClass {
        public void foo() {
            System.out.println("2、这是来自OverrideInner类中重新定义的OneInnerClass中的foo()方法输出的信息。");
        }
    }

    public static void main(String[] args) {
        new OverrideInner();
    }
}

运行上面的代码,输出信息:“1、这是一条定义在OneOuterClass类中的内部类OneInnerClass中的定义的foo()方法执行输出的信息。”

上面代码分析:

(1)类OverrideInner继承外部类OneOuterClass,并重新定义了OneOuterClass类中的内部类OneInnerClass。

(2)在类OneOuterClass的构造函数中调用了内部类OneInnerClass中定义的方法foo()。

(3)从输出信息看,在类OverrideInner中重新定义的OneInnerClass并没有覆盖继承的类OneOuterClass中定义的类OneInnerClass的方法。也就是没有覆盖。这是因为它们在完全不同的名称空间下,属于两个不同的内部类。

3、内部类规则总结

比起普通的顶层类来说,内部类有着更为复杂的规则。首先,内部类如同类中的成员一样,有访问权限,可以声明为public\protected\default(不加说明符时)\private,这与普通类是不一样的,普通类只能声明为public或者default(不加说明符)。

除了访问权限之外,我们还可以声明内部类为abstact、final或者static。当一个内部类被声明为抽象类时,就不能直接实例化这个内部类了;当一个内部类被声明为final时,说明这个类不能被继承;当一个内部类被声明为静态类static时,将可以直接创建这个内部类的对象。

当声明一个静态static的内部类(嵌套类)时,可以在这个内部类中加入静态方法,但是不能访问外部的非静态成员。在非静态的内部类中不能包含静态成员,静态成员属于类本身,可以直接通过类名来访问,而非静态的内部类对象依赖于外部类对象,也就是说,必须有外部类对象存在,而这与静态成员属于类本身,通过类名来调用冲突了。

内部类不仅可以让我们将逻辑上相关的一组类组织起来,并由外部类来控制内部类的可见性,而且与接口的结合能实现更为灵活与强大的功能。

Java并不支持类的多继承,当需要从多个类继承的时候,可以让外部类继承一个类,同时编写一个内部类来继承另外一个类。这样既能得到多继承的好处,又避免了C++多继承存在的问题。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值