java炒冷饭系列10 内部类 使用.this与.new和向上转型
来源:互联网 发布:tap建站 编辑:程序博客网 时间:2024/06/05 18:57
使用.this与.new
如果你需要生成对外部类对象的引用,可以使用外部类的名字后紧跟加点和this(OutClass.this)。这样产生的引用自动地具有正确的类型,这一点在编译期就被知晓并受到检查,因此没有任何运行时开销。下面的示例展示了如何使用.this
public class DotThis { void f(){ System.out.println("DotThis.f()"); } public class Inner{ public DotThis outer(){ return DotThis.this; } } public Inner inner(){ return new Inner(); } public static void main(String[] args) { DotThis dt = new DotThis(); DotThis.Inner dti = dt.inner(); dti.outer(); }}
我在这里在补充一点,OuterClass.this 还可以用来引用外部类同名的属性和方法
public class Outer { private String name = "jianglei"; public void method(){ System.out.println("Outer.method()"); } public class Inner{ private String name = "Deng yi"; public void method(){ System.out.println("Inner.method()"); } public void test(){ System.out.println(name); System.out.println(Outer.this.name); method(); Outer.this.method(); } } public Inner getInner(){ return new Inner(); } public static void main(String[] args) { Outer.Inner inner = new Outer().getInner(); inner.test(); }}//输出Deng yijiangleiInner.method()Outer.method()
有时你可能想告知某些其他对象,去创建其某个内部类的对象。要实现此目的,你必须在new表达式中提供对其他外部类对象的引用,这是需要使用.new语法,就像下面这样:
public class DotNew { public class Inner{} public static void main(String[] args) { DotNew dn = new DotNew(); DotNew.Inner dni = dn.new Inner(); }}
要想直接创建内部类的对象,你不能按照你想象的方式,去引用外部类的名字DotNew,而是必须使用外部类的对象来创建该内部类对象,就像在上面的程序中所看到的那样。这也解决了内部类名字作用域的问题,因此你不必声明(实际上你不能声明)db.new DotNew.Inner()
在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗地连接到创建它的外部类对象上。但是,如果你创建的是嵌套类(静态内部类),那么它就不需要对外部类对象的引用。
下面你可以看到将.new应用于Parcel的示例:
public class Parcel3 { class Contents{ private int i = 11; public int value(){ return i; } } class Destination{ private String label; Destination(String whereTo){ label = whereTo; } String readLabel(){ return label; } } public static void main(String[] args) { Parcel3 p = new Parcel3(); Parcel3.Contents contents = p.new Contents(); Parcel3.Destination d = p.new Destination("Tasmania"); }}
内部类与向上转型
当将内部类向上转型为其基类,尤其是转型为一个接口的时候,内部类就有了用武之地。(从实现了某个接口的对象,得到对此接口的引用,与向上转型为这个对象的基类,实质上效果是一样的。)这是因为此内部类--某个接口的实现--能够完全不可见,并且不可用。所得到的只是指向基类或接口的引用,所以能够很方便地隐藏实现细节。
我们可以创建前一个示例的接口:
public interface Contents { int value();}
public interface Destination { String readLabel();}
现在Contents和Destination表示客户端程序员可用的接口。(记住,接口的所有成员自动被设置为public的。)
当取得了一个指向基类或接口的引用时,甚至可能无法找出它确切的类型,看下面的例子:
public class Parcel4 { private class PContents implements Contents{ @Override public int value() { return 0; } } protected class PDestination implements Destination{ private String label; private PDestination(String whereTo) { label = whereTo; } @Override public String readLabel() { return label; } } public Destination destination(String s) { return new PDestination(s); } public Contents contents() { return new PContents(); }}class TestParcel{ public static void main(String[] args) { Parcel4 p = new Parcel4(); Contents c = p.contents(); Destination d = p.destination("Tasmania"); //! Parcel4.PContents pc = p.new PContents(); }}
Parcel4中增加了一些新的东西:内部类PContents是private,所以除了Parcel4,没有人能访问它。PDestination是protected,所以只有Parcel4及其子类,还有与Parcel4同一个包中的类(因为protected也给予了包访问权)能访问PDestination,其他类都不能访问PDestination。这意味着,如果客户端程序员想了解或访问这些成员,那是要受到限制的。实际上,甚至不能向下转型成private内部类(或protected内部类,除非是继承它的子类),因为不能访问其名字,就像在TestParcel类中看到的那样。于是,private内部类给类的设计者提供了一种途径,通过这种方式可以完全阻止任何依赖于类型的编码,并且完全隐藏了实现的细节。此外,从客户端程序员的角度来看,由于不能访问任何新增加的,原本不属于公共接口的方法,所以扩展接口是没有价值的。这也给Java编译器提供了生成更高效代码的机会
参考文献
《Java编程思想》10.3使用this与new
《Java编程思想》10.4内部类与向上转型
- java炒冷饭系列10 内部类 使用.this与.new和向上转型
- java炒冷饭系列11 方法和作用域内的内部类 与 匿名内部类
- 内部类与向上转型
- 内部类与向上转型
- 内部类与向上转型
- 内部类与向上转型
- 内部类与向上转型
- java炒冷饭系列14 内部类标识符
- 从头认识java-8.4 内部类与向上转型
- [Java基础]内部类与向上转型来隐藏实现
- 10.4 内部类与向上转型
- java炒冷饭系列12 嵌套类(静态内部类)
- java炒冷饭系列13 内部类的继承
- java炒冷饭系列09 内部类的创建和链接到外部类
- 内部类 .this 和 .new
- java学习——内部类向上转型为接口
- 【java】内部类向上转型为接口例子
- java内部类的this和new语法
- C中如何调用C++函数
- ObjectInputStream的readObject()方法读取对象问题
- Hadoop实践(三)---MapReduce中的Counter
- Qt 获取本机的IP地址和Mac地址
- 前言
- java炒冷饭系列10 内部类 使用.this与.new和向上转型
- EffectiveC++学习笔记-条款10
- c++设计模式之单例模式
- Android studio导入开源库
- 创建角色的365个问题
- 史上最全的言情小说全面剖析
- 微信支付教程
- JavaScript全局函数及自定义函数
- 如何快速转载CSDN中的博客