《Java编程思想》第十章 内部类

1、将一个类的定义放到另一个类的内部,称为内部类。允许把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性。

 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月20日 下午4:39:35
 4  */
 5 public class Parcel1 {
 6     class Contents{
 7         private int i = 11;
 8         public int value(){return i;}
 9     }
10     class Destination{
11         private String label;
12         Destination(String whereTo){
13             label = whereTo;
14         }
15         String readLable(){return label;}
16     }
17     public void ship(String dest){
18         Contents c  = new Contents();
19         System.out.println(c.value());
20         Destination d = new Destination(dest);
21         System.out.println(d.readLable());
22     }
23     public static void main(String[] args) {
24         // TODO Auto-generated method stub
25         Parcel1 parcel1 = new Parcel1();
26         parcel1.ship("Tasmania");
27     }
28 }

2、内部类能访问其外围对象的所有成员,拥有外围类的所有元素的访问权。构建内部类对象时,需要一个指向其外围类对象的引用。

 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月20日 下午5:07:09
 4  */
 5 public class Parcel2 {
 6     class Contents{
 7         private int i = 11;
 8         public int value(){return i;}
 9     }
10     class Destination{
11         private String label;
12         Destination(String whereTo){
13             label = whereTo;
14         }
15         String readLable(){return label;}
16     }
17     public Destination to(String s){
18         return new Destination(s);
19     }
20     public Contents contents(){
21         return new Contents();
22     }
23     public void ship(String dest){
24         Contents c  = new Contents();
25         //System.out.println(c.value());
26         Destination d = new Destination(dest);
27         System.out.println(d.readLable());
28     }
29     public static void main(String[] args) {
30         // TODO Auto-generated method stub
31         Parcel2 p = new Parcel2();
32         p.ship("Tasmania");
33         Parcel2 q = new Parcel2();
34         Parcel2.Contents c = q.contents();
35         Parcel2.Destination d = q.to("Borneo");
36     }
37
38 }
 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月20日 下午5:13:32
 4  */
 5 interface Selector{
 6     boolean end();
 7     Object current();
 8     void next();
 9 }
10 public class Sequence {
11     private Object[] items;
12     private int next = 0;
13     public Sequence(int size){items = new Object[size];}
14     public void add(Object x){
15         if(next<items.length)
16             items[next++] = x;
17     }
18     private class SequeceSelector implements Selector{
19         private int i = 0;
20         public boolean end(){return i == items.length;}
21         public Object current(){return items[i];}
22         public void next(){if(i<items.length) i++;}
23     }
24     public Selector selector(){
25         return new SequeceSelector();
26     }
27     public static void main(String[] args) {
28         // TODO Auto-generated method stub
29         Sequence sequence = new Sequence(10);
30         for(int i = 0; i<10;i++){
31             sequence.add(Integer.toString(i));
32         }
33         Selector selector = sequence.selector();
34         while(!selector.end()){
35             System.out.println(selector.current()+" ");
36             selector.next();
37         }
38     }
39
40 }

3、需要生成对外部类对象的引用,则使用外部类名字后面加.this   如果想告知某些其他对象,去创建某个内部类的对象,则必须在new表达式中提供对其他外部类对象的引用,使用.new语法。要创建内部类的对象,要使用外部类的对象来创建内部类的对象。

 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月21日 下午3:56:37
 4  */
 5 public class DotThis {
 6     void f(){System.out.println("DoThis.f()");}
 7     public class Inner{
 8         public DotThis outer(){
 9             return DotThis.this;
10         }
11     }
12     public Inner inner() {
13         return new Inner();
14     }
15     public static void main(String[] args) {
16         // TODO Auto-generated method stub
17         DotThis dt = new DotThis();
18         DotThis.Inner dti = dt.inner();
19         dti.outer().f();
20     }
21
22 }
 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月21日 下午4:02:57
 4  */
 5 public class Parcel3 {
 6     class Contents{
 7         private int i = 11;
 8         public int value(){return i;}
 9     }
10     class Destination{
11         private String label;
12         Destination(String whereTo){
13             label = whereTo;
14         }
15         String readLable(){return label;}
16     }
17
18     public static void main(String[] args) {
19         // TODO Auto-generated method stub
20         Parcel3 p = new Parcel3();
21         Parcel3.Contents c = p.new Contents();
22         Parcel3.Destination d = p.new Destination("Tasmania");
23     }
24
25 }

4、如果不需要内部类对象与外部类对象之间有联系,则可以将内部类声明为static,这称为嵌套类。嵌套类没有this方法。不能链接外部类。

5、嵌套类和普通内部类的区别:普通内部类的字段与方法,只能放在类的外部层次上,所以普通的内部类不能有static数据和static字段,也不能包含嵌套类。

6、嵌套类可以作为接口的一部分。放入接口中的任何类都是public和static的。

7、如果要创建某些公共代码,使得他们可以被某个接口的所有不同实现所共有,则使用接口内部嵌套类方便。

8、多层嵌套类均可以访问其所嵌入的外围类的所有成员。

 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月21日 下午4:48:45
 4  */
 5 class MNA{
 6     private void f(){System.out.println("f()");}
 7     class A{
 8         private void g(){System.out.println("g()");}
 9         public class B{
10             void h(){
11                 System.out.println("h()");
12                 g();
13                 f();
14             }
15         }
16     }
17 }
18 public class MultiNestingAccess {
19     public static void main(String[] args) {
20         // TODO Auto-generated method stub
21         MNA mna = new MNA();
22         MNA.A mnaa = mna.new A();
23         MNA.A.B mnaab = mnaa.new B();
24         mnaab.h();
25     }
26
27 }

9、为什么需要内部类:每个内部类都能独立的继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,都对内部类没有影响。内部类有效的解决了多继承问题,允许继承多个非接口类型。

 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月21日 下午5:09:38
 4  */
 5 interface Incrementable{
 6     void increment();
 7 }
 8
 9 class Callee1 implements Incrementable{
10     private int i = 0;
11     public void increment() {
12         // TODO Auto-generated method stub
13         i++;
14         System.out.println(i);
15     }
16 }
17
18 class MyIncrement{
19     public void increment(){System.out.println("Other operation");}
20     static void f(MyIncrement mi){mi.increment();}
21 }
22
23 class Callee2 extends MyIncrement{
24     private int i = 0;
25     public void increment(){
26         super.increment();
27         i++;
28         System.out.println(i);
29     }
30     private class Closure implements Incrementable{
31         public void increment(){
32             Callee2.this.increment();
33         }
34     }
35     Incrementable getCallbackReference(){
36         return new Closure();
37     }
38 }
39
40 class Caller{
41     private Incrementable callbackReference;
42     Caller(Incrementable cbh) {
43         // TODO Auto-generated constructor stub
44         callbackReference = cbh;
45     }
46     void go(){callbackReference.increment();}
47 }
48 public class Callbacks {
49
50     public static void main(String[] args) {
51         // TODO Auto-generated method stub
52         Callee1 c1 = new Callee1();
53         Callee2 c2 = new Callee2();
54         MyIncrement.f(c2);
55         Caller caller1 = new Caller(c1);
56         Caller caller2 = new Caller(c2.getCallbackReference());
57         caller1.go();
58         caller1.go();
59         caller2.go();
60         caller2.go();
61     }
62 }

10、如果拥有的是抽象的类或者具体的类,则只有内部类能实现多重继承。

11、闭包是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域。通过回调,对象能够携带一些信息,这些信息允许它在稍后的某个时刻调用初始的对象。通过内部对象提供的闭包功能可以实现回调。

 1 package controller;
 2 /**
 3  * @author zlz099:
 4  * @version 创建时间:2017年9月25日 下午9:38:48
 5  */
 6 public abstract class Event {
 7     private long eventTime;
 8     protected final long delayTime;
 9     public Event(long delayTime){
10         this.delayTime = delayTime;
11         start();
12     }
13     public void start(){
14         eventTime = System.nanoTime()+delayTime;
15     }
16     public boolean ready(){
17         return System.nanoTime()>=eventTime;
18     }
19     public abstract void action();
20
21 }
 1 package controller;
 2
 3 import java.util.*;
 4
 5 /**
 6  * @author zlz099:
 7  * @version 创建时间:2017年9月25日 下午9:36:23
 8  */
 9 public class Controller {
10     private List<Event> eventList = new ArrayList<Event>();
11     public void addEvent(Event c){eventList.add(c);}
12     public void run(){
13         while(eventList.size()>0){
14             for(Event e : new ArrayList<Event>(eventList))
15                 if(e.ready()){
16                     System.out.println(e);
17                     e.action();
18                     eventList.remove(e);
19                 }
20         }
21     }
22 }
  1 package controller;
  2
  3 import java.lang.Thread.State;
  4
  5 /**
  6  * @author zlz099:
  7  * @version 创建时间:2017年9月25日 下午9:48:46
  8  */
  9 public class Greenhouse extends Controller{
 10     private boolean light = false;
 11     public class LightOn extends Event{
 12         public LightOn(long delayTime){super(delayTime);}
 13         public void action() {
 14             // TODO Auto-generated method stub
 15             light = true;
 16         }
 17         public String toString(){return "Light is on";}
 18     }
 19     public class LightOff extends Event{
 20
 21         public LightOff(long delayTime){super(delayTime);}
 22         public void action() {
 23             // TODO Auto-generated method stub
 24             light = false;
 25         }
 26         public String toString(){return "Light is off";}
 27     }
 28     private boolean water = false;
 29     public class WaterOn extends Event{
 30         public WaterOn(long delayTime){super(delayTime);}
 31         public void action() {
 32             // TODO Auto-generated method stub
 33             water = true;
 34         }
 35         public String toString(){return "greenhouse water is on";}
 36     }
 37
 38     public class WaterOff extends Event{
 39         public WaterOff(long delayTime){super(delayTime);}
 40         public void action() {
 41             // TODO Auto-generated method stub
 42             water = false;
 43         }
 44         public String toString(){return "greenhouse water is off";}
 45     }
 46
 47     private String thermostat = "Day";
 48     public class ThermostatNight extends Event{
 49         public ThermostatNight(long delayTime){super(delayTime);}
 50         public void action() {
 51             // TODO Auto-generated method stub
 52             thermostat = "Night";
 53         }
 54         public String toString(){return "Thermostat on night setting";}
 55     }
 56
 57     public class ThermostatDay extends Event{
 58         public ThermostatDay(long delayTime){super(delayTime);}
 59         public void action() {
 60             // TODO Auto-generated method stub
 61             thermostat = "Day";
 62         }
 63         public String toString(){return "Thermostat on day setting";}
 64     }
 65
 66     public class Bell extends Event{
 67         public Bell(long delayTime){super(delayTime);}
 68         public void action() {
 69             // TODO Auto-generated method stub
 70             addEvent(new Bell(delayTime));
 71         }
 72         public String toString(){return "Ring!";}
 73     }
 74     public class Restart extends Event{
 75         private Event[] eventList;
 76         public Restart(long delayTime,Event[] eventList){
 77             super(delayTime);
 78             this.eventList = eventList;
 79             for(Event e : eventList)
 80                 addEvent(e);
 81         }
 82         public void action(){
 83             for(Event e : eventList){
 84                 e.start();
 85                 addEvent(e);
 86             }
 87             start();
 88             addEvent(this);
 89         }
 90         public String toString(){
 91             return "Restarting system";
 92         }
 93     }
 94     public static class Terminate extends Event {
 95         // TODO Auto-generated method stub
 96         public Terminate(long delayTime){super(delayTime);}
 97         public void action(){System.exit(0);}
 98         public String toString(){return "Terminating";}
 99     }
100 }
 1 package controller;
 2 /**
 3  * @author zlz099:
 4  * @version 创建时间:2017年9月26日 上午9:46:11
 5  */
 6 public class GreenhouseController {
 7
 8     public static void main(String[] args) {
 9         // TODO Auto-generated method stub
10         Greenhouse gs = new Greenhouse();
11         gs.addEvent(gs.new Bell(900));
12         Event[] eventList = {
13             gs.new ThermostatNight(0),
14             gs.new LightOn(200),
15             //gs.new LightOff(200),
16             gs.new LightOff(400),
17             gs.new WaterOn(600),
18             gs.new WaterOff(800),
19             gs.new ThermostatDay(1400)
20         };
21         gs.addEvent(gs.new Restart(2000, eventList));
22         if(args.length == 1)
23             gs.addEvent(new Greenhouse.Terminate((new Integer(args[0]))));
24         gs.run();
25     }
26
27 }

12、内部类的构造器必须连接到指向其外围类对象的引用,所以继承内部类有点复杂。默认构造器不好使,且不能只是传递一个指向外围类对象的引用。此外,必须在构造器内使用如下算法:enclosingClassReference.super();才提供了必要的引用,编译才能通过。

 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月26日 上午10:00:39
 4  * 内部类的继承
 5  */
 6 class WithInner{
 7     class Inner{}
 8 }
 9 public class InheritInner extends WithInner.Inner{
10      InheritInner(WithInner wi) {
11         // TODO Auto-generated constructor stub
12          wi.super();
13      }
14
15     public static void main(String[] args) {
16         // TODO Auto-generated method stub
17         WithInner wi = new WithInner();
18         InheritInner ii = new InheritInner(wi);
19     }
20
21 }

13、当继承某个外围类时,内部类不会发生神奇的变化。这两个内部类是独立的个体,各自在各自的命名空间中。当然,明确的继承某个内部类是可以的。

 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月26日 上午10:05:28
 4  */
 5 class Egg{
 6     private Yolk y;
 7     protected class Yolk{
 8         public Yolk(){System.out.println("Egg.Yolk()");}
 9     }
10     public Egg(){
11         System.out.println("new Egg()");
12         y = new Yolk();
13     }
14 }
15 public class BigEgg extends Egg {
16     public void Yolk(){System.out.println("BigEgg.Yolk()");}
17     public static void main(String[] args) {
18         // TODO Auto-generated method stub
19         new BigEgg();
20     }
21
22 }
 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月26日 上午10:57:38
 4  */
 5 class Egg2{
 6     protected class Yolk{
 7         public Yolk(){
 8             System.out.println("Egg2.Yolk()");
 9         }
10         public void f(){System.out.println("Egg2.Yolk.f()");}
11     }
12     private Yolk y = new Yolk();
13     public Egg2(){System.out.println("New Egg2()");}
14     public void insertYolk(Yolk yy){y =yy;}
15     public void g(){y.f();}
16 }
17 public class BigEgg2 extends Egg2{
18     public class Yolk extends Egg2.Yolk{
19         public Yolk(){System.out.println("BigEgg2.Yolk()");}
20         public void f(){System.out.println("BigEgg2.Yolk.f()");}
21     }
22     public BigEgg2(){insertYolk(new Yolk());}
23     public static void main(String[] args) {
24         // TODO Auto-generated method stub
25         Egg2 e2 = new BigEgg2();
26         e2.g();
27     }
28
29 }

14、局部内部类可以在代码块内创建内部类,不能有访问说明符,但可以访问当前代码块内的常量以及此外围类的所有成员。

 1 /**
 2  * @author zlz099:
 3  * @version 创建时间:2017年9月26日 上午11:12:03
 4  */
 5 interface Counter{
 6     int next();
 7 }
 8 public class LocalInnerClass {
 9     private int count = 0;
10     Counter getCounter (final String name){
11         class LocalCounter implements Counter{
12             public LocalCounter(){
13                 System.out.println("LocalCounter()");
14             }
15             public int next(){
16                 System.out.println(name);
17                 return count++;
18             }
19         }
20         return new LocalCounter();
21     }
22     Counter getCounter2(final String name){
23         return new Counter() {
24             {
25                 System.out.println("Counter()");
26             }
27             @Override
28             public int next() {
29                 // TODO Auto-generated method stub
30                 System.out.println(name);
31                 return count++;
32             }
33         };
34     }
35     public static void main(String[] args) {
36         // TODO Auto-generated method stub
37         LocalInnerClass lic = new LocalInnerClass();
38         Counter
39             c1=lic.getCounter("Local inner ");
40         Counter
41             c2=lic.getCounter2("Anonymous inner ");
42
43         for(int i = 0; i<5; i++){
44             System.out.println(c1.next());
45         }
46         for(int i = 0; i<5; i++){
47             System.out.println(c2.next());
48         }
49     }
50
51 }

15、使用局部内部类而不是匿名内部类的理由是我们需要一个已命名的构造器,或者需要重载构造器,而匿名内部类只能用于实例初始化。即需要不止一个该内部类的而对象。

时间: 2024-10-10 04:22:01

《Java编程思想》第十章 内部类的相关文章

Java编程思想---第十章 内部类(下)

第十章 内部类(下) 10.9 内部类的继承 因为内部类的构造器必须连接到指向其外围类对象的引用,所以在继承内部类的时候事情会变得有些复杂,问题在于那个指向外围类对象的引用必须被初始化,而在导出类中不再存在可连接的默认对象,要解决这个问题,必须使用特殊的语法来明确说清他们之间的关联: class WithInner { class Inner {} } public class InheritInner extends WithInner.Inner { InheritInner(WithInn

Java编程思想---第十章 内部类(上)

第十章  内部类(上) 可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一种非常有用的特性,它允许你把一些逻辑相关的类组织在一起,并控制位于内部的类的可视性,但内部类与组合是完全不同的概念. 10.1 创建内部类 创建内部类的方法就是,把类的定义置于外围类的里面: public class Parcel1 { class Contents { private int i = 11; public int value() { return i; } } class Destina

【Java编程思想】10.内部类

将一个类的定义放在另一个类的定义内部,这就是内部类. 10.1 创建内部类 内部类的名字是嵌套在外部类里面的 外部类可以有方法,返回一个指向内部类的调用.(外部类中可以调用内部类) 如果在外部类中,希望能在除了静态方法之外的任意位置创建某个内部类对象,那么可以向下面这样指明对象类型. OuterClassName.InnerClassName x = new InnerClassName(); 10.2 链接到外部类 在创建了一个内部类的对象后,内部类与制造它的外围对象(enclosing ob

Java编程思想(前十章)

Java编程思想 有C++编程基础的条件下, 前10章可以快速过一下,都是基本语法,不需要花太多时间. 着重中后段的一些章节,类型信息.泛型.容器.IO.并发等. 中文翻译版 阅读地址 对于一个架构师而言,掌握各种语言的优势并可以运用到系统中,由此简化系统的开发,是其架构生涯的第一步. 每一个程序员都不能固步自封,要多接触新的行业,新的技术领域,突破自我. 对象入门 类的继承一般使用'统一标记法'(UML图)来画继承的图. 在面向对象的程序中, 通常要用到上溯造型(向上转型)的技术, 需要动态绑

Java编程思想之十 内部类

可以将一个类定义放在另一个类的定义内部,这就是内部类. 10.1 创建内部类 创建内部类就是把类的定义置于外部类里面. public class Parcell { class contents{ int i=0; public void GetI(){ System.out.println("contents"+i); i++; } } class Destintion{ private String label; public void GetI(String s){ System

Java编程思想笔记(内部类)

      1.创建内部类       2.链接到外部类:当生成一个内部类的对象时,此对象与制造它的外围对象之间就有了一种联系,所以它能访问其外围对象的所有成员,而不需要任何特殊条件.   3.使用.this()与.new():1.如果你需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this.2.DotNew dn = new DotNew(); DotNew.Inner dni = dn.new Inner(); //要想直接创建内部类的对象,你不能按照你想象的方式,去引用外部

关于阅读java编程思想和effective java的一些看法

个人认为,java编程思想并不适合当作新手入门书籍来看,它更多是像给已经使用过java的人群对于基础的一些查缺补漏,有点像一本大部头的工具书,目前该书已看至第十章 -- 内部类, 而effective java这本书,更多是如所说的,是一本分享经验与指引你避免走弯路的经典著作,针对如何编写高效.设计优良的程序提出了最实用.最权威的指导方针,目前该书只看至第三章.我本来是想看完一个章节来写一个读书笔记,但目前来看,这样不合适,都是经典书籍,好书就该多读几次,所以第一遍初读只是大概了解书籍所讲的内容

《On Java 8》中文版,又名《Java 编程思想》中文第五版

来源:LingCoder/OnJava8 主译: LingCoder 参译: LortSir 校对:nickChenyx E-mail: [email protected] 本书原作者为 [美] Bruce Eckel,即(Thinking in Java 4th Edition,2006)的作者. 本书是事实上的 Thinking in Java 5th Edition(On Java 8,2017). Thinking in Java 4th Edition 基于 JAVA 5 版本:On

《Java编程思想(第4版)》pdf

下载地址:网盘下载 内容简介 编辑 本书赢得了全球程序员的广泛赞誉,即使是最晦涩的概念,在Bruce Eckel的文字亲和力和小而直接的编程示例面前也会化解于无形.从Java的基础语法到最高级特性(深入的面向对象概念.多线程.自动项目构建.单元测试和调试等),本书都能逐步指导你轻松掌握.[1] 从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作.本书的作者拥有多年教学经验,对C.C++以及Java语言都有独到.深入的见解,以通俗易懂及小而直接的示例解释了一个个晦涩抽象的概

java编程思想第1、2、3章细节总结

转眼已经大二学期的暑假,已经使用java有一年了,才开始看thinking in java 这本经典书籍,算是做个系统总结吧,只列一些目前还掌握不熟的需要谨记的知识点. 第一章:对象导论 1.java中的权限:public,protected,private,default. public:可以被任何对象访问. protected:只能在本类和本类的内部类中使用,通过继承操作可以继承下去. private:只能在本类和本类的内部类中使用. default:如果没有加任何权限,则默认就是这个def