posts - 37, comments - 8, trackbacks - 0, articles - 0

java基础:关于内部类

Posted on 2008-08-01 11:25 梦与桥 阅读(224) 评论(0)  编辑  收藏 所属分类: java基础

1、内部类的优点:
优点一:在需要的地方定义类,可以直接使用外部类里的变量,代码比较简洁。
优点二:可以实现多继承。
优点三:解决命名空间的一种途径。
优点四:实现callback。
优点五:控制类的可见问题。

2、描述:内部类(Inner class)也叫嵌套类(Nested class),允许一个类的定义被放到另外一个类的定义中,这样的一组类在逻辑上是一个整体。内部类和其外层类存在逻辑上的从属关系,内部类对其外层类的成员有完全的访问权限。

3、分类:静态内部类(Static Inner Class)、成员内部类(Member Inner Class)、局部内部类(Local Inner Class)、匿名内部类(Anonymous Inner Class)

    成员内部类实例:
        

class OuterClass
{
 private String str1="同名变量之外部类。";
 private String str2="外部类变量。";
 public static void method1()
 {
  //OuterClass.InnerClass ic=new OuterClass().new InnerClass();//方式一
  OuterClass oc=new OuterClass();//方式二
  OuterClass.InnerClass ic=oc.new InnerClass();
  System.out.println("外部类静态方法调用"+ic.str3);
 }
 public void method2()
 {
  InnerClass ic=new InnerClass();
  System.out.println("外部类非静态方法调用"+ic.str3);
 }
 public class InnerClass
 {
  private String str1="同名变量之内部类。";
  public String str3="内部类成员变量。";
  public void print()
  {
   String str1="同名变量之局部。";
   System.out.println("内部类调用外部类变量"+str2);
   System.out.println(str1);
   System.out.println(this.str1);
   System.out.println(OuterClass.this.str1);//若str1为静态,此处可省this,其实这不此处要讨论的问题
   
  }
 }
}
public class Test
{
 public static void main(String[] args)
 {
  OuterClass.method1();
  OuterClass oc=new OuterClass();
  oc.method2();
  OuterClass.InnerClass ic=new OuterClass().new InnerClass();
  System.out.println("天涯之类调用"+ic.str3);
  ic.print();

 }
}

运行结果:  

        注意:所有内部类名称不可与其外层类名称相同,内部类不可定义静态方法
                    内部类的完整名称:外部类.内部类
                    内部类.class文件名称:外部内$内部类.class
                    其外层类的非静态方法使用内部类,同使用普通类完全一样
                    在其外层类的非静态方法之外的任何地方定义生成内部类的一个对象,必用使用内部类的完整名称,语法格式:外部类对象.new内部类名称(参数)
                    成员内部类可以使用任意的访问修饰符:public、protected、default、private 
                    内部类中引用外部类成员,格式:外部类名.this.成员名称

    静态内部类实例:
class OuterClass
{
 private static String str1="外部类静态变量。";
 private String str2="外部类非静态变量。";
 public void method1()
 {
  System.out.println("内部类引用"+InnerClass.str3);
  InnerClass ic=new InnerClass();
  System.out.println("内部类引用"+ic.str4);
 }
 public static void method2()
 {
  System.out.println("内部类引用"+InnerClass.str3);
  InnerClass ic=new InnerClass();
  System.out.println("内部类引用"+ic.str4);
 }
 public static class InnerClass
 {
  private static String str3="内部类静态变量。";
  private String str4="内部类非静态变量。";

  public void print()
  {
   System.out.println("内部类引用其外部类静态方法:");
   OuterClass.method2();
   System.out.println("内部类引用其外部类静态方法:\n"+OuterClass.str1);
  }
 }
}
public class Test
{
 public static void main(String[] args)
 {
  OuterClass oc=new OuterClass();
  OuterClass.InnerClass ic=new OuterClass.InnerClass();
  ic.print();
  oc.method1();


 }
}

运行结果:
        注意:
                    内部类可以直接引用外部类中定义的静态成员,但不可以引用外部实例成员
                    static不妨碍创建静态/非静态的成员及方法
    局部内部类实例:
class OuterClass
{
 private String str1="外部类变量";
 public  void method()
 {
  final String str3="final类型的局部变量。";
   class InnerClass
    {
    public void print()
     {
      System.out.println(str1);
      System.out.println(str3);
     }
    }
  InnerClass ic=new InnerClass();
  ic.print();
 }
}
public class Test
{
 public static void main(String[] args)
 {
  OuterClass oc=new OuterClass();
  oc.method();
 }
}
运行结果:
        注意:
                    局部内部类在局部块中可见,超过作用域将不可见,只可用abstract 或final修饰符
                    可以访问其外部类的字段和局部变量(要被声明为final,不被访问的不用声明)
                    在静态代码块(如静态方法与静态初始化块)中定义时,将只能引用静态变量
    匿名内部类实例:
interface Interest
{
 void letter();
 void computer();
}
class Student
{
 public void school()
 {
  System.out.println("吉林农业大学发展学院");
 }
 public void specialty()
 {
  System.out.println("计算机科学与技术");
 }
 public void intersets(Interest interest )
 {
  interest.letter();
  interest.computer();
 }
 
}
public class Test
{
 public static void main(String[] args)
 {
  Student stu=new Student();
  stu.school();
  stu.specialty();
  stu.intersets(new Interest(){
   public void letter()
   {
    System.out.println("My first interest is letter.");
   }
   public void computer()
   {
    System.out.println("My second interest is computer");
   }
   });
 }
}
运行结果:
         注意:
                    不能用任何修饰符,无构造函数,匿名成员的初始化只能通过非静态初始化块进行
                    实例中的匿名类是作为方法形参类形的接口实现类,也可作为形参类型的派生类(这样就实现了类的多继承)
                    定义对象时不能带有参数

附一本教材上的匿名类实例:
class a
{
 void ShowA()
 {
  System.out.println("我是a类的方法.");
 }
}
class b
{
 a One=new a(){
  void ShowA()
  {
   System.out.println("我是匿名内部类(类A的子类)的方法.");
  }
 };
 void ShowB()
 {
  One.ShowA();
 }
}
public class Test
{
 public static void main(String args[])
 {
  b Two=new b();
  Two.ShowB();
 }

}

运行结果:打印出:我是匿名内部类(类A的子类)的方法.

4、接口中的嵌套类:当一个类的对象与接口有很强的逻辑关联时,可将此类定义为对应接口的嵌套类
例如:
interface Ia
{
 int var1=0;
 class NestedClass
 {
  public void display()
  {
   System.out.println(var1);
  }
 }
}
public class Test
{
 public static void main(String args[])
 {
  Ia.NestedClass inc=new Ia.NestedClass();
  inc.display();
 }
}
一个接口定义的嵌套类只能是public和static的,默认情况下也是,接口的实现类与接口的嵌套类无多大联系,前者在实现接口时无需关心后者,当然可能用到后者。

5、总结:
                内部类的嵌套可以多层,目的是使代码简洁,下面举一个外部类要返回一个对象的例子:
interface Ia
{
 void show1();
}
class OuterClass
{
 public Ia method()
 {
  class InnterClass implements Ia
  {
   public void show1()
   {
    System.out.println("Hello");
   }
  }
  return new InnterClass();
 }
 public void show2()
 {
  Ia iu=method();
  iu.show1();
 }
}

public class Test
{
 public static void main(String args[])
 {
  final String str="world!";
  OuterClass oc=new OuterClass();
  oc.show2();
 }
}

这是在一个方法中,也可以一个语句块中,比如说在if内。当想需要创建一个对象,而又用不上他的名字时,可以创建匿名类对象,他的语法:new interfacename(){......}; 或 new superclassname(){......}; 这在JAVA事件处理中大量使用,例如:
frame.addWindowListener(new WindowAdapter(){

  public void windowClosing(WindowEvent e){

  System.exit(0);

 }

});
如果这个匿名内部类继承了一个只含有带参数构造函数的父类,创建它的时候必须带上这些参数,并在实现的过程中使用super关键字调用相应的内容。


只有注册用户登录后才能发表评论。


网站导航: