Java中的嵌套类

 

最近在读《Effective Java第二版》,因为笔者之前学过一些设计模式,所以对书中的多数内容可能感受不大(但这丝毫不影响这是一本好书哈)。倒是今天读到第22条——优先考虑静态成员类感觉归纳的很好,特此发博。

嵌套类(nested class)是指定义在另一个类内部的类,它存在的意义就是为它的外部类提供服务。嵌套类有四种:

静态成员类(static member class)

非静态成员类(nonstatic member class)

匿名类(anonymous class)

局部类(local class)

 

其中,静态成员类和非静态成员类并称为成员类,是定义在类的内部,与类的域平级,因此叫做member class。与之对应的是局部类,局部类是指定义在类的方法的内部的类。

还有,上面的四种嵌套类的后三种并称为内部类(inner class)。上面是概念部分,接下来咱们来仔细理解其中的差别。

1. 静态成员类

静态成员类是指定义在类内部的静态类,你完全可以把它看成是一个普通类。只是因为它被定义在类的内部,所以可见性有所不同。

 

 

/**
 * Created by yizhenn on 16-12-13.
 */
public class Calculator {
    private int a;
    private int b;

    public Calculator(int a, int b) {
        this.a = a;
        this.b = b;
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }

    @Override
    public String toString() {
        return "Calculator{" +
                "a=" + a +
                ", b=" + b +
                '}';
    }

    public static class Operator{
        public int add(Calculator calculator){
            return calculator.a+calculator.b;
        }
        public int minus(Calculator calculator){
            return calculator.a-calculator.b;
        }
        public int multiply(Calculator calculator){
            return calculator.a*calculator.b;
        }
        public double divide(Calculator calculator){
            return calculator.a/calculator.b;
        }
    }
}
/**
 * Created by yizhenn on 16-12-13.
 */
public class Demo {
    public static void main(String[] args) {
        Calculator calculator=new Calculator(1,1);
        Calculator calculator1=new Calculator(1,2);
        Calculator.Operator operator=new Calculator.Operator();
        System.out.println(operator.add(calculator));
        System.out.println(operator.add(calculator1));
    }
}

在上面的需求中,将Operator定义为静态内部类是明智的,因为在客户端Demo中,Operator对象有一个就够了。而且,笔者更认为应该把Operator类中的方法都声明为静态方法。这样保证了Operator仅仅为Calculator服务,同时保证了性能消耗最小。为何这样说?来看上面这一需求的非静态内部类的实现。

 

 

2. 非静态成员类

非静态成员类是定义在类内部的普通类,你可以将它看成是一个类的成员对象,只不过这个成员对象的类型是被它自己定义的,而且这个自定义的类型还可以访问外部类中的域。同上的需求,用非静态成员类实现:

 

/**
 * Created by yizhenn on 16-12-13.
 */
public class Calculator {
    private int a;
    private int b;

    public Calculator(int a, int b) {
        this.a = a;
        this.b = b;
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }

    @Override
    public String toString() {
        return "Calculator{" +
                "a=" + a +
                ", b=" + b +
                '}';
    }

    public class Operator{
        public int add(){
            return a+b;
        }
        public int minus(){
            return a-b;
        }
        public int multiply(){
            return a*b;
        }
        public double divide(){
            return a/b;
        }
    }
}

 

/**
 * Created by yizhenn on 16-12-13.
 */
public class Demo {
    public static void main(String[] args) {
        Calculator calculator=new Calculator(1,1);
        Calculator.Operator operator=calculator.new Operator();
        System.out.println(operator.add());

        Calculator calculator1=new Calculator(2,2);
        Calculator.Operator operator1=calculator1.new Operator();
        System.out.println(operator1.add());

    }
}


在上面说过,非静态成员类就相当于类的成员对象,因此你会发现:每个Operator对象都必须关联一个Calculator对象。也正因为如此,在Operator类的内部,可以直接访问外部类的成员。

 

 

 

3. 匿名类

关于匿名类,是用的最广泛的内部类。是一种在使用的时候具体化接口的形式。比如:

 

/**
 * Created by yizhenn on 16-12-13.
 */
public class Demo {
    public static void main(String[] args) {
       new Thread(new Runnable() {
           @Override
           public void run() {
               System.out.println();
           }
       }).start();

    }
}


再如:

 

 

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Created by yizhenn on 16-12-13.
 */
public class Demo {
    public static void main(String[] args) {
       List studentList=new ArrayList();
        studentList.add(new Student(10));
        studentList.add(new Student(1));
        studentList.add(new Student(5));
        Collections.sort(studentList, new Comparator() {
            @Override
            public int compare(Student o1, Student o2) {
                if(o1.ageo2.age)
                    return 1;
                else return 0;
            }
        });
    }

    static class Student{
        private int age;

        public Student(int age) {
            this.age = age;
        }
    }
}

 

4. 局部类

 

局部类是指在类的方法的内部定义的类,它与成员类的区别在于:成员类在外部类的内部,但是在外部类的方法的外部;而局部类在外部类的内部,而且还在外部类的方法的内部。

/**
 * Created by yizhenn on 16-12-13.
 */
public class Demo {
    public static void main(String[] args) {
       class MyTask implements Runnable{
           @Override
           public void run() {
               System.out.println();
           }
       }
       new Thread(new MyTask()).start();
    }
}

 

 

 

 

到知乎阅读最新的技术博客:https://www.zhihu.com/people/hulianwangzhaopin/activities

笔者开设了一个知乎live,详细的介绍的JAVA从入门到精通该如何学,学什么?

提供给想深入学习和提高JAVA能力的同学,欢迎收听https://www.zhihu.com/lives/932192204248682496

提供给想学习云计算的同学,欢迎收听https://www.zhihu.com/lives/1046567982750281728

 

你可能感兴趣的:(Java)