你的位置:首页 > Java教程

[Java教程]JAVA内部类使用


一、什么是内部类?

  一个类的定义放在另一个类的内部,这个类就叫做内部类

二、内部类有那些特性?

  1、内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。
  2、内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否是private的 。
  3、内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态成员变量 。

三、内部类有哪几种?

  1.成员内部类

    如:
    
 1 package com.test01; 2  3 public class A { 4   // 内部类 B 继承 TestPojo 和实现 TestInterface 接口 5   class B extends TestPojo implements TestInterface{ 6     //内部类 B 自己的方法 7     public void run(){ 8       System.out.println("我正在跑!"); 9     }10     //重写的接口方法11     public void testf() {12       System.out.println("实现接口!");13     }14   } 15   // 方法里面调用内部类16   public void test(){17     B b = new B() ;18     b.testf() ;    // 掉用重写接口方法19     b.run() ;     // 调用自己的方法20     b.testpojo() ;   // 调用继承父类的方法21   }22   // main 方法测试23   public static void main(String[] args) {24     A a = new A() ;25     a.test() ;26   }27 }28 // 定义了一个接口 ,方法为testf() 29 interface TestInterface{30   public void testf() ;31 }32 // 定义了一个普通类 方法testpojo() 33 class TestPojo{34   public void testpojo(){35     System.out.println("我是简单的pojo类");36   }37 }38 // 实现 调用内部类里面的方法39 class Textone{40   public static void main(String[] args) {41     A.B b = new A().new B() ;  //调用类A里面的内部类B42     /** 等同于 下面代码43      *     A a = new A() ;44      *     A.B b = a.new B() ;45      * */46     b.testf() ;   // 掉用重写接口方法47     b.run() ;    // 调用自己的方法48     b.testpojo() ;  // 调用继承父类的方法49   }50 }

  2、方法内部类

 1 package com.test01; 2  3 public class PerTest { 4   public void test(){     // 定义一个方法 5     class Ne{        // 定义一个方法内部类 6       public void fle(){  // 定义方法内部类的方法  7         System.out.println("我正在飞翔!"); 8       } 9     } ;10     new Ne().fle() ;    //调用内部类的方法11   }12   public static void main(String[] args) {13     new PerTest().test() ;  //测试14   }15 }  

  注意: (1)、方法内部类只能在定义该内部类的方法内实例化,不可以在此方法外对其实例化。
      (2)、方法内部类对象不能使用该内部类所在方法的非final局部变量。        

      因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,
      局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!
      例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变
      量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。 (该理解来源于百度百科)

   3、匿名内部类

      1)、抽象匿名内部类

        

 1 package com.anonymous; 2  3 public class AbstractClass { 4   public void test(){        //方法为test 5     TestA a = new TestA(){    //实现抽象类 6       @Override 7       public void run() {    //实现抽象类的方法 8         System.out.println("我正在使用抽象匿名内部类"); 9       }10     } ;11     a.run() ;          //调用内部类的方法12   }13   public static void main(String[] args) {14     new AbstractClass().test() ;  //测试15   }16 }17 //定义一个抽象类 TestA 抽象方法为run()18 abstract class TestA{19   public abstract void run() ;20 }

    2)、接口匿名内部类

 1 package com.anonymous; 2  3 public class TestAnonymous { 4   MyInterface m = new MyInterface(){  //实现接口 5     public void eat() {        //重写MyInterface 接口方法 6       System.out.println("我正在吃饭!"); 7     } 8   } ; 9   public void ss(){  //方法ss10     m.eat() ;    //调用重写的方法11   }12   public static void main(String[] args) {13     new TestAnonymous().ss() ;  //测试14   }15 }16 //定义一个接口 方法为 eat17 interface MyInterface{18   public void eat() ;19 }

  注意:匿名内部 类 可以定义在方法内也可以定义在类的成员中,不管是那种匿名内部类都不能被外部类直接调用

四、内部类的作用?

  每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有
内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。
接口解决了部分问题,而内部类有效地实现了“多重继承”。