内部类

把一个类放在一个类内部定义,这个定义在其他类内部的类就被称为内部类。

1. 内部类作用如下:

  1)内部类提供了更好的封装,把内部类应藏在外部类之内,不允许同一个包内的其他类访问该类。假设该类在脱离了某个类之外没有任何意义,可以将该类定义在依赖的类里。

  2)内部类成员可以直接访问外部的私有数据,因为内部类被当成外部类的成员,同一个类的成员之间可以互相访问。

  3)匿名内部类适合用于创建那些仅需要一次使用的类。

2. 非静态内部类:

  先创建外部类对象,再通过外部类对象创建内部类。Java不允许在非静态内部类重定义静态成员,静态方法,也不能有静态初始化块。

public class OutClass {
    private String a;
    private static String name;
    public void f(){}
    public static void fn(){}
    class InClass{
        private String b;
        public InClass(){
            b=a;
            b=name;
            f();
            fn();
        }
    }
    public static void main(String[] args) {
        OutClass.InClass inClass = new OutClass().new InClass();
    }
}

3. 静态内部类:
  如果用static来修饰一个内部类,它就属于这个外部类本身,而不属于某个外部类实例。根据静态成员不能访问非静态成员原则,静态内部类也不能访问外部类的非静态成员。

public class OutClass {
    private int a;
    private static String name;
    public OutClass(){}
    public void  f() {}
    public static void fn(){}
    public static class InClass{
        private int b;
        private static String c;
        public InClass(){            
            //b=a; //不能访问外部类的非静态变量
            c=name;
            //f(); //不能使用外部类的非静态方法
            fn();
        }
    }
    public static void main(String[] args) {
        OutClass.InClass inClass =new InClass();
    }    
}

4.接口内部类:

  接口内部类默认使用public staic修饰符。

5. 局部内部类:

  如果把一个内部类放在方法里定义,这个类就是一个局部内部类。对于局部成员,使用static修饰毫无意义,所以局部内部类不能用static修饰

public class Test {
    public static void main(String[] args) {
        abstract class InnerBase{
           int a;
           public abstract void fn();
        }
        class Inner extends InnerBase{
            public  void fn(){}
        }
        InnerBase inner = new Inner();
    }

}

6.匿名内部类
  匿名类适合创建那种只需要一次使用的类。你明年内部类必须集成一个父类或实现一个接口。必须实现父类或接口的所有抽象方法。

  如果匿名内部类想要访问外部类的变量,则必须使用final修饰符来修饰外部类的局部变量。

public class Test {
    interface Product{
        public String getName();
    }
    public abstract class Pro{
        public abstract void printName();
    }
    public static void main(String[] args) {
        System.out.println(new Product(){
                {
                    System.out.println("实现接口的匿名内部类初始化!");
                }
                public String getName(){
                    return "computer";
                }
            }.getName());
        
        final String nameString = "Keyboard";
        new Test().new Pro(){
                {
                    System.out.println("继承类的匿名内部类初始化!");
                }
                public void printName(){
                    System.out.println(nameString);;
                }
            }.printName();      
    }
}

 7.闭包和回调:

闭包是一种能被调用的对象,它保存了创建它的作用域信息。非静态内部类不仅记录了外部类的详细信息,还保留了一个创建非静态内部类对象引用,还可直接调用外部类的private成员,因此可以把非静态内部类当成面向对象领域的闭包。

以下代码为实际应用:

public class test {
    public abstract class Teachable{
        abstract void work();
    }
    public class Programmer{    
        public void work(){
            System.out.println("coding");
        }
    }
    public class TeachableProgrammer extends Programmer{
        private void teach() {
            System.out.println("teaching");
            
        }
        private class Closure extends Teachable{

            @Override
            public void work() {
                teach();
            }            
        }
        
        public Teachable getCallBackReference(){
            return new Closure();
        }
    }
    public static void main(String[] args) {
        TeachableProgrammer tProgrammer = new test().new TeachableProgrammer();
        tProgrammer.work();
        tProgrammer.getCallBackReference().work();
        
    }
}

以上内容来自学习《疯狂JAVA讲义》

原文地址:https://www.cnblogs.com/wxlovewx/p/5231215.html