java内部类学习笔记

java内部类定义:在一个类的内部定义另一个类

实现原理:当我们在一个类outter(这里称作外部类)中定义另外一个类inner(这里称作内部类)时,这个内部类实际上捕获了一个指向外部类成员的引用,换句话讲,内部类中的方法成员可以自由访问外部类中的属性成员,但是注意,只能访问其中的构造器方法,而不能访问其余方法。

下面将以具体的代码讲述其中的知识点,在每条语句的后面都会附上这么写的原因或者实现机制

第一部分:普通内部类

实例一:使用外部类名.内部类名的格式声明一个内部类

public class Demo1 {

    /**
     * 这里定义一个内部类,这个内部类可以访问包含他的外部类的所有的变量和方法
     * 但是外部类却不能访问内部类中被定义为private的成员
     */
    class Contents{  //这里定义第一个内部类
        private int i=11;
        public int value(){
            return i;
        }        
    }
    
    /**
     *
     * 如果你不特意指定内部类的成员的访问权限,那么他默认为public的,换句话讲,只要可以找到一个外部类的引用
         * 他就可以被同一个包中的所有成员访问
     */
    class Destination{   //这里定义第二个内部类
         private String label;        
         Destination(String whereTo){
             label=whereTo;
         }
        String readLabel(){
            return label;
        }
    }
    
    public void ship(String dest){
        /*Contents 是一个内部类,但是这里可以直接使用Contents进行声明,是因为内部类同这个
         * 方法是同级的,换句话讲,因为内部类在这个方法之前编译,所以当我们的虚拟机在编译这个方法之时,可以“知道”这个类是什么,从而
                 *成功编译。
        */
        Contents c=new Contents();
        Destination d=new Destination(dest);
        System.out.println(d.readLabel());
    }

            
               public static void main(String args[]){    
        /**
         * 当我们新建一个指向外部类的引用时,其中包含的成员(包括内部类)就已经被编译了
         */
        Demo1 demo1=new Demo1();
        demo1.ship("hello world");

                /**
                *这个方法是static的。所以编译器先编译它,但这时,编译器还没有编译内部类,所以需要手动地“告诉”编译器这是一个内部类,
                *故采用outterclassname.innerclassname的形式进行声明,等号右边要新建一个内部类,此时需要一个外部类的引用
                */
        Demo1.Contents t=demo1.new Contents();
    }
    
}

实例二:使用接口名声明一个内部类

//这里声明一个接口
public interface Selector {
	boolean end();
	Object current();
	void next();
}

//当我们的内部类继承自外部的一些接口时,在static方法中声明这些内部类时,可以直接使用使用"接口名"的形式
//而不需要使用“外部类名.内部类名”的形式

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;

		/**如果没有到达数组的末尾,就返回true,如果没有到达数组的末尾,就返回false
		 * @Override
		 */
		public boolean end() {
			// TODO Auto-generated method stub
			return i==items.length;
		}

		@Override
		public Object current() {
			// TODO Auto-generated method stub
			return items[i];
		}

		@Override
		public void next() {
			// TODO Auto-generated method stub
			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接口是什么了。
                 *换句话讲,可以直接用接口名进行声明,而不用
		 * outername.innername的形式
		 */
		Selector selector=sequence.selector();
		
	}

}

下面还有匿名内部类的用法,将在后来更新





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值