文档章节

《Thinking in Java》Ten 内部类

DouDouLee
 DouDouLee
发布于 2016/04/10 17:35
字数 1624
阅读 73
收藏 6

内部类:将一个类的定义放在另一个类的定义内部。

创建内部类:

//内部类
class Outer{
 class Inner{
 {System.out.println("Inner class");}
 
 public void print(){
  System.out.println("Inner print()");
 }
}
 public Inner inMethod(){
  return new Inner();
 }
}
public class OuterInnerTest {
  
  public static void main(String[] args){
   Outer out = new Outer();
  
   //从外部类的非静态方法之外的任意位置创建某个内部类的对象,必须具体地
  
   //指明这个对象:OuterClassName.InnerClassName。
  
   Outer.Inner in = out.inMethod();
   in.print();
  }
}

内部类自动拥有对其外围类所有成员的访问权。当外围类的对象创建了一个内部类对象时,此内部类对象会捕获一个指向外围类对象的引用。这样,在内部类访问外围类的成员时,是所捕获的引用在操纵内部类成员。

package Ten;
interface Selector{
 boolean end();
 Object current();
 void next();
 Sequence sequ();
}
public class Sequence {
 private Object[] items;
 private int next = 0;
 
 public Sequence(int size){items = new Object[size];}
 public void add(Object x){
  if(next < items.length)
   items[next++] = x;
 }
 
 class StringHolder{
  String str;
  
  StringHolder(String str){
   this.str = str;
  }
  
  public String toStr(){return str;}
 
 }

 //内部类 其中的三个方法都用到了外围类的items,说明内部类自动拥有对其外围类的所有成员的访问权

 private class SequenceSelector implements Selector{
  private int i = 0;
  public boolean end() {
   // TODO Auto-generated method stub
   return i == items.length;
  }
  public Object current() {
   // TODO Auto-generated method stub
   return items[i];
  }
  public void next() {
   // TODO Auto-generated method stub
   if(i < items.length)
    i++;
  }
  public Sequence sequ() {
   // TODO Auto-generated method stub
  
   return Sequence.this;//生成外部类的引用

  }
  
 }

 //迭代器设计模式

 public Selector selector(){
  return new SequenceSelector();
 }
 
 public static void main(String[] args){

  //创建内部类对象,此内部类对象会捕获一个指向外围类的引用,当访问外围类成员时就是用这个引用来访问

  Sequence sequence = new Sequence(10);
  for(int i=0;i<10;i++)
   /*String java.lang.Integer.toString(int i)
Returns a String object representing the specified integer.
*/
   //sequence.add(Integer.toString(i));
   sequence.add(sequence.new StringHolder(Integer.toString(i)));

  Selector selector = sequence.selector();//内部类访问外围类的方法
 
  while(!selector.end()){
   System.out.print(selector.current() + " ");
   selector.next();
  }
 }
}/*0 1 2 3 4 5 6 7 8 9 */

.this、.new

可以使用外围类的名字加.this生成对外围类对象的引用。

package Ten;
class Outer3{
 class Inner3{
  Inner3(){
   System.out.println("Inner3");
  }
 }
 
 Outer3 outer(){

  return Outer3.this;//生成外部类的引用可以使用外部类的名字加.this

 }
}
public class OuterInner {
 public static void main(String[] args){
  Outer3 out3 = new Outer3();
  System.out.println(out3.outer());
  
  Outer3.Inner3 in3 = out3.new Inner3();//内部类对象的引用的创建方法
 
 }
}

在方法和作用域中的内部类

在作用域中的内部类:

 package Ten;
public class ZuoyongyuInner {
 private void internal(boolean b){
  if(b){
 
   //在作用域内定义内部类
   
   class Track{
    private String id;
    Track(String s){
     id = s;
    }
    String getTrack(){return id;}
  
   }//在作用域外内部类Track是不可用的
   
   Track tc = new Track("Track");
   String s = tc.getTrack();
  }
 }
 
 public void track(){internal(true);}
 
 public static void main(String[] args){
  ZuoyongyuInner zyi = new ZuoyongyuInner();
  zyi.track();
 }
}

exercise11

创建一个private内部类实现一个public接口,写一个方法返回此private内部类的引用,并将此引用向上转型为接口类型,尝试向下转型说明此内部类被完全隐藏了。

 package Ten;
class C{
 private class D implements B{
  public void f() {
   // TODO Auto-generated method stub
   System.out.println("Inner class D f()");
  }}
 
 public B Dm(){
  return new D();

 }//返回此private内部类的引用,并将此引用向上转型为接口类型

}
public class PrivateInner {
 public static void main(String[] args){
  C c = new C();
  c.Dm().f();
  //D d = new D(); Dcannot be resolved to a type

  //D被完全隐藏了

 }
}/*Inner class D f()*/

匿名内部类

即没有名字的内部类。匿名内部类的分号;不是标记此内部类的结束,标记的是表达式的结束,只不过此表达式包含了匿名内部类。
Exercise13.

package Ten;
public class Exise13 {
 public B b(){
  return new B(){
   public void f() {
    // TODO Auto-generated method stub
    System.out.println("Anonymous class Exise13.B()");
   }
   
  }; //
 }
 public static void main(String[] args){
  Exise13 e = new Exise13();
  e.b().f();
 }
}/*Anonymous class Exise13.B()*/

Exercise15.

创建一个拥有含有参数的构造器的类,接着创建第二个类包含一个返回第一个类的对象的引用的方法

package Ten;
class NonDeCnstr{
 String str;
 NonDeCnstr(String str){
  this.str = str;
  System.out.println(str);
 }
 public void f(){System.out.println("NonDeCnstr f()");}
}
class ReturnNon{
 public NonDeCnstr nondec(String str){
  
  //返回第一个类的引用
 
  return new NonDeCnstr(str){
   public void f(){System.out.println("ReturnNon f()");}
  };
 }
}
public class Excise15{
 public static void main(String[] args){
  ReturnNon r = new ReturnNon();
  r.nondec("ABC").f();
 }
}/*
ABC
ReturnNon f()*/

 

package Ten;
public class ReturnAnonymous {

 //contents()是返回值为接口Contents类型的方法

 public Contents contents(){
  return new Contents(){
   private int i = 11;
   public int value(){
    return i;
   }
  
  };匿名内部类的;不是标记此内部类的结束,标记的是表达式的结束,只不过此表达式包含了匿名内部类。

 }
 public static void main(String[] args){
  ReturnAnonymous re = new ReturnAnonymous();
  Contents c = re.contents();
 }
}

用匿名内部类实现工厂方法

package Ten;

//用匿名内部类实现工厂方法丢硬币

interface Toss{
 boolean b();
}
interface TossFactory{
 Toss getToss();
}
class Coin implements Toss{
 int EVENT = 2;
 private  int events = 1;
 boolean b1;
 public boolean b() {
  // TODO Auto-generated method stub
  System.out.println("Coin event :"+ events);
  return (events++ != EVENT);
 }

 //匿名内部类 

 public static TossFactory factoy = new TossFactory(){
  public Toss getToss() {
   // TODO Auto-generated method stub
   return new Coin();
  }
 };
}
public class FactoryCoin {
 public static void play(){
  Coin c = new Coin();
  while(c.b())
   ;
 }
 public static void main(String[] args){
  FactoryCoin fc = new FactoryCoin();
  fc.play();
 }
}

嵌套类

类中包含类...

package Ten;
public class QianTao {
 private static class QianTao1{
  private int i ;
  public int value(int i){
   this.i = i;
   QianTao1 q1 = new QianTao1();
   System.out.println(q1.getClass() +" value: "+ i);
   return i;
  }
  
  //内部类中又包括内部类
 
  private class QianTao2{
   private int i ;
   public int value(int i){
    this.i = i;
    QianTao2 q2 = new QianTao2();
    System.out.println(q2.getClass() + " value: "+ i);
    return i;
   }
  }
 }
 
 public static void main(String[] args){
  QianTao1 q1 = new QianTao1();
  q1.value(1);
  
  //QianTao2对外部方法不能直接Access
 
  QianTao1.QianTao2 q2 = q1.new QianTao2();
  q1.value(2);
 }
}/*
class Ten.QianTao$QianTao1 value: 1
class Ten.QianTao$QianTao1 value: 2*/

exercise19

创建一个包含内部类的类,而此内部类中又包含内部类,编译器生成了每一个类的.class文件

 package Ten;
public class NestClass {
 class Inner1{
 
  class Inner2{
   void f(){}
  }
  Inner2 makeInner2(){return new Inner2();}
 }
 Inner1 makeInner1(){return new Inner1();}
 static class Nested1{
  void f(){}
 
  static class Nested2{
   void f(){}
  }
 }
 
 public static void main(String[] args){
  new NestClass.Nested1().f();
  new NestClass.Nested1.Nested2().f();
  NestClass n = new NestClass();
  NestClass.Inner1 n1 = n.makeInner1();
  NestClass.Inner1.Inner2 n2 = n1.makeInner2();
  n2.f();
  
 }
 
 }/*不是输出
生成的.class文件
NestClass.class
NestClass$Inner1.class
NestClass$Inner1$Inner2.class
NestClass$Nested1.class
NestClass$Nested1$Nested2.class
*/

包含内部类的接口

 package Ten;

//创建包含嵌套类的接口

public interface InterfaceQian {
 public void f();
 public static class A implements InterfaceQian{
  
  public void f() {
   // TODO Auto-generated method stub
   System.out.println("A f()");
  }
  public static void main(String[] args){
   A a = new A();
   a.f();
  }
 } 
}/*A f()*/

由实现接口的类间接返回接口

package Ten;
interface interf{
 void f();
}
class A{
 public interf get(){
  
  class Inf implements interf{
   public void f() {
    // TODO Auto-generated method stub
    System.out.println("Inf.f()");
   }
   
  }
  return new Inf();
  
 }
}
public class InterfaceInner {
 public static void main(String[] args){
  A a = new A();
  
  interf intf = a.get();//由实现接口的类间接返回接口
  
  intf.f();
  
 }
}

 

© 著作权归作者所有

DouDouLee
粉丝 6
博文 95
码字总数 45242
作品 0
西安
私信 提问
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
2018/06/21
0
0
Java中的内部类实例初始化匿名函数(JLS7 8.6:Instance Initializers)

偶尔发现了一段好玩的java代码,关于Java内部类的,觉得很有意思,但是想不明白这段代码是java语法的特性哪?还是别的什么。最后发现还是对java了解的不够深啊。先上代码: import java.util...

qalong
2013/09/02
3.4K
0
关于Scala的路徑依赖类型(Path-dependent type)

咋看这个术语,有点吓倒。其实不是什么新东西,也是讲关于内部类和外部类的事,不过两者有点区别。在Scala中,内部类和外部类的一些行为特性和Java差不多。 请看如下的Scala代码: class Out...

mj4738
2011/11/25
925
0
【Scala】Scala高级使用技巧之一

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/gongxifacai_believe/article/details/82110617 1、Scaladoc的使用 Scaladoc是Scala的API文档,包含了Scala所有的A...

魏晓蕾
2018/08/27
0
0
《On Java 8》中文版,又名《Java 编程思想》中文第五版

来源:LingCoder/OnJava8 主译: LingCoder 参译: LortSir 校对:nickChenyx E-mail: lingcoder@gmail.com 本书原作者为 [美] Bruce Eckel,即(Thinking in Java 4th Edition,2006)的作者。......

ApacheCN_飞龙
04/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Taro 兼容 h5 踩坑指南

最近一周在做 Taro 适配 h5 端,过程中改改补补,好不酸爽。 本文记录📝遇到的问题,希望为有相同需求的哥们👬节约点时间。 Taro 版本:1.3.9。 解决跨域问题 h5 发请求会报跨域问题,需...

dkvirus
56分钟前
4
0
Spring boot 静态资源访问

0. 两个配置 spring.mvc.static-path-patternspring.resources.static-locations 1. application中需要先行的两个配置项 1.1 spring.mvc.static-path-pattern 这个配置项是告诉springboo......

moon888
今天
3
0
hash slot(虚拟桶)

在分布式集群中,如何保证相同请求落到相同的机器上,并且后面的集群机器可以尽可能的均分请求,并且当扩容或down机的情况下能对原有集群影响最小。 round robin算法:是把数据mod后直接映射...

李朝强
今天
4
0
Kafka 原理和实战

本文首发于 vivo互联网技术 微信公众号 https://mp.weixin.qq.com/s/bV8AhqAjQp4a_iXRfobkCQ 作者简介:郑志彬,毕业于华南理工大学计算机科学与技术(双语班)。先后从事过电子商务、开放平...

vivo互联网技术
今天
19
0
java数据类型

基本类型: 整型:Byte,short,int,long 浮点型:float,double 字符型:char 布尔型:boolean 引用类型: 类类型: 接口类型: 数组类型: Byte 1字节 八位 -128 -------- 127 short 2字节...

audience_1
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部