相关阅读:java
JAVA基础(二)内存优化-使用Java引用作缓存
JAVA基础(三)ClassLoader实现热加载
JAVA基础(四)枚举(enum)和常量定义,工厂类使用对比
JAVA基础(五)函数式接口-复用,解耦之利刃
JAVA编程思想(一)经过依赖注入增长扩展性
JAVA编程思想(二)如何面向接口编程
JAVA编程思想(三)去掉别扭的if,自注册策略模式优雅知足开闭原则
JAVA编程思想(四)Builder模式经典范式以及和工厂模式如何选?
HikariPool源码(二)设计思想借鉴
人在职场(一)IT大厂生存法则编程
首先Java类的做用是功能内聚,将相近特性的功能内聚到一个类中,例如StringUtil类内聚String相关的功能,DateUtil类内聚Date相关的功能,那么内部类天然也有功能内聚的做用,与通常类不一样的是,定义一个内部类一般意味者既要功能内聚,又要对外屏蔽可见性,即不但愿外部可见,减小对外暴露的接口,这样从源码结构上来看,须要了解的类信息更少,更简洁。缓存
既然内部类是为了对外屏蔽可见性,那么内部类的功能不能直接用内部方法实现么?函数
内部类能够经过内部方法实现,但有的场景更适合用内部类来实现:
1.有一组相近的功能,能够内聚,归属到一个特性,若是都用方法实现,那么原来这个类的方法会不少。
2.须要继承或者实现某个接口,此时经过方法就没法作到。post
从static关键字的通常用法出发很容易理解二者的区别:
1.static方法不能访问非static成员,同理静态内部类也同样。
2.非static方法能访问非static成员,同理内部类也同样。
3.非静态成员,须要经过类实例去访问,同理访问内部类也同样。
4.静态成员,能够经过类而非类实例来访问,同理访问静态内部类也同样。
所以,只要记住static关键字在通常类中的用法则可。下面看一个例子:优化
public class OuterClass {
private String outerField; // 非静态成员
private static String staticOuterField; // 静态成员
public InnerClass innerClass = new InnerClass();
public StaticInterClass staticInterClass = new StaticInterClass();
public class InnerClass {
public void printFields() {
System.out.println(outerField); // 可访问非静态成员
System.out.println(staticOuterField); // 可访问静态成员
}
}
public static class StaticInterClass {
public void printFields() {
System.out.println(outerField); // 报错,不可访问非静态成员
System.out.println(staticOuterField); // 可访问静态成员
}
}
public static void main(String[] args) {
OuterClass outerClass = new OuterClass();
// 类的访问有区别
OuterClass.StaticInterClass staticInterClass = new OuterClass.StaticInterClass(); // 静态内部类能够直接经过类来访问
OuterClass.InnerClass in = new OuterClass.InnerClass(); // 报错,内部类不能经过类去访问
// 类实例的访问是同样的
outerClass.innerClass.printFields();
outerClass.staticInterClass.printFields();
}
}
复制代码
这个也能够结合static关键字的通常用法出发来考虑:
1.外部其余类须要如何访问内部类? 例如是经过外部类的实例访问,仍是经过外部类访问。若是经过类访问,那么就使用静态内部类,不然使用内部类。
2.是否须要访问类的非静态成员,若是须要就用内部类,不然用静态内部类。ui
在Java中不支持继承多个类,可是在一个类中能够定义多个内部类,不一样的内部类又能够继承不一样的类,这样就等于同一个类能够继承多个类。不过这样作跟使用组合也差很少了,都是在内部持有了一个新的类,而继承和组合的区别是继承能够继承一个抽象类,而组合不能。咱们来看一个例子:spa
public class FlyingDog extends Dog {
// Bird bird = new Bird(); 这么用是组合
InnerBird innerBird = new InnerBird(); // 这么用是继承
public void fly() {
// bird.fly(); 这么用是组合
innerBird.fly(); // 这么用是继承
}
// 实现了多重继承,不过就这个例子而言,使用多重继承跟使用组合没有啥区别。惟一区别是仅当父类是抽象类的时候只能使用继承。
private class InnerBird extends Bird {
}
public static void main(String[] args) {
FlyingDog flyingDog = new FlyingDog();
flyingDog.fly();
flyingDog.run();
}
}
class Bird {
public void fly() {
System.out.println("I can fly");
}
}
class Dog {
public void run() {
System.out.println("I can run");
}
}
复制代码
end.设计