内部类

⒈成员内部类⒉静态内部类⒊局部内部类⒋匿名内部类

将一个类的定义放在另一个类的定义内部,这就是内部类

public class Parcel {
    class Contents {
      private int i = 11;
      public int value() { return i; }
    }
    class Destination {
      private String label;
      Destination(String whereTo) {
        label = whereTo;
     }
     String readLabel() { return label; }
   }
   public Destination to(String s) {
     return new Destination(s);
   }
   public Contents contents() {
     return new Contents();
   }
   public void ship(String dest) {
     Contents c = contents();
     Destination d = to(dest);
     System.out.println(d.readLabel());
   }
   public static void main(String[] args) {
     Parcel p = new Parcel();
     p.ship("Tasmania");
     Parcel q = new Parcel();
     // Defining references to inner classes:
     Parcel.Contents c = q.contents();
     Parcel.Destination d = q.to("Borneo");
   }
 }

这里在类Parcel中创建了两个内部类Contents和Destination。同时每个内部类对应的创建了一个外部类方法,该方法用来返回一个指向内部类对象的引用。这种方式很常用!如果不提供指向内部类对象引用的函数,需要借助“.new”来创建内部类对象(后面会有用法)。如果想从外部类的非静态方法之外的任意位置创建某个内部类对象,那么必须像上述main()方法那样,具体指明这个对象的类型:OutClassName.InnerClassName(eg:Parcel.Contents),为什么要这么做呢?

注意:非静态内部类对象有着指向外部类对象的引用。

这可以至少解释两个问题:

1、内部类拥有外部类的所有元素的访问权(因为当生成内部类时内部类自动产生了指向外部类对象的引用,该引用可以访问外部类的所有成员)

2、创建内部类对象时,需要指明对象类型,即:

OutClassName out = new OutClassName();

OutClassName.InnerClassName=out.new InnerClassName(); 

 

使用 .this 和 .new

如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟原点和this。如果需要生成内部类对象,可以使用外部类对象后面紧跟原点和this。

外部类引用:

public class DotThis {
  void f() { System.out.println("DotThis.f()"); }
  public class Inner {
    public DotThis outer() {
      return DotThis.this;
      // A plain "this" would be Inner's "this"
    }
  }
  public Inner inner() { return new Inner(); }
  public static void main(String[] args) {
    DotThis dt = new DotThis();
    DotThis.Inner dti = dt.inner();
    dti.outer().f();
  }
}

 

注意:上面代码DotThis.this返回外部类对象引用,如果直接使用this,则是内部类Inner对象引用,不能通过编译。

创建内部类对象:

 

内部类语法

一、成员内部类(非静态):

1、可以访问外部类所有元素

public class DotNew {
  public class Inner {}
  public static void main(String[] args) {
    DotNew dn = new DotNew();
    DotNew.Inner dni = dn.new Inner();
  }
}

2、创建对象两种方式:(1)在外部类中声明方法返回内部类对象的引用(2)通过内部类对象后跟原点和new的方式(eg:DotNew dn = new DotNew(); DotNew.Inner dni = dn.new Inner();)

3、成员内部类中不能包含静态数据(成员变量和方法)

二、静态内部类:

1、不能访问外部类的非静态元素和方法。(因为静态内部类没有指向外部类对象的引用,只能直接通过类名来调用)

2、创建方式比较简单

Outer.Inner inner = new Outer.Inner();
inner.func();

3、可以包含静态数据

三、局部内部类

局部内部类就是可以定义在方法体内,比较少用

四、匿名内部类

 

interface content{
        int func();
    }
System.out.println(new content(){
            @Override
            public int func() {
                return 1;
            }
        }.func());

内部类优势:

1、可以访问外部类所有元素

2、隐藏性好,只有本类可操作

3、可以解决C++里面的多继承问题。怎么解决?

我们知道,Java不支持多继承(即一个类同时继承两个或多个类),只支持多重继承(即A继承B,B继承C,那么A间接继承了C),利用Java的内部类机制可以做到多重继承的效果。可以声明多个内部类分别继承相应的类,然后对于外部类来说,就同时拥有了相应内部类的功能。

 

参考:java编程思想

 

内部类操作外部类数据只能是final类型,因为外部类方法执行结束后,内部类的方法有可能还没执行完。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值