1 / 25

Ch15 視窗程式設計 (2)

Ch15 視窗程式設計 (2). JAVA 程式語言入門 (2). 大綱. 監聽器介面 ( 參考 Ch 10) 事件轉接類別 ( 參考 Ch 10) 抽象類別 介面 多重繼承. 抽象類別 (1/3). 類別定義中,只要有一個方法(或以上)定義為 抽象方法 (abstract method),則該類別為 抽象類別 (abstract class)。 抽象方法並沒有定義方法的主體(沒有實作) 無法利用抽象類別建立物件。 抽象類別的用處是當作父類別,讓子類別繼承。 子類別必須將父類別中的抽象方法實作出來,才能建立物件。. 抽象類別 (2/3).

cassia
Download Presentation

Ch15 視窗程式設計 (2)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Ch15 視窗程式設計(2) JAVA程式語言入門(2)

  2. 大綱 • 監聽器介面(參考Ch 10) • 事件轉接類別(參考Ch 10) • 抽象類別 • 介面 • 多重繼承

  3. 抽象類別(1/3) • 類別定義中,只要有一個方法(或以上)定義為抽象方法(abstract method),則該類別為抽象類別(abstract class)。 • 抽象方法並沒有定義方法的主體(沒有實作) • 無法利用抽象類別建立物件。 • 抽象類別的用處是當作父類別,讓子類別繼承。 • 子類別必須將父類別中的抽象方法實作出來,才能建立物件。

  4. 抽象類別(2/3) • 抽象類別的定義語法: 修飾字 abstract class 類別名稱 { //屬性宣告 修飾字 abstract 型別 方法名稱(參數列); //其它方法定義 } • 某個類別的主體內,宣告了抽象方法,則該類別必須宣告為抽象類別。 • 抽象類別雖然不能用以建立物件,但是可以當作物件的型別,用來宣告參照變數。 • 抽象類別的子類別若不完全實作抽象方法,則依然是抽象類別。

  5. 抽象類別(3/3) • 使用抽象類別的用意,主要是「制定固定的訊息接收管道,但不把焦點放在訊息的處理上」。 • 抽象類別和一般類別一樣,都可以定義建構子,只是不能直接以抽象類別的建構子建立物件。 • 抽象方法的目的就是為了讓子類別實作,所以abstract不能同時和final、static或private一起使用。

  6. 單一繼承 vs 多重繼承(1/2) • Java的繼承是屬於單一繼承,C++的繼承是屬於多重繼承 • 多重繼承是指:指一個類別能夠繼承多個父類別 • 在許多時候多重繼承的性質是相當有用。 • 在Java,多重繼承的性質交給介面。

  7. 單一繼承 vs 多重繼承(2/2) • 多重繼承的性質很有用,現實環境中,處處是多重繼承,想想以下情境: 你有一隻手機,它有PDA和GPS的功能,有一天,ToTo跟你借GPS 如果1:你怕ToTo弄壞了,他的媽媽又不會賠,這時,你可以採用『單一繼承』的說法, “不好意思,我有行動電話” 如果2:你不怕ToTo弄壞,因為他弄壞了,你就可以順理成章的成為他的小童星經紀人,好好利用他大賺一筆;則,你可以採用『多重繼承』的說法, “我有一隻手機,它有GPS的功能,借給你”

  8. 介面(1/2) • 介面中定義的方法就像是飲料販賣機上的按鈕

  9. 介面(2/2) • 介面(Interface)是在類別繼承架構中定義類別行為,內含常數和方法宣告,但是並沒有實作程式碼

  10. 介面的定義與實作(1/3) • 定義介面的語法: 修飾字 interface 介面名稱 { //靜態常數定義 //抽象方法宣告 } • 介面定義的例子: interface MyInterface { int i=2;  //已預設使用public、final、static void m();//已預設使用public、abstract }

  11. 介面的定義與實作(2/3) • 實作介面的類別定義語法: 修飾字 class 類別名稱implements 介面名稱 { //包含實作方法的敘述 }

  12. 介面的定義與實作(3/3) • 介面多重繼承的語法: interface 子介面 extends 父介面一, 父介面二, ... { //新增的靜態常數及抽象方法 } • 類別實作多個介面的語法: class 類別名稱 implements 介面一, 介面二, ... { //類別主體敘述 }

  13. 範例1:宣告與使用介面(1/4) • UML類別圖,如下圖所示:

  14. 範例1:宣告與使用介面(2/4) • AreaInterface介面,如下所示: interface AreaInterface { final double PI = 3.1415926; void area(); }

  15. 範例1:宣告與使用介面(3/4) • 接著Circle類別可以實作這個介面,如下所示: class Circle extends Shape implements AreaInterface { ……… public void area() { System.out.println("X座標: " + x); System.out.println("Y座標: " + y); System.out.println("圓半徑: " + r); System.out.println("圓面積: " + PI*r*r); } }

  16. abstract class Shape0601 { public double x; public double y; } interface AreaInterface0601 { final double PI = 3.1415926; void area(); } class Circle0601 extends Shape0601 implements AreaInterface0601 { public double r; public Circle0601(double x, double y, double r) { this.x = x; this.y = y; this.r = r; } public void area() { System.out.println("X座標: " + x); System.out.println("Y座標: " + y); System.out.println("圓半徑: " + r); System.out.println("圓面積: " + PI*r*r); } } class Ch06_01 { public static void main(String [] args) { Circle0601 c = new Circle0601(5.0, 5.0, 8.0); c.area(); System.out.println("PI常數: " + AreaInterface0601.PI); System.out.println("PI常數(以物件方式): " + c.PI); } } 範例1:宣告與使用介面(4/4)

  17. MouseListener • import javax.swing.*; //引用Swing套件 • import java.awt.*; • import java.awt.event.*; //引用處理事件的event套件 • public class MouseEX extends JFrame { • JButton clickME = new JButton("請按我!"); //建立元件 • JLabel lbMouse = new JLabel("滑鼠事件訊息"), //建立顯示訊息的標籤 • lbMouseButton = new JLabel("按下按鍵"); • //以匿名類別的方式實作MouseListener介面, • //宣告回應滑鼠事件的監聽器 • MouseListener mlBtn = new MouseListener() { • private int clickCount = 0, //記錄按鈕被按下次數的屬性 • doubleClickCount = 0; //記錄按鈕被按下次數的屬性

  18. //處理按一下滑鼠按鍵動作的方法 • public void mouseClicked(MouseEvent e) { • if(e.getClickCount() == 2) • doubleClickCount++; • ((JButton) e.getSource()).setText("按下一下 : " + • (clickCount++) + "次 | 連按兩次 : " + doubleClickCount + "次"); • } • //處理滑鼠游標進入元件的方法 • public void mouseEntered(MouseEvent e) { • ((JButton) e.getSource()).setText("滑鼠游標進入按鈕範圍"); • } • //處理滑鼠游標離開元件的方法 • public void mouseExited(MouseEvent e) { • ((JButton) e.getSource()).setText("滑鼠游標離開按鈕範圍"); • }

  19. //處理按下滑鼠按鍵動作的方法 • public void mousePressed(MouseEvent e){ • switch(e.getButton()){ //取得滑鼠被按下的按鍵 • case MouseEvent.BUTTON1 : • lbMouseButton.setText("滑鼠左鍵被按下"); • break; • case MouseEvent.BUTTON2 : • lbMouseButton.setText("滑鼠中間鍵被按下"); • break; • case MouseEvent.BUTTON3 : • lbMouseButton.setText("滑鼠右鍵被按下"); • break; • case MouseEvent.NOBUTTON : • lbMouseButton.setText("沒有滑鼠按鍵被按下"); • break; • } • } • //處理放開滑鼠按鍵動作的方法 • //即使不處理事件但仍須定義空的回應方法 • public void mouseReleased(MouseEvent e){ } • };

  20. //以匿名類別的方式實作MouseMotionListener介面, • //宣告回應滑鼠事件的監聽器 • MouseMotionListener mmlFrame = new MouseMotionListener(){ • public void mouseDragged(MouseEvent e){ //滑鼠拖曳 • lbMouse.setText("滑鼠在視窗範圍內 [拖曳] , 游標位置在 ( " • + e.getX() + ", " + e.getY() + " )"); • } • public void mouseMoved(MouseEvent e){ //滑鼠移動 • lbMouse.setText("滑鼠在視窗範圍內 [移動] , 游標位置在 ( " • + e.getX() + ", " + e.getY() + " )"); • } • }; • MouseEX(){ • Box bxBtn = new Box(BoxLayout.X_AXIS); • bxBtn.add(Box.createHorizontalGlue()); • bxBtn.add(clickME); //加入按鈕元件 • bxBtn.add(Box.createHorizontalGlue()); • Container cp = getContentPane(); //取得內容面版 • Box bxLabel = new Box(BoxLayout.Y_AXIS);

  21. bxLabel.add(lbMouse); //將標籤元件加入Box容器 • bxLabel.add(Box.createVerticalStrut(10)); • bxLabel.add(lbMouseButton); • cp.add(bxBtn); //將包含按鈕元件的Box容器加入內容面版 • cp.add(bxLabel, BorderLayout.SOUTH); • //將包含標籤元件的Box容器加入面版 • clickME.addMouseListener(mlBtn); • //註冊由mlBtn監聽clickME元件的滑鼠事件 • addMouseMotionListener(mmlFrame); • //註冊由mmlFrame監聽視窗的滑鼠移動事件 • setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); • setSize(300, 250); • setVisible(true); • } • public static void main(String args[]) { • new MouseEX(); //產生視窗框架物件 • } • }

  22. MouseAdapter • import javax.swing.*; //引用Swing套件 • import java.awt.*; • import java.awt.event.*; //引用處理事件的event套件 • public class AdapterEX extends JFrame{ • JButton clickME = new JButton("請按我!"); //建立元件 • JLabel lbPos = new JLabel("顯示滑鼠相關訊息"); • MouseListener mlFrame = new MouseListener(){ • public void mouseClicked(MouseEvent e){ • lbPos.setText("在 (" + e.getX() + ", " + e.getY() + ") 按下滑鼠"); • } • public void mouseEntered(MouseEvent e){ • lbPos.setText("滑鼠游標進入視窗"); • } • public void mouseExited(MouseEvent e){ • lbPos.setText("滑鼠游標離開視窗"); • }

  23. //即使不處理事件但仍須定義空的回應方法 • public void mousePressed(MouseEvent e){ } • public void mouseReleased(MouseEvent e){ } • }; • //運用匿名內部類別, 以繼承MouseAdaptor的方式定義監聽器類別, 並完成宣告 • MouseAdapter maBtn = new MouseAdapter(){ • int clickCount = 0; //記錄按鈕被按下次數的屬性 • public void mouseClicked(MouseEvent e){ • ((JButton) e.getSource()).setText( • "按鈕被按了" + (clickCount++) + "次"); • } • public void mouseEntered(MouseEvent e){ • ((JButton) e.getSource()).setText("滑鼠游標進入按鈕範圍"); • } • public void mouseExited(MouseEvent e){ • ((JButton) e.getSource()).setText("滑鼠游標離開按鈕範圍"); • } • };

  24. AdapterEX(){ • Container cp = getContentPane(); //取得內容面版 • Box bxBtn = new Box(BoxLayout.X_AXIS); • bxBtn.add(Box.createHorizontalGlue()); • bxBtn.add(clickME); //將元件加入Box容器 • bxBtn.add(Box.createHorizontalGlue()); • cp.add(bxBtn); //將Box容器加入內容面版 • cp.add(lbPos, BorderLayout.SOUTH); • clickME.addMouseListener(maBtn); • //註冊由maBtn監聽clickME元件的滑鼠事件 • addMouseListener(mlFrame); • //註冊由mlFrame監聽視窗的滑鼠事件 • setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); • setSize(200, 150); • setVisible(true); • }

  25. public static void main(String args[]) { • new AdapterEX(); //產生視窗框架物件 • } • }

More Related