Java基础-内部类

内部类

优点:

1.内部类与外部类可以方便的访问彼此的私有域(包括私有方法、私有属性)。
2.内部类是另外一种封装,对外部的其他类隐藏。
3.内部类可以实现java的单继承局限。

缺点:

1.结构复杂。

分类:
  1. 成员内部类
  2. 局部内部类
  3. 匿名内部类
  4. 静态内部类(到这里就有个问题:java一般类能不能用static修饰呢?)

编译器不允许最外层的类声明为static,但是可以声明内部类为static。

一、成员内部类

我感觉这是比较常见的,类Pet像是类Person的一个成员,Person称为外部类。成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。

class Person{
    public String name;
    public int age;
    public Person(){}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    //内部类作为外部类的成员;
    public class Pet{
        public String name;
        public int age;

        public Pet() {}
        public Pet(String name, int age) {
            this.name = name;
            this.age = age;
        }
    }
}

注意:成员内部类内部不允许存在任何static变量或方法 正如成员方法中不能有任何静态属性 (成员方法与对象相关、静态属性与类有关),静态成员内部类内部方法不允许访问外部非静态成员。

       内部类就相当于一个外部bai类的成员变量,du所以可以直接访问外部变量,外部类不能直接访问内部类变量,必须通过创建内部类实例的方法访问,
new InnerClass(32).m就是创建内部类实例访问内部类成员变量。
       你想不通的肯定是指内部类的私有变量怎么可以被外部类访问吧,按常规,私有变量m只能在InnerClass里被访问,但你要注意,内部类就相当于一个外部类的成员变量,举个例子:

class Outer{
    private int m;
    private class Inner{
        private int n;
        private int k;
    }
}

        m和类Inner都是成员变量,他们之间是平等的,唯一不同的就是Inner它是包装了几个成员变量比如n,k,也就是说m、n、k是平等的,区别在于访问n k要通过Inner,就是要建立Inner实例访问n、k.

二、静态内部类

public class Outer {
    //定义一个实例变量和一个静态变量
    private int a;
    private static int b;
    //定义一个静态方法和一个非静态方法
    public static void say(){}
    public void test(){
        //在外部类中调用内部类的属性和方法
        Outer.Inner.c = 1;            //可以通过静态内部类的全类名来调用静态内部类的静态属性(外部类名.静态内部类名.属性)
        Outer.Inner.go();            //可以通过静态内部类的全类名来调用静态内部类的静态方法(外部类名.静态内部类名.方法)
        //Outer.Inner.walk();        //不能通过类静态内部类的全类名来调用内部类的非静态属性和方法
        Inner inner = new Inner();
        inner.d = 1;
        inner.walk();                    //可以通过创建内部类实例来调用静态内部类的非静态属性和方法
    }
    //静态内部类
    public static class Inner{
        //在静态内部类中定义一个静态变量和一个实例变量
        static int c;
        int d;
        //定义一个匿名代码块和一个静态代码块
        {}
        static{}
        //定义一个静态方法和一个普通方法
        public static void go(){}
        public void walk(){
            //在静态内部类中调用外部类的属性和方法
            int f = b;                     //可以直接调用外部类的静态属性
            say();                        //可以直接调用外部类的静态方法
            //int e = a;                 直接调用外部类的非静态属性出错编译出错
            //test();                    直接调用外部类的非静态方法时编译出错
            Outer outer = new Outer();
            int e = outer.a;            //可以通过创建外部类实例来调用外部类的非静态属性
            outer.test();                //可以通过创建外部类实例来调用外部类的非静态方法
        }
    }
}

----参考https://www.cnblogs.com/heavenplus/p/9451181.html

三、局部内部类

       局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
       注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。

  • 在方法中定义内部类:

Java教材里的解释
注意:即使是方法中定义的内部类也是可以像非静态内部类访问外部类一样,用外部类对象.方法()来访问。

四、匿名内部类

       匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。
       详细例子可见Java基础图形界面类内分开设置各种按钮的键盘事件时。

五、内部类的创建

4.1 在外部类外部 创建非静态内部类

语法: 外部类.内部类 内部类对象 = new 外部类().new 内部类();
举例: Outer.Inner in = new Outer().new Inner();

4.2 在外部类外部 创建静态内部类

语法: 外部类.内部类 内部类对象 = new 外部类.内部类();
举例: Outer.Inner in = new Outer.Inner();

4.3 在外部类内部创建内部类语法

在外部类内部创建内部类,就像普通对象一样直接创建:
Inner in = new Inner();



文章总结:内部类的应用:

  1. 每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整,
  2. 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏。
  3. 方便编写事件驱动程序
  4. 方便编写线程代码

参考:
https://www.cnblogs.com/dolphin0520/p/3811445.html(详细)
https://www.cnblogs.com/heavenplus/p/9451181.html
https://blog.csdn.net/zhao_miao/article/details/83245816

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 下列说法中关于内部类的说法正确的是( )。 A. 内部类只能访问外部的静态成员 B. 内部类只能在外部的方法中被实例化 C. 内部类可以访问外部的私有成员 D. 内部类不能继承其他 答案:C。内部类可以访问外部的私有成员。 2. 下列代码的输出结果是( )。 class Outer { private int num = 10; class Inner { public void print() { System.out.println("num = " + num); } } } public class Test { public static void main(String[] args) { Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); inner.print(); } } A. num = 10 B. num = 0 C. 编译错误 D. 运行时错误 答案:A。内部类可以访问外部的私有成员,因此可以输出num的值。 3. 下列代码的输出结果是( )。 class Outer { private int num = 10; public void method() { class Inner { public void print() { System.out.println("num = " + num); } } Inner inner = new Inner(); inner.print(); } } public class Test { public static void main(String[] args) { Outer outer = new Outer(); outer.method(); } } A. num = 10 B. num = 0 C. 编译错误 D. 运行时错误 答案:A。方法内部定义的局部内部类可以访问外部的成员变量,因此可以输出num的值。 4. 下列说法中关于静态内部类的说法正确的是( )。 A. 静态内部类不能访问外部的静态成员 B. 静态内部类只能在外部的静态方法中被实例化 C. 静态内部类不能访问外部的非静态成员 D. 静态内部类不能继承其他 答案:A。静态内部类不能访问外部的非静态成员,但可以访问外部的静态成员。 5. 下列代码的输出结果是( )。 class Outer { private int num = 10; static class Inner { public void print() { System.out.println("num = " + num); } } } public class Test { public static void main(String[] args) { Outer.Inner inner = new Outer.Inner(); inner.print(); } } A. num = 10 B. num = 0 C. 编译错误 D. 运行时错误 答案:C。静态内部类不能访问外部的非静态成员,因此编译错误。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值