java 内部类

一,什么是内部类?

    内部类是指在一个外部类的内部再定义一个类,类名不需要和文件名相同。而对于一般的,类定义代码不嵌套在其它类定义中的类,成为顶层(top-level)类,对于一个内部类,包含定义代码的类称为外部类(outer class)。

   内部类和外部类的比较:                                              

     1,内部类可以是静态static的,也可用public,default,protected和private修饰。(而外部顶级类即类名和文件名相同的只能使用public和default)。                                    

    2,内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现           outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。

二,内部类的作用?

      内部类存在的目的应该只是为它的外围类(outer class)提供服务,如果内部类可能用于其它的某个环境中,它就应该是顶层类。

      内部类的作用(这个是这篇博客总结的比较好http://andy136566.iteye.com/blog/1061951)

                              可以很好的实现隐藏(因为内部类可以有private与protected权限)。

                              内部类有外部类所以元素的访问权限。

                              可以实现伪多重继承。

                             

三,内部类的分类

      A.成员内部类

         成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法,即使是private的。同时外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。       要注意的是,成员内部类不能含有static的变量和方法。成员内部类需要先创建了外部类,才能创建它自己的

          在成员内部类要引用外部类对象时,使用outer.this来表示外部类对象

          而需要创建内部类对象,可以使用outer.inner  obj = outerobj.new inner();

    public class Outer { 
        public static void main(String[] args) { 
            Outer outer = new Outer(); 
            Outer.Inner inner = outer.new Inner(); 
            inner.print("Outer.new"); 
     
            inner = outer.getInner(); 
            inner.print("Outer.get"); 
        } 
     
        // 个人推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时 
        public Inner getInner() { 
            return new Inner(); 
        } 
     
        public class Inner { 
            public void print(String str) { 
                System.out.println(str); 
            } 
        } 
    } 

 B.局部内部类

   局部内部类,是指内部类定义在方法和作用域内(局部内部类用的比较少)

    public class Parcel4 { 
        public Destination destination(String s) { 
            class PDestination implements Destination { 
                private String label; 
     
                private PDestination(String whereTo) { 
                    label = whereTo; 
                } 
     
                public String readLabel() { 
                    return label; 
                } 
            } 
            return new PDestination(s); 
        } 
     
        public static void main(String[] args) { 
            Parcel4 p = new Parcel4(); 
            Destination d = p.destination("Tasmania"); 
        } 
    } 

 

    定义在作用域里:

    public class Parcel5 { 
        private void internalTracking(boolean b) { 
            if (b) { 
                class TrackingSlip { 
                    private String id; 
                    TrackingSlip(String s) { 
                        id = s; 
                    } 
                    String getSlip() { 
                        return id; 
                    } 
                } 
                TrackingSlip ts = new TrackingSlip("slip"); 
                String s = ts.getSlip(); 
            } 
        } 
     
        public void track() { 
            internalTracking(true); 
        } 
     
        public static void main(String[] args) { 
            Parcel5 p = new Parcel5(); 
            p.track(); 
        } 
    } 

     局部内部类也像别的类一样进行编译,但只是作用域不同而已,只在该方法或条件的作用域内才能使用,退出这些作用域后无法引用的

 

 C.静态内部类

   就是修饰为static的内部类。声明为static的内部类,不需要内部类对象和外部类对象之间的联系,就是说我们可以直接引用ou ter.inner,即不需要创建外部类,也不需要创建内部类。嵌套类和普通的内部类还有一个区别:普通内部类不能有static数据和static属性,也不能包含嵌套类,但嵌套类可以。而静态内部类,一般声明为public,方便调用,如果声明为private只能在外部类的内部使用。

 

public class Outer {
	    static int x =1;
	    static class Nest {
	        void print(){
 	            System.out.println("Nest "+x);
 	        }
 	    }
 	    public static void main(String[] args){
 	        Outer.Nest nest = new Outer.Nest();
	        nest.print();
 	    }
 	}

 因为静态嵌套类和其他静态方法一样只能访问其它静态的成员,而不能访问实例成员。因此静态嵌套类和外部类(封装类)之间的联系就很少了,他们之间可能也就 是命名空间上的一些关联。上面例子中你需要注意的就是静态嵌套类的声明方法 new Outer.Nest() 连续写了两个类名,以至于我们都怀疑前面的Outer是个包名了,好在包名一般都小写的,要不还真分不清……

 

 

D.匿名内部类   当我们把内部类的定义和声明写到一起时,就不用给这个类起个类名而是直接使用了,这种形式的内部类根本就没有类名,因此我们叫它匿名内部类。匿名类在事件处理中最常用。

 

public class Dog {
	    public interface Pet {
	        public void beFriendly();
                public void play();
 	    }
	  public static void main(String[] args){
 	        Pet dog = new Pet(){
 	            @Override
	            public void beFriendly() {
	                System.out.println("蹭蹭你^_^");
	            }
	            @Override
                public void play() {
	                System.out.println("把飞盘叼给你,逼你把飞盘丢出去,然后它再捡回来让你继续扔,连续500次^_^");
                    }
 	         };
	        dog.beFriendly();
 	        dog.play();
 	 
 	    }
 	}

 好吧我们再看一个例子,方法参数内的匿名内部类在事件处理中很常见

 

 

public class Dog { 
       static abstract class Ball {
               abstract String getName();
        }
        void play(Ball b){
	      System.out.println(b.getName());
 	}
	public static void main(String[] args){
 	     Dog dog = new Dog();
	      dog.play(new Ball(){
                 @Override
	            String getName() {
	                return "qiu qiu";
	     }});
	    }
	}

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值