java 匿名内部类与嵌套类01

本文详细介绍了Java中匿名内部类的使用方法,包括如何利用匿名内部类实现接口、继承类,以及如何在内部类中初始化域等内容。同时,还探讨了匿名内部类在单例模式中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<pre name="code" class="java">public interface Contents {
  int value();
}



public class Parcel7 {
  public Contents contents() {
    return new Contents() { 
      private int i = 11;
      public int value() { 
    	  return i; 
      }
    }; 
  }
  public static void main(String[] args) {
    Parcel7 p = new Parcel7();
    Contents c = p.contents();
  }
}

cotents()方法将返回值的生成和类的定义结合在一起,看起来是在创建一个Contents对象,但与此同时插入了一个类的定义.

此语法的含义是:创建一个"继承"或是实现Contents接口的类的对象,通过new关键字向上转型为Contents的引用.

以上用法相当于:

public class Parcel7b {
  class MyContents implements Contents {
    private int i = 11;
    public int value() { return i; }
  }
  public Contents contents() { return new MyContents(); }
  public static void main(String[] args) {
    Parcel7b p = new Parcel7b();
    Contents c = p.contents();
  }
}
匿名内部类也可以继承一个class,for example:

public class Wrapping {
  private int i;
  public Wrapping(int x) { i = x; }
  public int value() { return i; }
}

ublic class Parcel8 {
  public Wrapping wrapping(int x) {
    // Base constructor call:
    return new Wrapping(x) { // Pass constructor argument.
      public int value() {
    	  System.out.println(super.value()*47);
        return super.value() * 47;
      }
    }; // Semicolon required
  }
  public static void main(String[] args) {
    Parcel8 p = new Parcel8();
    Wrapping w = p.wrapping(10);
  }
}
Wrapping只是一个具有具体实现的普通类,但是还是可以被当做公用接口来用.

在匿名内部类的内部还可以对域进行初始化的操作:

public class Parcel9 {
  // Argument must be final to use inside
  // anonymous inner class:
  public Destination destination(final String dest) {
    return new Destination() {
      private String label = dest;
      public String readLabel() { return label; }
    };
  }
  public static void main(String[] args) {
    Parcel9 p = new Parcel9();
    Destination d = p.destination("Tasmania");
  }

public interface Destination {
  String readLabel();
}

因为dest 在外围定义,在内部类中使用时,编译器会强制要求dest是final类型的.

匿名内部类在singleton中的运用:

interface Service {
  void method1();
  void method2();
}

interface ServiceFactory {
  Service getService();
}	

class Implementation1 implements Service {
  private Implementation1() {}
  public void method1() {System.out.println("Implementation1 method1");}
  public void method2() {System.out.println("Implementation1 method2");}
  public static ServiceFactory factory =
    new ServiceFactory() {
      public Service getService() {
        return new Implementation1();
      }
    };
}	

class Implementation2 implements Service {
  private Implementation2() {}
  public void method1() {System.out.println("Implementation2 method1");}
  public void method2() {System.out.println("Implementation2 method2");}
  public static ServiceFactory factory =
    new ServiceFactory() {
      public Service getService() {
        return new Implementation2();
      }
    };
}	

public class Factories {
  public static void serviceConsumer(ServiceFactory fact) {
    Service s = fact.getService();
    s.method1();
    s.method2();
  }
  public static void main(String[] args) {
    serviceConsumer(Implementation1.factory);
    // Implementations are completely interchangeable:
    serviceConsumer(Implementation2.factory);
  }
}
输出:

Implementation1 method1
Implementation1 method2
Implementation2 method1
Implementation2 method2


service对象在factory被方法调用的时候才会被创建.

内部类可以无限嵌套,只要你想这么干:

class MNA {
  private void f() {}
  class A {
    private void g() {
    	System.out.println("tom");
    }
    public class B {
      void h() {
        g();
        f();
        System.out.println("jerry");
      }
    }
  }
}	

public class MultiNestingAccess {
  public static void main(String[] args) {
	  MNA mna = new MNA();
	  MNA.A mnaa = mna.new A();
	  MNA.A.B mnaab = mnaa.new B();
	  mnaab.h();
  }
}
你会发现,对于内部类A,来说,即使基类MNA中f方法是private的,A依然可以对他进行访问.

你可以使用.new来创建内部类对象,前提是该内部类的外围类对象已经被创建.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值