最近在读《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