内部类和上溯造型
迄今为止,内部类看起来仍然没什么出格的处所。究竟,用它实现埋没显得有些大题小做。Java已经有一个很是优秀的埋没机制——只答允类成为“友好的”(只在一个包内可见),而不是把它建设成一个内部类。
然而,当我们筹备上溯造型到一个基本类(出格是到一个接口)的时候,内部类就开始发挥其要害浸染(从用于实现的工具生成一个接口句柄具有与上溯造型至一个基本类沟通的结果)。这是由于内部类随后可完全进入不行见或不行用状态——对任何人都将如此。所以我们可以很是利便地埋没实施细节。我们获得的全部回报就是一个基本类可能接口的句柄,并且甚至有大概不知道精确的范例。就象下面这样:
//: Parcel3.java // Returning a handle to an inner class package c07.parcel3; abstract class Contents { abstract public int value(); } interface Destination { String readLabel(); } public class Parcel3 { private class PContents extends Contents { private int i = 11; public int value() { return i; } } protected class PDestination implements Destination { private String label; private PDestination(String whereTo) { label = whereTo; } public String readLabel() { return label; } } public Destination dest(String s) { return new PDestination(s); } public Contents cont() { return new PContents(); } } class Test { public static void main(String[] args) { Parcel3 p = new Parcel3(); Contents c = p.cont(); Destination d = p.dest("Tanzania"); // Illegal -- can't access private class: //! Parcel3.PContents c = p.new PContents(); } } ///:~
此刻,Contents和Destination代表可由客户措施员利用的接口(记着接口会将本身的所有成员都酿成public属性)。为利便起见,它们置于单唯一个文件里,但原始的Contents和Destination在它们本身的文件中是彼此public的。
在Parcel3中,一些新对象已经插手:内部类PContents被设为private,所以除了Parcel3之外,其他任何对象都不能会见它。PDestination被设为protected,所以除了Parcel3,Parcel3包内的类(因为protected也为包赋予了会见权;也就是说,protected也是“友好的”),以及Parcel3的担任者之外,其他任何对象都不能会见PDestination。这意味着客户措施员对这些成员的认识与会见将会受到限制。事实上,我们甚至不能下溯造型到一个private内部类(可能一个protected内部类,除非本身自己即是一个担任者),因为我们不能会见名字,就象在classTest里看到的那样。所以,操作private内部类,类设计人员可完全克制其他人依赖范例编码,并可将详细的实施细节完全埋没起来。除此以外,从客户措施员的角度来看,一个接口的范畴没有意义的,因为他们不能会见不属于民众接口类的任何特别要领。这样一来,Java编译器也有时机生成效率更高的代码。
普通(非内部)类不行设为private或protected——只答允public可能“友好的”。
留意Contents不必成为一个抽象类。在这儿也可以利用一个普通类,但这种设计最典范的起点依然是一个“接口”。