面试后学习 -- Java内部类

面试问到的一个Java内部类的问题,今天总结下。如果我理解有误,请指正,谢谢。

一个简单的内部类:

package innerclazz;

public class OuterClazz {

    class InnerClazz{//inner class
        
    }
}

Java为什么用内部类

  • 提供一种方法把只在一个地方用的类逻辑分组
  • 增强封装(可以理解一种类似“多重继承”)
  • 容易维护

为什么说内部类可以实现类似的多重继承,Java是不需要class多重继承的, 想要实现类似多重继承的效果可以用内部类,比如Class B 已经继承了Class C 就没有办法继承Class A, 但是把B设计成A的内部类,就可以访问A的内部变量和方法了,就像是也继承了A。

package innerclazz;

public class ClazzA {

    private int age = 0;
    public void printFromA(){
        System.out.println("The age in ClazzA is "+age);
    }
    //ClazzB 可以直接调用ClazzA的方法和访问它的变量,
    class ClazzB extends ClazzC{//inner class
        public void print() {
            age++;
            printFromA();
        }
    }
    public static void main(String[] args) {
        ClazzB clazzB = new ClazzA().new ClazzB();
        clazzB.print();
    }
}

class ClazzC{
    
}

执行结果:

The age in ClazzA is 1

几种内部类

① 静态内部类

静态内部类不可以访问它外部类的非静态变量和方法,如果想访问外部类的变量和方法只能通过外部类的实例。

package innerclazz;

public class OuterClazz {

    private int age = 0;
    private static int intAge = 10;
    public void printAge(){
        System.out.println("The age in ClazzA is "+age);
    }
    
    //ClazzB 可以直接调用ClazzA的方法和访问它的变量,
    static class ClazzB {//inner class
        public void print() {
            System.out.println("The int age in Out class is "+intAge);
            OuterClazz outerClazz = new OuterClazz();
            outerClazz.age++;
            outerClazz.printAge();
        }
    }
    public static void main(String[] args) {
        ClazzB clazzB =  new OuterClazz.  ClazzB();
        clazzB.print();
    }
}

执行结果:

The int age in Out class is 10
The age in ClazzA is 1

② 非静态内部类

内部类可以直接访问外部类的方法和变量(包括静态的)。

package innerclazz;

public class OuterClazz {

    private int age = 0;
    private static int intAge = 10;
    public void printAge(){
        System.out.println("The age in ClazzA is "+age);
    }
    
    //ClazzB 可以直接调用ClazzA的方法和访问它的变量,
     class ClazzB {//inner class
        public void print() {
            System.out.println("The int age in Out class is "+intAge);
            age++;
            printAge();
        }
    }
    public static void main(String[] args) {
        ClazzB clazzB =  new OuterClazz(). new  ClazzB();
        clazzB.print();
    }
}

执行结果和静态内部类相同。

③ 本地内部类

本地内部类声明在一个块中,函数本地类就是一个函数中声明一个类,作用域只在函数内,外部没办法创建实例

package innerclazz;

public class LocalClazz {

    public static void testLocalClazz() {
        int age =10;
        class InnerClazz {
            public void pringAge() {
                //age++; //Error: Local variable age defined in an enclosing scope must be final or effectively final
                System.out.println("this age is "+age);
            }
        }
        InnerClazz innerClazz = new InnerClazz();
        innerClazz.pringAge();
    }

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

④ 匿名类

没有名字的内部类就是匿名内部类,在声明的时候实例化,用来重写一个类的方法,或者实现一个接口

package innerclazz;

public class AnonymousInnerClazz {
    private Animal animal = new Animal() {
        
        @Override
        public void eat() {
            System.out.println("eat, eat, eat!");
            
        }
    };
    public static void main(String[] args) {
        new AnonymousInnerClazz().animal.eat();
    }
    

}
interface Animal{
    public void eat();
}

执行结果:

eat, eat, eat!

真的有点饿了,也累了,(~﹃~)~zZ

参考
inner classes
Java Inner classes
Nested Classes

你可能感兴趣的:(面试后学习 -- Java内部类)