JavaSE 成长之路@IT·程序猿程序员

JavaSE基础(十) - 内部类 👾

2016-12-17  本文已影响198人  SawyerZh
内部类

今天接触了一天的 Java 内部类,这个东西给我感觉一点就是:变化多端。之所以说这个东西变化多端,后面我们会用一些例子来证明,通过不同的形式来实现同一个方法。

内部类,可以分为以下四种

1.创建内部类类对象格式

class Outer {

    class Inner {

        public void method() {
            System.out.println("Hello Inner");
        }
    }
}

class Sample_InnerClass01 {

    public static void main(String[] args) {
        // 外部类.内部类 对象名 = 外部类对象.内部类对象;
        Outer.Inner oi = new Outer().new Inner();
        oi.method();
    }
}

Tip👉:直接通过这种方式在创建内部类对象是不常用、也不推荐的方式,下面我们会介绍其他调用内部类的方式。


2.成员内部类私有的使用

class Outer {

    private int num = 10;

    private class Inner {
        public void method() {
            System.out.println("Print: " + num);
        }
    }

    public void print() {
        Inner in = new Inner();
        in.method();
    }
}

class Sample_InnerClass02 {

    public static void main(String[] args) {
        Outer o = new Outer();
        o.print();
    }
}

Thinking💁‍♂️:本例中为什么内部类能访问到外部类的成员变量?


3.静态成员内部类

class Outer {

    private static int num = 10;

    static class Inner {
        public void method() {
            System.out.println("Print: " + num);
        }
    }
}

class Sample_InnerClass03 {

    public static void main(String[] args) {
        // 外部类.内部类 对象名 = 外部类名.内部类对象;
        Outer.Inner oi = new Outer.Inner();
        oi.method();
    }
}

Reminder👨‍💻:静态内部类中只能访问本类的静态成员。


4.成员内部类的小练习🐣

class Outer {

    public int num = 10;

    class Inner {
         public int num = 20;

         public void show() {
            int num = 30;
            System.out.println(num);            // 30
            System.out.println(this.num);       // 20
            // 内部类之所以能获取到外部类的成员,是因为它能获取到外部类的引用 外部类名.this
            System.out.println(Outer.this.num); // 10
         }
    }
}

class Sample_InnerClass04 {

    public static void main(String[] args) {
        new Outer().new Inner().show();
    }
}

5.局部内部类访问局部变量

class Outer {

    public void method() {

        int num = 10;   // 在 JDK1.8之后 JVM 会自动加上 final 修饰符

        class Inner {
            public void print() {
                System.out.println(num);
            }
        }

        Inner in = new Inner();
        in.print();
    }
}

class Sample_InnerClass05 {

    public static void main(String[] args) {
        new Outer().method();
    }
}

6.匿名子类对象概述

new 类名或接口() {
    重写方法;
}
interface Inter {
    public abstract void print1();
}

class Outer {

    public void method() {
        Inter in = new Inter() {
            public void print1() {
                System.out.println("Print1");
            }
        };

        in.print1();
    }
}

class Sample_InnerClass06 {

    public static void main(String[] args) {
        new Outer().method();
    }
}

7.匿名子类对象重写多个方法的调用

interface Inter {

    public void show1();

    public void show2();
}

class Outer {

    public void method() {

        Inter in = new Inter() {    // 父类引用指向子类对象(多态)

            public void show1() {
                System.out.println("show1");
            }

            public void show2() {
                System.out.println("show2");
            }
        };

        in.show1();
        in.show2();
        System.out.println(in);
    }
}

class Sample_InnerClass07 {

    public static void main(String[] args) {
        new Outer().method();
    }
}

Discussion🤡:Inter 父类指向匿名子类对象,其实是一个多态,如果在子类对象中定义了父类中不存在的方法,则编译会报错。而如果创建一个子类对象来实现接口方法的话,就可以扩展子类特有的功能了。


8.接口对象作为参数传递的多种实现形式

interface Inter {
    void print();
}

class Demo {
    public static void method(Inter i) {
        i.print();
    }
}

class InterClass implements Inter {
    public void print() {
        System.out.println("Hello World1!");
    }
}

class Test {

    private static final Inter i3;

    static {
        i3 = new Inter() {
            public void print() {
                System.out.println("Hello World3!");
            }
        };
    }

    public static void main(String[] args) {
        // 1.创建一个实现接口的子类对象。
        InterClass i1 = new InterClass();
        Demo.method(i1);
        
        // 2.在方法中创建一个匿名子类并返回。
        Inter i2 = method();
        Demo.method(i2);
        
        // 3.定义一个 Inter类型的 static 成员变量,并在构造代码块中用赋值它的子类对象。
        Demo.method(i3);

        // 4.在成员方法的参数位置创匿名子类对象,并重写父类方法。(推荐方式)
        Demo.method(new Inter() {
            public void print() {
                System.out.println("Hello World4!");
            }
        });
    }

    public static Inter method() {
        return new Inter() {
            public void print() {
                System.out.println("Hello World2!");
            }
        };
    }
}

Discussion🤡:可以看到,通过子类实现 抽象类接口 的方式千变万化,语法的掌握是基础,但最终目的是为了提高代码的内聚性、减少耦合性并简化代码,只有从这个目的出发去使用我们的内部类才能让我们的编程能力得到提高。


9.悄悄话

上一篇下一篇

猜你喜欢

热点阅读