Android_1.0_eBook_by_tom_kao_2008_10_15.pdf
《Android应用框架原理与程序设计36技》
本書完整範例程式碼請到網站下載:
www.misoo1.com 或 tom-kao.blogspot.com
高煥堂 著(2008 年10 月第三版)
misoo.tw@gmail.com
反向控制(Inversion of Control)
當子類別繼承父類別時,父類別之函數可以呼叫子類別之函數。雖然父類別(前輩)誕生時,子類別(晚輩)常常尚未誕生﹔但是前輩有時候可預知晚輩中的函數,就可呼叫它。
框架裡的抽象類別就是扮演父類別的角色,只是含有一些陽春型(抽象的)的類別,其提供很通用,但不完整的函數,是設計師刻意留給應用程式的子類別來補充的。一旦補充完成,框架裡的父類別的函數就可以「反向呼叫」子類別裡的函數了。
2.2.2.1 以一般Java 程式為例
例如:有了一個繪圖的Shape 父類別:
// Shape.java
package framework;
public class Shap{
public void paint() { this.onDraw(); }
public abstract void onDraw();
}
設計者預期子類別將會定義一個Draw()函數,於是讓Paint()呼叫子類別的Draw()函數。於是子類別(晚輩)提供Draw()給父類別(前輩)來呼叫之,如下:
//Cicrle.java
package _objects;
import java.awt.Color;
import java.awt.Graphics;
import _framework.*;
public class Circle extends Shape {
private Graphics m_gr;
private int x, y, radius;
public Circle(Graphics gr) { m_gr = gr; }
public void SetValue(int x0, int y0, int rad){
x = x0; y = y0;
radius = rad;
}
public void Draw(){ //畫圓
m_gr.setColor(Color.BLACK);
m_gr.drawOval(x-radius, y-radius, 2*radius, 2*radius);
}}
接者,寫個JMain 類別:
// JMain.java
import java.awt.*;
import javax.swing.*;
import _framework.Shape;
import _objects.*;
class JP extends JPanel {
public void paintComponent(Graphics gr){
super.paintComponents(gr);
Circle cir = new Circle(gr);
cir.setValue(160, 100, 45);
Shape sp = cir;
sp.paint();
}
}
public class JMain extends JFrame{
public JMain(){
setTitle("");
setSize(400,300);
}
public static void main(String args[]){
JMain frm = new JMain();
JP panel = new JP();
frm.add(panel);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setVisible(true);
}
}
//执行sp.paint()指令时,呼叫Shape父类别的paint()函数
//接着呼叫子类别Circle中的onDraw()函数[因为onDraw是在子类别中定义]
//这种长辈呼叫晚辈的用法,就是 反向Inversion呼叫法。
//由于长辈拥有主控权,所以这种机制又称为 反向控制(Inversion of Control)
//这种传统的Ioc机制称为继承体系Ioc
//后来,人们常将许多相关的父类别聚集起来成为框架
//逐渐地延伸为:应用框架主动呼叫应用程式的情形,就称为Ioc
//或者说:会主动呼叫应用程式的框架就称为Ioc框架,例如Android,Spring等等