在实现一个完成功能时,可能需要几个类协调辅助才能更优雅的完成,但对使用人员来说,一个完成对对应一个类,方便理解和使用,此时使用内部类仔合适不过,增加了聚合性,对外屏蔽了具体实现细节。那内部类和静态内部类(嵌套勒)区分又是出于什么样的考虑呢?
1 、实现方式和使用的区别
内部类实现和使用
public class City {
private String cityName;
private static String country = "中国";
private Location location;
public City(String cityName,String code){
this.cityName = cityName;
}
class Location{
private double latitude;
private double longitude;
public Location(double latitude, double longitude){
this.latitude = latitude;
this.longitude = longitude;
}
public void printOutClassFileds(){
//访问外部类的成员方法和成员方法
System.out.printf("cityName %s, country %s ",cityName,country);
}
}
public Location createLocation(){
return new Location(12d,34d);
}
public static void main(String[] args) {
City city = new City("Harbin","001002");
//Location创建方式: 使用外部对象
City.Location location1 = city.new Location(123d,124d);
location1.printOutClassFileds();
City.Location location2 = city.createLocation();
location2.printOutClassFileds();
}
}
静态内部类实现和使用
public class City {
private String cityName;
private static String country = "中国";
private Location location;
public City(String cityName,String code){
this.cityName = cityName;
}
static class Location{
private double latitude;
private double longitude;
public Location(double latitude, double longitude){
this.latitude = latitude;
this.longitude = longitude;
}
public void printOutClassFileds(){
//访问外部类的类变量
System.out.printf(" country %s ",country);//无法外部类的成员变量cityName
}
}
public Location createLocation(){
return new Location(12d,34d);
}
public static void main(String[] args) {
City city = new City("Harbin","001002");
//Location创建方式: new
City.Location location1 = new City.Location(123d,124d);
location1.printOutClassFileds();
City.Location location2 = city.createLocation();
location2.printOutClassFileds();
}
}
二者差异总结:
(1)普通内部类需要依赖外部对象创建,因为内部类中存在一个外部类对象指针this;嵌套类被static修饰,属于外部类属性,不用以来具体外部类对象。
(2)普通内部累可以访问外部类的所有属性;嵌套内部类只能访问外部类的类属性。
(3)普通内部类不能有类属性和类方法。
2、适用场景差异
从创建方式来看,虽然两种类型的内部类都是可以在外部使用过程中创建出来,但从创建方式容易度来看,普通内部类比嵌套内部类的隐蔽性更强,这也是内部类设计的一个其中一个初衷,所以大多情况下,使用普通类的范围更广。
3、 HashMap中Node设计为嵌套类分析
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
public final K getKey() { return key; }
public final V getValue() { return value; }
public final String toString() { return key + "=" + value; }
public final int hashCode() {
return Objects.hashCode(key) ^ Objects.hashCode(value);
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (o == this)
return true;
if (o instanceof Map.Entry) {
Map.Entry<?,?> e = (Map.Entry<?,?>)o;
if (Objects.equals(key, e.getKey()) &&
Objects.equals(value, e.getValue()))
return true;
}
return false;
}
}
单独分析看Node定义,似乎使用普通内部类也可以。原因有待进一步探讨{#todo}