Download presentation
Presentation is loading. Please wait.
1
Interfaces and Packages
Lecturer:楊昌樺
2
Outline 抽象(Abstract) 巢狀類別(Nested Classes) Your Turn 介面(Interfaces)
抽象類別(Abstract Classes) 抽象方法(Abstract Methods) 巢狀類別(Nested Classes) 靜態巢狀類別(static nested classes) 內部類別(inner classes) Your Turn 介面(Interfaces) 套件(Packages)
3
抽象(Abstract) 真實世界 Java 程式中
食物為例,應沒見過食物這個東西,一般見到的都是紅蘿蔔、蘋果、巧克力這種真實東西,所以食物可以代表一種抽象概念。 Java 程式中 lava.lang.Number 類別代表數字的抽象概念,所以 Number 是一個抽象類別(Abstract Class) 抽象類別只能被其他類別繼承,不能被實體化 如果企圖對 abstract class 進行實體化動作,將會在編譯時期發生錯誤
4
抽象類別(Abstract Classes)
定義 類別內部有尚未定義實作內容的方法,則此類別必須宣告為 abstract class,該方法需宣告為 abstract method 宣告 abstract class Number { … } 特性 宣告為 abstract 的類別無法產生實體。例如,您無法對上述類別做: Number myNumber = new Number(); // 會發生錯誤
5
抽象方法(Abstract Methods)
沒有實作內容的 methods (即沒有 method body) abstract classes 至少必須提供一個完整或部分程式碼的 method 若一個 abstract class 都只有宣告 abstract methods 的話,那就必須改宣告成介面(interface) 抽象類別主要是用來在繼承上,繼承的 subclass 必須將 abstract classes 中的 abstract methods 實作內容補上
6
抽象類別(Abstract Classes)
範例: GraphicsObject 是一個抽象類別,提供所有 subclass 必備的成員變數與 methods Point Origin; // 重心 moveTo(); // 移動 abstract draw(); // 繪出 GraphicsObject abstract class Rectangle Circle Line
7
抽象類別(Abstract Classes)
public abstract class GraphicsObject { protected Point Origin; public GraphicsObject() { Origin = new Point(0,0); } public void moveTo(int newX, int newY) { Origin.x = newX; Origin.y = newY; public abstract void draw(); // abstract method protected void finalize() throws Throwable { Origin = null; super.finalize();
8
抽象類別(Abstract Classes)
class Rectangle extends GraphicsObject { public int Length; public int Height; public Rectangle() { Length = 0; Height = 0; } public Rectangle(int Left, int Top, int Len, int High) { Origin.x = Left; Origin.y = Top; Length = Len; Height = High; public void draw() { // 必須填上 abstract method 的實作內容 System.out.println("Rectangle has been drawn at \n" + "(" + Origin.x + ", " + Origin.y + ") - (" + (Origin.x+Length) + ", " + Origin.y + ")\n" + "(" + Origin.x + ", " + (Origin.y+Height) + ") - (" + (Origin.x+Length) + ", " + (Origin.y+Height) + ")");
9
抽象類別(Abstract Classes)
class Circle extends GraphicsObject { public int Radius; public Circle() { Radius = 0; } public Circle(int a, int b, int r) { Origin.x = a; Origin.y = b; Radius = r; public void draw() { // 必須填上 abstract method 的實作內容 System.out.println("Circle has been drawn at \n" + "Center: (" + Origin.x + ", " + Origin.y + ")\n" + "Radius: " + Radius);
10
抽象類別(Abstract Classes)
class Line extends GraphicsObject { public Point End; public Line() { End = new Point(0,0); } public Line(int a, int b, int c, int d) { Origin.x = a; Origin.y = b; End = new Point(c, d); public Line(Point p1, Point p2) { Origin.x = p1.x; Origin.y = p1.y; End = new Point(p2.x, p2.y); public void draw() { // 必須填上 abstract method 的實作內容 System.out.println ("Line: (" + Origin.x + ", " + Origin.y + ") - (" + End.x + ", " + End.y + ")");
11
抽象類別(Abstract Classes)
測試主程式:DrawDemo.java public class DrawDemo { public static void main(String[] args){ Rectangle rectObj = new Rectangle(1, 2 ,5 ,5); Circle cirObj = new Circle(1, 1, 5); Line lineObj = new Line(1, 1, 2, 2); rectObj.draw(); cirObj.draw(); lineObj.draw(); }
12
巢狀類別(Nested Classes) Java 中 可以將一個類別變成另一個類別的成員 如下的程式碼稱為巢狀類別
class EnclosingClass { … class ANestedClass { }
13
巢狀類別(Nested Classes) 巢狀類別(Nested Classes) 強制限制住兩個類別之間的關連性
使用時機:當某一個類別在另一個類別中才具有意義的時候,如:只有在文字元件(text component)之內,文字游標才具有意義。因此文字游標(巢狀類別)定義於文字元件(類別)之內應是一個很好的選擇。 巢狀類別可以存取外層類別的任何成員,即使是宣告成 private 的成員。
14
巢狀類別(Nested Classes) 巢狀類別 如同其他成員一樣,巢狀類別也可以宣告成 static
宣告為 static 的巢狀類別,稱為靜態巢狀類別(static nested class) 非 static 的巢狀類別,稱為內部類別(inner class) class EnclosingClass { ... static class StaticNestedClass { } class InnerClass {
15
巢狀類別(Nested Classes) 靜態巢狀類別(static nested class)
與 class variables, class method 一樣都是屬於類別,而非屬於物件 與 class method 一樣,在靜態巢狀類別中也不能直接使用實體變數(instance variables) 反應的是兩個類別之間的關連性 宣告 存取範圍 類別特性 繼承宣告 public protected (空白) private static abstract final extends 父類別名稱 implements 父介面名稱 class 類別名稱
16
巢狀類別(Nested Classes) 靜態巢狀類別(static nested class)
使用前不用 new 即可使用。 可擁有任何 static 成員。 這個Class也是在Load進JVM的記憶體後就存在 主類別名稱.內部類別名稱.方法(參數); 如 Line2.Data.showData("Hi...");
17
巢狀類別(Nested Classes) 內部類別(inner class)
與 instance variables, instance methods 一樣都是屬於物件 反應的是兩個類別實體物件之間的關連性 宣告 存取範圍 類別特性 繼承宣告 public protected (空白) private abstract final extends 父類別名稱 implements 父介面名稱 class 類別名稱
18
巢狀類別(Nested Classes) 內部類別(inner class)
InnerClass 的實體只能存活在 Enclosing Class 物件之內 InnerClass 可以直接使用 EnclosingClass 物件的實體變數與 methods(包括宣告成 private 的) class EnclosingClass { ... class InnerClass { }
19
巢狀類別(Nested Classes) 內部類別(inner class) new一個內部物件 使用前必須先 new 才能使用
不可以擁有 static 成員,但可有 static final 成員。 可以繼承 static 成員。 new一個內部物件 物件instance.類別名稱 = 物件instance.new 類別名稱(參數); 如 myLine2.Style = myLine2.new CStyle();
20
巢狀類別(Nested Classes) Example: Line2.java import java.lang.Math;
public class Line2 { public Point Start; public Point End; public CStyle Style = null; public Line2() { Start = new Point(0,0); End = new Point(0,0); } public Line2(int a, int b, int c, int d) { Start = new Point(a, b); End = new Point(c, d); public Line2(Point p1, Point p2) { Start = new Point(p1.x, p1.y); End = new Point(p2.x, p2.y);
21
巢狀類別(Nested Classes) public class CStyle { int Thickness; int Pattern;
int Color; public CStyle() { Thickness = 0; Pattern = 0; Color = 0; } public CStyle(int th, int pt, int cl) { Thickness = th; Pattern = pt; Color = cl; public String draw() { return "Thickness: " + Thickness + "\nPattern: " + Pattern + "\nColor: " + Color;
22
巢狀類別(Nested Classes) public void CreateStyle(int th, int pt, int cl) {
Style = new CStyle(th, pt, cl); } public void draw() { System.out.println ("Line: (" + Start.x + ", " + Start.y + ") - (" + End.x + ", " + End.y + ")"); public double area() { return Math.sqrt(Math.pow(End.x - Start.x,2) + Math.pow(End.y - Start.y,2)); protected void finalize() throws Throwable { Start = null; End = null; super.finalize();
23
巢狀類別(Nested Classes) Line2 的測試主程式:DrawLine2.java
public class DrawLine2 { public static void main(String[] args) { Line MyLine = new Line(1,1,5,5); MyLine.draw(); System.out.println("Length = " + MyLine.area()); MyLine.CreateStyle(3,3,3); System.out.println(MyLine.Style.draw()); }
24
Your Turn 假設給定以下類別:Parcel.java,試著在此類別中寫一個 main() 來測試其中所有巢狀類別的方法。
public class Parcel { class Contents { private int i = 11; public int value() { return i; } } class Destination { private String label; Destination(String whereTo) { label = whereTo; } String readLabel() { return label; } static class Data { static void showData(String data){ System.out.println(data); }
25
介面(Interface) 定義 宣告 作用 一段只有常數與函式宣告,但沒有函式實作的程式碼。
[public] interface 介面名稱 [extends 父介面名稱] 作用 讓某個功能,不論由誰實作,都能夠有相同的函式名稱,傳入值,傳出值,與存取範圍。
26
介面(Interface) 定義介面 public interface Stockwatcher {
final String sunTicker = “SUNW”; final String oracleTicker = “ORCL”; final String ciscoTicker = “CSCO”; void valueChanged(String tickerSymbol, double newValue); … }
27
介面(Interface) 介面(interface)與抽象類別(abstract class)
介面裡不能實作任何 methods;不過,abstract class 可以 一個類別可以同時實作多個介面;但一個類別只能有一個 superclass(Java 不支援多重繼承) 介面不屬於類別階層架構的一份子。毫不相干的類別,也可以實作相同介面 因為多重繼承會有問題,但實際上又有多重繼承的需要,所以發明了 interface,作為折衷的替代方案。
28
介面(Interface) 注意事項 如果某介面繼承另一個介面,則 subclass 能從 superclass 繼承到的只有常數與函式宣告而已。 介面一旦公佈出去,開始供大家使用後,就請盡量不要更改。因為一旦更改,那些已經使用此介面的程式會因無法實作新功能,而不能執行。 如果真要更改,請宣告新介面,其它人就可以決定要實作一個介面或兩個介面都實作。 優點 快速知道如何使用此class,省去閱讀大量文件之時間
29
介面(Interface) 範例: GraphicsObject Rectangle Circle Line Paintable
Point Origin; // 重心 moveTo(); // 移動 abstract draw(); // 繪出 GraphicsObject Rectangle Circle Line Point Origin; moveTo(); abstract draw(); Point Origin; moveTo(); abstract draw(); Point Origin; moveTo(); abstract draw(); void fillColor (int Color); double getArea(); Paintable
30
介面(Interface) 範例:Paintable.java public interface Paintable {
public void fillColor(String Color); public double getArea(); }
31
介面(Interface) 範例:Rectangle2.java
public class Rectangle2 extends GraphicsObject implements Paintable { public int Length; public int Height; public Rectangle2() { Length = 0; Height = 0; } public Rectangle2(int Left, int Top, int Len, int High) { Origin.x = Left; Origin.y = Top; Length = Len; Height = High;
32
介面(Interface) public void draw() {
System.out.println("Rectangle has been drawn at \n" + "(" + Origin.x + ", " + Origin.y + ") - (" + (Origin.x+Length) + ", " + Origin.y + ")\n" + "(" + Origin.x + ", " + (Origin.y+Height) + ") - (" + (Origin.x+Length) + ", " + (Origin.y+Height) + ")"); } public void fillColor(String Color) { System.out.println("Rectangle has been filled with " + Color); public double getArea() { return Length * Height;
33
套件(Package) 定義 宣告套件的方法 套件示意圖 性質相似之類別的集合 在原始檔案的第一行寫下: package 套件名稱;
Graphics 套件 XXX.java YYY.java ZZZ.java package Graphics; Class XXX { } package Graphics; Class YYY { } package Graphics; Class ZZZ { }
34
套件(Package) 套件目的 套件命名習慣 防止兩位程式師取了相同的類別名稱 將公司的網際網路名稱倒過來寫
範例:package tw.com.pcschool.Graphics 有時會再加上部門名稱 範例:package tw.com.pcschool.rd.Graphics
35
套件(Package) 在 Java 中規定,.class 檔案真正存在的地方必須與套件的命名結構相對應 tw com pcschool
Point.java Point.class package tw.com.pcschool.Graphics; class Point { ….. } tw com pcschool Graphics Point.class
36
套件(Package) package 與目錄結構 使用 javac 之參數
所有屬於 packagename 類別庫的 .class 檔案都必須儲存在 packagename 資料夾下 packagename 必須唯一,類別庫名稱可使用句點分隔不同層次的資料夾名稱 例: package tw.com.pcschool.Graphics package tw.com.pcschool.rd.Graphics 使用 javac 之參數 語法:javac –classpath user-class-path –d des-path xxx.java -classpath:指定使用者自訂類別路徑,至存放類別目錄的上一層 -d:指定編譯完成之 .class 檔案產生路徑 若指定路徑中的名稱包含空白,必須使用雙引號括起來
37
套件(Package) Source 與 Class 檔的管理 Source 檔與 Class 不一定要放在同一個目錄下
38
註:套件(Package)Command版
編譯時能夠抓到我們自訂的套件,要用 classpath 參數告訴 javac 到哪裡去找我們要的套件 在 javac 後方直接用 –classpath 參數 javac –classpath .;c:\jdk1.3\lib;c:\mylib\tw\com \pcschool\Graphics Point.java 使用 jar 壓縮檔案 語法:jar cvf jar-file-name –C directory-path/ . 在 cmd 視窗中,輸入 jar,並參閱其說明 使用類別庫 語法:java –classpath .;user-class-path main-class 用分號「;」區隔多個類別庫 類別庫可為目錄路徑、zip 檔案或 jar 檔案 目錄擺放結構一定要正確!
39
用eclipse作套件jar檔 使用Fat Jar的plug-in 將plug-in目錄放在eclipse目錄
可在命令列執行eclipse –clean 讓plug-in反映上去 成功後以後Project按右鍵會多 Build Fat Jar選項 選擇Finish即可 別的專案創造時選Library 別的程式import其class
40
Your Turn 製作套件及使用練習: 試著將此課堂中所講解的程式碼:GraphicsObject.java、Point.java、Circle.java、Rectangle.java 以及 Line.java 全部都 整合到 tw.com.Graphics 套件中 最前面加 package tw.com.Graphics; 因為要跨專案,所以別程式用到的Point, Circle, Rectangle等類別要變成public 創造新專案裡面放 DrawDemo 程式 一開始要import tw.com.Graphics.*; 確認可以正確執行 DrawDemo裡面的main程式
Similar presentations