内部类

内部类定义: 把一个类A放在另一个类B的内部定义,则称类A为内部类,包含内部类的类B称为外部类。
内部类特点:

  1. 内部类成员可以直接访问外部类的私有数据,但外部类不能访问内部类的实现细节。
  2. 内部类可以被public、protected、priivate、static修饰。
  3. private修饰的内部类只能在外部类内使用;protected修饰的内部类可被与外部类处于同一包下的其他类及其子类访问;public修饰的内部类可以被任意访问;defult即省略修饰符的内部类只能让与外部类处于同一包下的类访问。
    内部类分类: 非静态内部类、静态内部类、局部内部类、匿名内部类
    非静态内部类:
public class Outer{
    private double weight;
    public Outer(double weight){
        this.weight = weight;
    }
    private class Inner{
        private String color;
        public Inner(String color) {
            this.color = color;
            //内部类引用外部类私有成员weight
            System.out.println("color:" + color + "--" + "weight" + weight + "。");
        }
        public String getColor() {
            return color;
        }
        public void setColor(String color) {
            this.color = color;
        }
    }
    public void test(){
        Inner in = new Inner("蓝色");
    }
    public static void main(String[] args) {
        Outer outer = new Outer(50);
        outer.test();
    }
}

如上面实例,Inner即为内部类,Outer为外部类。
编译上面代码,会在文件所在的路径生成两个.class文件,一个是Outer.class,一个是Inner.class文件;因为静态成员不能访问非静态成员,所以内部类Inner(非静态类)不能在public static void main(String[] args){}中实例化,所以在test()中实例化、调用。
静态内部类
即用static修饰的内部类即为静态内部类

public class StaticOuter {
        private double weight;
        public StaticOuter(double weight){
            this.weight = weight;
        }
    public double getWeight() {
        return weight;
    }
    public void setWeight(double weight) {
        this.weight = weight;
    }
    private static class Inner{
            private String color;
            public Inner(String color) {
                this.color = color;
                //这里不能在访问外部类的weight,因为静态成员不能访问非静态成员
                System.out.println("color:" + color);
            }
            public String getColor() {
                return color;
            }
            public void setColor(String color) {
                this.color = color;
            }

        }
//        public void test(){
//            Inner in = new Inner("蓝色");
//        }
        public static void main(String[] args) {
            StaticOuter outer = new StaticOuter(50);
            //这里可以直接实例化内部类Inner创建对象,因为main方法用static修饰
            Inner inner = new Inner("黑色");
            System.out.println("weight:"+outer.getWeight());
            //outer.test();
        }
}

如上面实例,Inner即为静态内部类,StaticOuter为外部类。
局部内部类
把内部类定义在方法里,此内部类即为局部内部类。局部内部类仅在方法里有效。因为局部内部类不能在外部类的方法以外使用,所以局部内部类不能使用访问控制符和static修饰

public class PartOuter {
    public static void main(String[] args) {
        class Inner{
            String a;
            int b;
        }
        Inner inner = new Inner();
        inner.a = "Java";
        inner.b = 666;
        System.out.println(inner.a+","+inner.b);
    }
}

如上实例,Inner即为局部内部类,定义在main方法里。
匿名内部类
特点: 匿名内部类必须实现一个接口或者继承一个父类;匿名内部类不能是抽象类;匿名内部类不能定义构造器;

abstract class Parent{
    private String name;
    public abstract String test();
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class UnName {
    public void func(Parent p){
        p.setName("小明");
        System.out.println(p.getName()+","+p.test());
    }
    public static void main(String[] args) {
        UnName unName = new UnName();
        //定义内部类,实现Parent父类
        unName.func(new Parent() {
            @Override
            public String test() {
                return "hello";
            }
        });
    }

}