Thinking in java 读书笔记(七.2:内部类:闭包和控制框架)
2018-02-12 20:47
375 查看
一、
内部类是就是面向对象的一种闭包形式。
首先说说闭包。最坑爹的闭包应该是JavaScript的闭包了,JS函数外部无法读取函数内的变量,而函数内可以读取外部变量,然后当外部需要读取内部变量时就需要使用闭包(JS一般使用一个function表示闭包)。
而对于Java来说,可以吧函数类比为class,当我们需要读取某个class的某个private的参数可以使用内部类来访问,因为内部类可以透明的访问它所嵌入的外围类的所有成员。
书上例子如下
二、控制框架
这里引入了第三种设计模式:模板方法。事实上其实应用框架是模板方法的一种实现,而控制框架是一种特殊的应用框架。
应用框架是设计来解决某种特定问题的一组类。运用某个应用程序框架,通常是继承一个或者多个类并且覆盖某些方法,在覆盖的方法中编写解决方案。
有写过JavaFX和Android,这两个应该都是这种应用框架的实现。但是书上用的swing举例。所以这里算是应用框架初探了…。
模板方法最关键的地方是使变量和常量分离
然后内部类和控制框架有什么关心呢,内部类一般用来改写event(至少目前只碰到过这个)。虽然现在自己个人写点东西都喜欢使用lambda表达式,或者直接使用匿名内部类,但是事实上使用内部类来写event可读性高的不是一点两点,还是改城用内部类吧。
三、内部类的继承、覆盖
内部类是就是面向对象的一种闭包形式。
首先说说闭包。最坑爹的闭包应该是JavaScript的闭包了,JS函数外部无法读取函数内的变量,而函数内可以读取外部变量,然后当外部需要读取内部变量时就需要使用闭包(JS一般使用一个function表示闭包)。
而对于Java来说,可以吧函数类比为class,当我们需要读取某个class的某个private的参数可以使用内部类来访问,因为内部类可以透明的访问它所嵌入的外围类的所有成员。
书上例子如下
package com.company.ChildrenClass; interface Incrementable{ void increment(); } class Callee1 implements Incrementable{ private int i = 0; @Override public void increment() { i++; System.out.println(i); } } class MyIncrement{ public void increment(){ System.out.println("other operation"); } static void f(MyIncrement myIncrement){ myIncrement.increment(); } } class Callee2 extends MyIncrement{ private int i=0; public void increment(){ super.increment(); i++; System.out.println(i); } private class Closure implements Incrementable{ @Override public void increment() { Callee2.this.increment(); } } Incrementable getCallBackReference(){ return new Closure(); } } class Caller{ private Incrementable callbackReference; Caller(Incrementable callbackReference){ this.callbackReference = callbackReference; } void go(){ callbackReference.increment(); } } /*这里的回调似乎是为了动态扩展 * Callee2由于继承的父类已经存在接口中的方法,想要同时实现父类和接口的方法, * 需要的就是内部类(其实已经是多继承的一种实现吧),内部类来实现接口,然后提供回调,传出内部类引用 * */ public class CallBacks { public static void main(String[] args) { Callee1 callee1 = new Callee1(); Callee2 callee2 = new Callee2(); MyIncrement.f(callee2); Caller caller1 = new Caller(callee1); Caller caller2 = new Caller(callee2.getCallBackReference()); caller1.go(); caller2.go(); } }
二、控制框架
这里引入了第三种设计模式:模板方法。事实上其实应用框架是模板方法的一种实现,而控制框架是一种特殊的应用框架。
应用框架是设计来解决某种特定问题的一组类。运用某个应用程序框架,通常是继承一个或者多个类并且覆盖某些方法,在覆盖的方法中编写解决方案。
有写过JavaFX和Android,这两个应该都是这种应用框架的实现。但是书上用的swing举例。所以这里算是应用框架初探了…。
模板方法最关键的地方是使变量和常量分离
//书中以下示例代码将忽略具体的event细节而设计框架。 public abstract class Event { private long eventTime; protected final long delayTime; public Event(long delayTime){ this.delayTime = delayTime; } public void start(){ //allows restarting eventTime = System.nanoTime()+delayTime;//generate start time; } public boolean ready(){ return System.nanoTime()>=eventTime; } public abstract void action(); } public class Controller { private List<Event> eventList = new ArrayList<>(); public void addEvent(Event event){ eventList.add(event); } public void run(){ while (eventList.size()>0){ //不是很清楚为什么要用副本 for (Event e:new ArrayList<Event>(eventList)){ if (e.ready()){ System.out.println(e); e.action(); eventList.remove(e); } } } } }
然后内部类和控制框架有什么关心呢,内部类一般用来改写event(至少目前只碰到过这个)。虽然现在自己个人写点东西都喜欢使用lambda表达式,或者直接使用匿名内部类,但是事实上使用内部类来写event可读性高的不是一点两点,还是改城用内部类吧。
//这里不使用书上的实例代码,放个写javafx的实例 //设置JavaFXStage关闭时的动作。 primaryStage.setOnCloseRequest(new WindowsCloseEvent(primaryStage)); class WindowsCloseEvent implements EventHandler<WindowEvent> { private Stage stage; public WindowsCloseEvent(Stage stage){ this.stage = stage; } public void handle(WindowEvent event) { event.consume(); if (!isSendFile&&!isRecFile){ UserBean clientBean = new UserBean(); clientBean.setType(-1); clientBean.setName(username); clientBean.setTimer(DateUtil.getTimer()); sendMessage(clientBean); primaryStage.close(); } if (isRecFile){ dialogController.setText("正在接受文件无法退出"); Dialog.show(); } if (isSendFile){ dialogController.setText("正在发送文件无法退出"); Dialog.show(); } } }
三、内部类的继承、覆盖
public class InheritInner extends WithClass.Inner { //因为非static的内部类如果外部类没有初始化的话,内部类也就不存在的, //所以需要传入一个外部类的实例 InheritInner(WithClass withClass){ withClass.super(); } public static void main(String[] args) { WithClass wi = new WithClass(); } } class WithClass{ class Inner{} } //因为内部类的访问需要通过外部类,所以其实子类是无法覆盖父类的内部类的。
相关文章推荐
- Thinking-in-Java 读书笔记-10-内部类
- Thinking-in-Java 读书笔记-6-访问权限控制
- 含继承在内的初始化过程 ——《Thinking in java》 读书笔记之一
- thinking in java 读书笔记3
- 《Thinking in Java》读书笔记
- 《Thinking in Java》读书笔记之并发(四)
- Thinking-in-Java 读书笔记-11-持有对象
- 第十章:内部类《Thinking in java》学习笔记
- 《Thinking in Java》学习笔记-----第6章 访问权限控制
- thingking in java 读书笔记---控制程序流
- 《Thinking in Java》读书笔记之并发(一)
- 《Thinking in Java》读书笔记之并发(三)
- 《Thinking in Java》读书笔记
- 《thinking in JAVA》读书笔记 - 1
- Thinking in Java 读书笔记 1
- Thinking in java 4th Edition 读书笔记-I/O(2)
- Thinking in java 读书笔记(三、finalize(),对象的创建,可变参数列表,函数重载)
- 《thinking in JAVA》读书笔记 (二)
- 《thinking-in-java》读书笔记-第15章-泛型(一)
- 第十章:内部类 《Thinking in java》学习笔记