Think in java: 什么是java内部类(1)

内部类是什么

  • 类中定义的类(隐藏名字)

    • 仅对包含该内部类的’外部类’可见
    • 静态方法必须通过外部类.内部类的方式来调用 (是因为没有this指针?)
    • 外部类能够访问内部类的一切对象,包括private
  • 链接到外部类

    • 内部类能访问所有制造它的外围对象的成员
    • 引出设计模式之一:迭代器模式,将某个数组以类的形式包装起来,并设计诸如add(). next(), end()等方法的形式对数组进行修改与访问的操作:
    interface Selector{
    	boolean end();
    	Object current();
    	void next();
    }
    public class Sequence{
    	private Object[] items;
    	private int next = 0;
    	public Sequence(int size){items = new Object[size];}
    	public void add(Object x){
    		if(next < items.length) items[next++] = x;
    	}
    
    	private class SequenceSelector implements Selector{
    		private int i = 0;
    		public boolean end(){ return i == items.length;}
    		public Object current(){return items[i];}
    		public void next(){if(i<items.length) i++;}
    	}
    	public Selector selector(){
    		return new SequenceSelector();
    	}
    	public static void main(String[] args){
    		Sequence sequence = new Sequence(10);
    		for(int i = 0;i < 10;i++)
    			sequence.add(Integer.toString(i));
    		Selector selector = sequence.selector();
    		while(!selector.end()){
    			System.out.print(selector.current+" ");
    			selector.next();
    		}
    	}
    }
    
    • 在这段代码中,selector接口,而sequenceSelector则是一个实现,它属于Sequence的内部类,在Sequencemain方法中,首先创建了一个Sequence对象,然后再创建了一个Selector对象,利用Selector接口所提供的方法来遍历数组,因此,这个内部类相当于一个迭代器。
    • 为什么内部类自动拥有外部类的访问权限:当某个外部类的对象创建了一个内部类对象时,编译器会帮助内部类对象捕获一个指向外围类对象的引用。再访问外部类成员的时候,利用的就是这个引用。着也同时意味着,内部类是无法访问静态对象的。此外,内部类被规定一掉要能访问外部类对象,因此内部类是不允许被定义为static的。当然,在类中使用static关键字来定义一个类也是可以的,这种类被称为嵌套类(内部类也被称为非静态嵌套类)
  • 在内部类中返回外部类引用

    • return outerclass.this
  • 在外部类中创建内部类引用

    • outerclass.innerclass obj = outerclass.new innerclass()
    • 换句话说内部类只能通过外部类调用.new方法创建,并且内部类对象不可能先于外部类对象的创建。
  • 内部类与向上转型

    • 书中令人费解的原话: 内部类向上转型为基类的时候,它是某个接口的实现,而内部类可以实现完全不可见与不可用(不可用是什么鬼?),它只是指向基类或者接口的引用,从而隐藏实现细节。
    • 举例解释:
    • 给定两个客户端程序员可见的接口,我们在调用引用的时候,在利用内部类进行实现的情况下,我们可能连实现这个接口的类的名字都不知道就可以创建引用。这样一来,这个实现类就不可能被继承与组合,从而无法扩展接口。
    public interface Destination{ String readLabel();}
    public interface Contents{int value();}
    class Parcel4{
    	private class PContents implements Contents{
    		private int i = 11;
    		pulbic int value(){return i;}
    	}
    	protected class PDestination implements Destination{
    		private String lable;
    		private PDestination(String whereTo){
    			label = whereTo;
    		}
    		public String readLabel(){return label;}
    	}// 内部类,接口Destination的实现
    	public Destination destination(String s){return new PDestination(s);}
    	public Contents contents(){return new PContents();}
    }
    public class TestParcel{
    	public static void main(String[] args){
    		Parcel4 p = new Parcel4();
    		Contents c = p.contents();
    		Destination d = p.destinations("123");
    	}
    }
    

参考资料

  • 《JAVA编程思想》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值