示例代码demo:
import java.math.BigDecimal;
/**
* 使用静态内部类提高封装性,车类
*/
public class Car {
//车名
private String name;
//售价
private BigDecimal price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
/**
* 厂商类
*/
static class Vendor {
//厂商名称
private String name;
//厂商归属城市
private String country;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
}
如上代码示例,有一个汽车类Car类,Car类中维护了一个静态内部类Vendor类,用来维护汽车对应的厂商信息。
接下来逆推下思路
如果不使用厂商类来维护厂商信息,就把厂商的信息也维护在汽车类中,因为反正也是一对一的关系,不过此时类的职责就不单一了,那么设计表的话字段是合并在一起还是分开呢?后面需求要是再增加字段,如果增加的都是厂商相关的字段,那么这个类是哪个信息为主,厂商为主?因为字段信息更全?还是依旧汽车为主,因为设计就是汽车信息为主,厂商只是辅助信息。这样汽车信息和厂商信息之间的关系就有点混淆了。所以定义静态内部类来提高封装性,汽车类是汽车信息,厂商类是厂商信息,各自抽象封装出来,所以建议根据类的职责来划分类。
那么为什么不单独维护一个厂商类,使用静态内部类好在哪?
单独维护一个厂商类不是不行,很多开发都会选择这种方式去维护类之间的关系,但是使用静态内部类,可以加强代码可读性和可理解性,这里可以把可以把静态内部类理解成是外部类的字子行为或子属性,那么通过静态内部类的定义就可以清晰的知道厂商类和汽车类是有关联关系的。
那么为什么不使用内部类,而选择使用静态内部类呢?
- 静态内部类不持有外部类的引用
这句话什么意思,因为内部类会持有一个外部类的引用,所以内部类可以访问外部类的属性、方法,即使是private修饰符修饰的也是可以访问的,如下:
可以正常访问不报错。而静态内部类就会有限制了,报错截图如下:
但是静态内部类可以访问外部类的静态属性和方法,如下:
所以真正属于对象的属性和方法,静态内部类是调用不了的,这样封装起来也更安全,只对静态内部类暴露想要暴露的方法。
- 静态内部类不依赖外部类
普通内部类与外部类之间是相互依赖的关系,内部类的实例是不能脱离外部类实例存在的。
先把Vendor类改为普通内部类,实例化普通内部类时,外部类和普通内部类要一起实例化,否则会报错,如下:
再把Vendor类改回静态内部类,而静态内部类是可以独立存在的,如下:
可以发现,Vendor类可以实例化成功。
普通内部类中不能声明static修饰符修饰的变量和方法,如下:
不过从截图结果可以看出,static修饰符修饰的常量还是可以被允许出现在普通内部类中的。
而静态内部类中则可以声明static修饰符修饰的变量和方法,如下:
总结
根据以上的测试结果,可以知道使用静态内部类,可以提高封装性和代码的可读性,同时相比起普通内部类,静态内部类就像个外部类一样,不会有那么多的使用限制。