Java中的内部类


  

引言:

Java中的内部类。当一个事物的内部,还有一个部分需要一个完整的结构进行描述,而这个内部完整的结构有只为外部事物提高服务,那么这个内部完整的结构最好使用内部类。

  java 中允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类。Inner class一般在定义它的类或语句块之内使用,在外部引用它是必须给出完整的名称。Inner class的名称不能与包含它的外部类类名相同。

  1. Java中允许将一个类A声明在另一个类B中,则类A就是内部类,类B称为外部类

  2. 分类

    • 成员内部类(static成员内部类和非static成员内部类)
    • 局部内部类(方法内、代码块内、构造器内)
    • 匿名内部类
  3. 成员内部类:

  • 一方面,作为外部类的成员:
  • 调用外部类的结构
  • 可以被static修饰
  • 可以被4种不同的权限修饰
  • 另一方面,作为一个类:
  • 类内可以定义属性、方法、构造器等
  • 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
  • 可以被abstract修饰
  1. 内部类的结构
//外部内
class Person {

    String name;
    int age;
    public void eat() {
        System.out.println("人,吃饭");
    }

    //静态成员内部类
    static class Dog{
        String name;
        int age;
        public void show() {
            System.out.println("卡拉是条狗");
            //eat();//报错,静态结构中不能调用非静态的属性、方法
        }
    }

    //非静态成员内部类
    class Bird {
        //属性
        String name;
        //方法
        public void sing() {
            System.out.println("我是一只小小鸟");
            //内部类中调用外部内的属性和方法
            Person.this.age = 2;
            eat();//Person.this.eat();
        }
        //构造器
        public Bird() {}
    }

    {
        //局部内部类
        class BB {}
    }

    public Person() {
        //局部内部类
        class CC {}
    }

    public void method() {
        //局部内部类
        class AA {}
    }

    //成员内部类
    private class A1{}
    class A2{}
    protected class A3{}
    public class A4{}
    final class A5{}
    static class A6{}
    static final class A7{}
    abstract class A8{}

    //内部接口
    private interface B1{}
    interface B2{}
    protected interface B3{}
    public interface B4{}
    //static interface B5{} //redundant for inner interfaces
    //abstract interface B6{} //redundant for inner interfaces
}
  1. 如何实例化成员内部类的对象
public class InnerClassTest {
    public static void main(String[] args) {
        //创建Dog实例(静态的成员内部类)
        Person.Dog dog = new Person.Dog();
        dog.show();

        //创建Bird实例(非静态的成员内部类)
//      Person.Bird bird = new Person.Bird();//错误的
        Person p = new Person();
        Person.Bird bird = p.new Bird();
        bird.sing();

    }
}

class Person {

    String name;
    int age;
    public void eat() {
        System.out.println("人,吃饭");
    }


    static class Dog{
        String name;
        int age;
        public void show() {
            System.out.println("卡拉是条狗");
        }
    }

    class Bird {
        String name;

        public void sing() {
            System.out.println("我是一只小小鸟");
        }

        public Bird() {}
    }
}
  1. 如何在成员内部类中区分调用外部内的结构
public class InnerClassTest {
    public static void main(String[] args) {
        Person.Bird bird = new Person().new Bird();
        bird.sing();
        bird.display("哈哈,哈哈哈哈");
    }
}

class Person {

    String name = "Tom";
    int age;
    public void eat() {
        System.out.println("人,吃饭");
    }


    static class Dog{
        String name;
        int age;
        public void show() {
            System.out.println("卡拉是条狗");
        }
    }

    class Bird {
        String name = "杜鹃";

        public void eat() {
            System.out.println("鸟,吃虫");
        }

        public void sing() {
            System.out.println("我是一只小小鸟");
            //与外部内未重名的属性、方法调用
            Person.this.age = 2;
            eat();//this.eat();
        }

        public void display(String name) {
            //调用与外部内重名的属性、方法
            System.out.println(name);//形参
            System.out.println(this.name);//内部类的属性
            System.out.println(Person.this.name);//外部类的属性

            eat();//默认省略this.
            this.eat();
            Person.this.eat();
        }

        public Bird() {}
    }
}
  1. 在局部内部类的方法中,如果调用外部类中所声明的方法中的局部变量的话,要求此局部变量必须声明为final的。
public class InnerClassTest {
    public void method() {
        //局部变量
        int num = 10;//省略了final关键字。JDK8及之后的版本可以省略,JDK7及之前的版本必须显式的将局部变量声明为final

        class AA{
            public void show() {
                //num = 20;//报错,final修饰的变量不能被重新赋值
                System.out.println(num);
            }
        }
    }
}
  1. 开发中局部内部类的使用
public class InnerClassTest {
    public static void main(String[] args) {

    }

    //开发中很少见
    public void method() {
        //局部内部类
        class AA {}
    }

    //返回一个实现了Comparable接口的类的对象
    public Comparable getComparable() {
        //创建一个实现了Comparable接口的类:局部内部类
        /*方式一:
        class MyComparable implements Comparable {

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }

        return new MyComparable();
        */

        /*方式二:*/
        return new Comparable() {

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }
}

文章作者: YangChongZhi
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 YangChongZhi !
评论
 上一篇
Java中抽象类和接口的异同 Java中抽象类和接口的异同
   引言: java中抽象类和接口的比较。接口是和类同级的一种结构,抽象类本质上是类,但是不能直接实例化对象。 相同点 不能实例化 都可以被继承 都可以包含抽象方法 不同点 抽象类中有构造器,供子类显示或非显示的调用;而
2021-01-04
下一篇 
Java在JDK8中接口的新特性 Java在JDK8中接口的新特性
   引言: JDK8中,在接口中除了定义全局静态常量和公共抽象方法之外,还可以定义静态方法和默认方法 JDK8以后,在接口中除了能定义全局常量和抽象方法之外,还可以定义静态方法和默认方法 静态方法 使用static关键字修饰。可以通过
2021-01-03
  目录