Java SE 是什么,包括哪些内容(二十)?
本文内容参考自Java8标准
再次感谢Java编程思想对本文的启发!
在这篇博文的开头,需要说明的情况有以下两点:
1、之前说的类的向上转型(不是内部类的向上转型)主要的应用是为了实现多态,即把子类的对象实例赋值给父类的引用,而内部类的向上转型主要应用不再是这个,而是隐藏具体的实现(内部类其中一个非常重要的应用就是:可以将内部类向上转型为其父类,尤其是转型为一个接口,但是这种转型不是为了实现多态,而是隐藏实现。)。
2、private类实际上的意义不是很大,因为一个类即代表一种数据类型,创建出来就是为了给客户端程序员使用的(实际上你根本无法使用private类),那么private内部类是不一样的,它可以很好地隐藏具体的实现。
代码示例:
// 内部类的向上转型
//接口Destination
public interface Destination{
//方法readLabel()
String readLabel();
}
//接口Contents
public interface Contents{
//方法value(),返回类型的int
int value();
}
//现在Contents和Destination表示客户端程序员可用的接口。
//PS:接口的所有成员自动被设置为public的
//当取得了一个指向父类或接口的引用时,甚至可能无法找出它确切的类型。
//比如:
//下面的代码示例中很好地展示了内部类是如何隐藏具体实现的
//类Parcel4
class Parcel4{
//private内部类PContents实现了接口Contents
private class PContents implements Contents{
//int类型的类变量i,初始化值为11
private int i = 11;
//方法value()
public int value(){
//返回i的值
return i;
}
}
//protected内部类PDestination实现了接口Destination
protected class PDestination implements Destination{
//String类型的类变量label
private String label;
//构造方法,带一个String类型的形式参数whereTo.
private PDestination(String whereTo){
//为类变量label赋值
label = whereTo;
}
//方法readLabel()
public String readLabel(){
//返回类变量label的值
return label;
}
}
//方法destination(String s),带一个String类型的形式参数s
//返回类型为Destination
public Destination destination(String s){
//返回一个内部类PDestination的对象实例。
return new PDestination(s);
}
//方法contents(),返回类型为Contents
public Contents contents(){
//返回一个内部类PContents的对象实例。
return new PContents();
}
//测试类TestParcel
public class TestParcel{
//程序执行入口main方法
public static void main(String[] args){
//创建类Parcel4的对象实例
Parcel4 p = new Parcel();
//通过p的contents()方法返回一个对象实例,
//赋值给Contents类型的引用c,实际上在这里,你不知道返回
//的具体的类型是什么,可能是Contents类型,也可能是接口Contents
//的某个实现类。
Contents c = p.contents();
//同上。
Destination d = p.destination("Tasmania");
}
}
}
//从根本上来说,private和protected内部类只能在当前的类内部使用。
//而对外可以通过一个方法,从而隐藏了具体的实现。
类Parcel4中增加了一些东西:内部类PContents是private,所以,除了在类Parcel4内部,其它类根本无法访问它。PDestination是protected,所以只有类Parcel4及其子类还有与类Parcel4同一个包中的类(protected也有包访问权)能访问PDestination,其它类都不能访问PDestination。
以上内容意味着,如果客户端程序员想了解或者访问它们,是要受到限制的。
同样的,你也无法通过向下转型(强制转型)将父类转型成private内部类(如果是protected,除非是继承自它的子类),因为你根本就无法访问它们的名字。
于是,private内部类给类的设计者提供了一种途径:通过这种方式可以完全阻止任何依赖于类型的编码(这里指的是依赖于特定的类型),并且可以完全隐藏细节。
同时,带来的一个问题是:从客户端程序员的角度来看,由于不能访问任何新增加的,原本不属于父接口的方法,所以拓展接口是没有价值的(因为子类中拓展的方法父类型的引用是不能访问的,除非将它强制转换成子类,但是父类引用无法强制转换成private子类,所以就没法访问),这给Java编译器提供了生成更高效代码的机会。
**总结:**从实际的开发角度来看,类的向上转型最大的意义在于多态,内部类的向上转型虽然本质上也是多态,但是它的更大的实际意义是隐藏具体的实现。
当你需要隐藏具体的实现的时候,首先考虑的是private修饰一个方法,如果有必要的话,再考虑private内部类。
PS:时间有限,有关Java SE的内容会持续更新!今天就先写这么多,如果有疑问或者有兴趣,可以加QQ:2649160693,并注明优快云,我会就博文中有疑义的问题做出解答。同时希望博文中不正确的地方各位加以指正。