Download presentation
Presentation is loading. Please wait.
1
Ch01 物件與類別複習 物件導向系統實務
2
本章大綱 以實例介紹物件導向的概念 以文字問答敘述複習物件類別的概念
3
第一部份 以實例介紹物件導向的概念
4
類別與物件(1/3) 實際世界:有一家吸塵機器人的製造工廠,工廠生產會自動行走的吸塵器,工廠生產了1000台機器。我家買了一台,你家也買了一台 物件:每一台吸塵機器人都有自己的實體,實體內包含有自己的名字、顏色…等特性值,例如:我家的吸塵機器人、你家的吸塵機器人、還有其他的998台吸塵機器人 類別:包含屬性(特性)、建構子、方法(動作)等的設定,例如:生產線上的模子
5
類別與物件(2/3) 主程式: 類別:吸塵機器人 class ourWorld
{ public static void main(String [] args) { 吸塵機器人 robot1 = new 吸塵機器人(“toto”, “銀灰色”); 吸塵機器人 robot2 = new 吸塵機器人(“月餅”, “紅色”); } 類別:吸塵機器人 class 吸塵機器人 { //屬性 String name; String color; //建構子 吸塵機器人(String name, String color) { this.name = name; this.color = color; } //方法 void 吸塵(){…}
6
類別與物件(3/3) name:String color:String 吸塵機器人 吸塵():void name:String = toto
robot1:吸塵機器人 name:String=月餅 color:String=紅 robot2:吸塵機器人 instanceOf
7
類別-如何建立一個類別(1/4) 類別的建立有兩個方法: 自己一行一行程式的去完成 善用已經存在的類別去組合完成
8
類別-如何建立一個類別(2/4) 實際世界:吸塵機器人的模子是這樣做的,吸塵機器人需要有三個技術結合: 吸塵器 感應器(偵測是否撞到墻?)
自動行走(類似玩具小汽車,會利用電力來前進) 工廠的設計部門當然不會自己設計這三個技術,他們會花錢購買這三個技術,再將這三個技術結合,再補加上一些設計,一個吸塵機器人的模子就完成了! 以物件導向的概念來看: 父類別:包含吸塵器、感應器、自動行走等類別 子類別:吸塵機器人 繼承:子類別繼承父類別,即子類別是新產物,而父類別是舊(已)有的技術 但是,JAVA是單一繼承,所以,在父類別中,吸塵器應該是吸塵機器人真正的父親;而感應器和自動行走,我們可以視為其輔助功能,我們以介面來實現 介面:類似類別,但是其方法沒有實作
9
類別-如何建立一個類別(3/4) 繼承關係: name:String color:String 吸塵機器人 吸塵():void
name:String = toto color:String=銀灰 robot1:吸塵機器人 name:String=月餅 color:String=紅 robot2:吸塵機器人 instanceOf 吸塵器 <interface>感應器 感應 ():void <interface>自動行走 繼承關係:
10
類別-如何建立一個類別(4/4) 類別:吸塵器 class 吸塵器 { void 吸塵() {…} } 介面:感應器
interface 感應器 { void 感應(); 介面:自動行走 interface 自動行走 {void 走(); 類別:吸塵機器人 class 吸塵機器人 extends 吸塵器 implements 感應器, 自動行走 { //屬性 String name; String color; //建構子 吸塵機器人(String name, String color) { this.name = name; this.color = color; } //方法 void 吸塵(){…} void 感應() {撞到東西原地打轉;} void 走() { 直直的走; }
11
多載(1/3) 實際世界:吸塵機器人已雛型完成,因為是智慧型的機器人,它會自己判斷現在地上是灰塵,還是可樂,還是固體加上液體。
這在物件導向程式設計中就是 多載:在一個類別中,有多個同名的方法,方法的回傳及參數個數或型式不同,例如: void 吸塵(液體) void 吸塵(固體) void 吸塵(液體,固體)
12
多載(2/3) 類別:吸塵機器人 class 吸塵機器人 extends 吸塵器 implements 感應器, 自動行走 { //屬性
{ //屬性 String name; String color; //建構子 吸塵機器人(String name, String color) { this.name = name; this.color = color; } //方法 void 吸塵(液體){…} void 吸塵(固體){xxx} void 吸塵(液體, 固體) {ccc} void 感應() {撞到東西原地打轉;} void 走() { 直直的走; }
13
多載(3/3) name:String color:String 吸塵機器人 吸塵(液體):void 吸塵(固體):void
name:String = toto color:String=銀灰 robot1:吸塵機器人 name:String=月餅 color:String=紅 robot2:吸塵機器人 instanceOf 吸塵器 吸塵():void <interface>感應器 感應 ():void <interface>自動行走
14
多型(1/3) 實際世界:工廠發現所設計的機器人打掃結果不理想,設計部門要做部份的修改,再生產吸塵機器人二世代。設計修改的部份是「走」,設計師發現原來的行動方向是類似「直線前進」,現在要做三種機器人: 機器人-A型:如乒乓球般撞到墻,會有一個回彈角度 機器人-B型:每次撞到墻,會產生一個亂數斜率,再以此斜率前進 機器人-C型:每次以旋轉方式前進
15
多型(2/3) name:String color:String 吸塵機器人 吸塵(液體):void 吸塵(固體):void
name:String = toto color:String=銀灰 robot1:吸塵機器人 name:String=月餅 color:String=紅 robot2:吸塵機器人 instanceOf 吸塵器 吸塵():void <interface>感應器 感應 ():void <interface>自動行走 機器人二世代-A { 直直的走;} 機器人二世代-B { 亂數斜率的走;} 機器人二世代-C { 螺旋型的走;} 多型(2/3)
16
多型(3/3) 類別:二世代-A class 機器人二世代-A extends 吸塵機器人 { void 走() { 直直的走; } }
類別:二世代-B class 機器人二世代-B extends 吸塵機器人 { 亂數斜率的走; } 類別:二世代-C class 機器人二世代-C extends 吸塵機器人 { 螺旋的走; } 如果在main方法中告一個物件x1如下: 機器人二世代-B x1 = new 機器人二世代-B(); 問題:x1怎麼走? 如果在main方法中宣告一個物件x2 如下: 吸塵機器人 x2 = new 機器人二世代-C(); 問題: x2怎麼走?
17
第二部份 以文字問答敘述複習物件類別的概念
18
類別與物件 程式之主體類別,其名稱必須與其儲存檔案之主檔名相同
主程式起始位置之字串public static void main(String [] args) 物件之屬性或成員以句點“.”描述之 2018/12/8 2018/12/8 18
19
Q1: 類別與物件 class myNumber { int number; } class Ex2_1_1 {
public static void main(String[] args) { myNumber a; a= new myNumber(); a.number= 5; System.out.println("a.number= "+a.number); a.number = 5 2018/12/8 2018/12/8 19
20
Q2: 原始型態與參考型態 原始型態為系統預設資料型態,如int、char、float、long、boolean等,可直接給予資料
參考資料為以設計之類別為資料型態,附以變數之型態,所以參考型態變數應先產生新物件,再給予資料 2018/12/8 2018/12/8 20
21
Q2: 原始型態與參考型態 class myNumber { int i; } class Ex2_2_1 {
public static void main(String[] args) { int j; myNumber a; j=3; a = new myNumber(); a.i=5; System.out.println("j="+j); System.out.println("a.i="+a.i); J=3 a.I=5 2018/12/8 2018/12/8 21
22
Q3: 生存物件之變數(屬性) 當以某類別為資料型態之物件尚未建立時,其中所宣告之屬性,均無法存取。
如果要使用這些屬性,就必須先產生其所屬之物件 2018/12/8 2018/12/8 22
23
Q3: 生存物件之變數(物件屬性) class MyClass1 { int i; } class Ex2_4_1 { int j;
public static void main(String[] args) { i = 3; j = 5; System.out.println("i="+i); System.out.println("j="+j); 發生錯誤, I與j為類別中的屬性,必須先宣告一物件變數,才能使用其中的屬性 2018/12/8 2018/12/8 23
24
Q3: 生存物件之變數(物件屬性) class MyClass1 { int i; } class Ex2_4_2 { int j;
public static void main(String[] args) { MyClass1 a = new MyClass1(); Ex2_4_2 b = new Ex2_4_2(); a.i=3; b.j=5; System.out.println("i="+a.i); System.out.println("j="+b.j); I=3 J=5 2018/12/8 2018/12/8 24
25
Q4: 類別之變數(類別屬性) 於類別中宣告之變數,若加上static,該變數即謂類別變數,否則是生存物件變數
類別變數可直接使用,不必先產生物件 類別變數是同一類別中所有物件所共有,而不是屬於某個物件 2018/12/8 2018/12/8 25
26
Q4: 類別之變數 class MyClass1 { static int i; } class Ex2_5_1 {
static int j; public static void main(String[] args) { MyClass1.i = 3; j = 5; System.out.println("i="+MyClass1.i); System.out.println("j="+j); I=3 J=5 2018/12/8 2018/12/8 26
27
Q4: 類別之變數 class MyClass1 { static int i; } class Ex2_5_2 {
static int j; public static void main(String[] args) { MyClass1 a = new MyClass1(); Ex2_5_2 b = new Ex2_5_2(); MyClass1 c = new MyClass1(); a.i=3; b.j=5; System.out.println("i="+a.i); System.out.println("j="+b.j); System.out.println("c.i="+c.i); System.out.println("MyClass1.i="+MyClass1.i); System.out.println("Ex2_5_2.j="+j); I=3 J=5 c.I=3 MyClass1.I=3 Ex2_5_2.j=5 2018/12/8 2018/12/8 27
28
Q5: 方法 類別中,所宣告之方法,類似一般高階語言的副程式 使用方法時,須先產生新物件再執行各新物件內之方法
使用( 呼叫)方法時,要注意傳入參數之一致性 參數型態一致 參數數量一致 宣告方法時,若無回傳資料,必須前置void,若有回傳資料,要註明回傳資料型態,且要有return 2018/12/8 2018/12/8 28
29
Q5: 方法 class Study { private int credit=0;
void addcredit(int i) { credit += i; } int totalcredit() { return credit; } } class Ex2_6_1 { public static void main(String[] args) { Study joe = new Study(); Study george = new Study(); joe.addcredit(12); george.addcredit(9); joe.addcredit(6); george.addcredit(3); System.out.println("joe studied:"+joe.totalcredit()+"credites"); System.out.println("george studied:"+george.totalcredit()+"credites"); Joe studied 18 credites George studied 12 credites 2018/12/8 2018/12/8 29
30
Q6: 物件方法 當方法所屬之物件尚未產生之前,該方法是無法執行的 2018/12/8 2018/12/8 30
31
Q6: 物件方法 class Mynumber { public int number;
public void setnumber(int i) { number = i; } public int getnumber() { return number; } } class Ex2_7_1{ public static void main(String[] args) { Mynumber.setnumber(3); System.out.println("number= "+Mynumber.number); 發生錯誤, 方法所屬的物件尚未產生 2018/12/8 2018/12/8 31
32
Q6: 物件方法 class Mynumber { public int number;
public void setnumber(int i) { number = i; } public int getnumber() { return number; } } class Ex2_7_2{ public static void main(String[] args) { Mynumber a= new Mynumber(); a.setnumber(3); System.out.println("number= "+a.getnumber()); Number=3 2018/12/8 2018/12/8 32
33
Q7: 類別方法 類別方法於宣告時須前置static 類別方法不同於物件方法,類別方法可直接使用
類別方法不可以直接呼叫物件方法,因為物件方法要先有物件存在,呼叫時要加上物件.方法() 物件方法可以直接呼叫類別方法 2018/12/8 2018/12/8 33
34
Q7: 類別方法 class Mynumber { public static int number;
public static void setnumber(int i) { number = i; } public static int getnumber() { return number; } } class Ex2_8_1{ public static void main(String[] args) { Mynumber.setnumber(3); System.out.println("number= "+Mynumber.number); Number=3 第2行的static不可以省,因為此程式中都沒有出現物件的宣告 2018/12/8 2018/12/8 34
35
Q8: 建構子 建構子之名稱必須與所屬類別之名稱相同 在沒有定義建構子的類別時,編繹器會自動設給一個沒有形式參數的建構子
建構子無回傳資料,內容無return,宣告中亦不得前置void 建構子主要功能是在所屬類別產生新物件時作初始化動作 2018/12/8 2018/12/8 35
36
Q8: 建構子 class Mynumber { int number; Mynumber() {
System.out.println("Here is Constructor"); number = 3; } int getnumber() { return number; } class Ex2_9_1 { public static void main(String[] args) { Mynumber a = new Mynumber(); System.out.println("Here is main: "+a.getnumber()); Here is Constructor Here is main: 3 2018/12/8 2018/12/8 36
37
Q9: 方法多載 方法多載之定義為:在同一類別內,有兩個(含)以上之方法,具有相同之名稱,但其宣告之類型或參數個數卻不相同
其目的是因應不同的傳遞資料,讓方法更有彈性 2018/12/8 2018/12/8 37
38
Q9: 方法多載 class adder{ int add(int i,int j){return i+j;}
double add(double i,double j){return i+j;} } class Ex2_10_1{ public static void main(String[] args){ int n; double x; adder a= new adder(); n=a.add(2,3); x=a.add(2.2, 3.3); System.out.println("int n = " + n); System.out.println("double x = " + x); Int n = 5 Double x = 5.5 2018/12/8 2018/12/8 38
39
Q9: 方法多載 class adder{ int n; double x; adder(int i, int j){ n= i+j;
System.out.println("use_int= "+n); } adder(double i, double j){ x= i+j; System.out.println("use_double= "+x); class Ex2_10_2{ public static void main(String[] args){ adder use_int= new adder(2,3); adder use_double= new adder(2.2, 3.3); Use_int=5 Use_double=5.5 2018/12/8 2018/12/8 39
40
Q10: public(公用)/private(私用)存取設定
當變數無前置任何存取設定時,僅允許在,同一package存取應用 2018/12/8 2018/12/8 40
41
Q10: public(公用)/private(私用)存取設定
class Mynumber { int i; public int j; } class Ex2_11_1 { public static void main(String[] args) { Mynumber a = new Mynumber(); a.i = 10; a.j = 20; System.out.println("a.i = "+a.i+", a.j = "+a.j); a.I=10,a.j=20 2018/12/8 2018/12/8 41
42
Q10: public(公用)/private(私用)存取設定
class Mynumber { int i; private int j; } class Ex2_11_2 { public static void main(String[] args) { Mynumber a = new Mynumber(); a.i = 10; a.j = 20; System.out.println("a.i = "+a.i+", a.j = "+a.j); J是一個private的屬性,只有類別Mynumber內有宣告的方法,才可以在建立物時取用,現在我們卻要在另一個類別的方法main中取用一個private的物件屬性,當然不行 2018/12/8 2018/12/8 42
43
Q10: public(公用)/private(私用)存取設定
class Mynumber { int i; private int j; } class Ex2_11_2 { private int k = 10; public static void main(String[] args) { Mynumber a = new Mynumber(); a.i = 10; Ex2_11_2 b = new Ex2_11_2(); //a.j = 20; System.out.println("a.i = "+a.i); System.out.println("b.k = " +b.k); a.I = 10 b.k = 10 2018/12/8 2018/12/8 43
44
Q10: public(公用)/private(私用)存取設定
class Mynumber { private int number; public void setnumber(int i) { number=i;} public int getnumber() { return number; } } class Ex2_11_3 { public static void main(String[] args) { Mynumber a = new Mynumber(); a.setnumber(10); System.out.println("result= "+a.getnumber()); Result=10 2018/12/8 2018/12/8 44
45
Q11: this 之應用 This之意義為所屬類別之代名詞 This可用於建構子間之呼叫
不能造成建構子遞迴 2018/12/8 2018/12/8 45
46
Q11: this 之應用 class Mynumber { private int number;
public Mynumber(int i){ this.number= i; } public int getnumber(){return number;} class Ex2_12_1 { public static void main(String[] args) { Mynumber a = new Mynumber(10); System.out.println("result= "+a.getnumber()); Result=10 第4行的this不加一樣可以 2018/12/8 2018/12/8 46
47
Q11: this 之應用 class Mynumber { private int number;
public Mynumber(int i){ this.number= i; } public Mynumber(int j, String s){ this(j); } public int getnumber(){ return number; } } class Ex2_12_2 { public static void main(String[] args) { Mynumber a = new Mynumber(10, "stringtest"); System.out.println("result= "+a.getnumber()); Result=10 2018/12/8 2018/12/8 47
48
Q12: 物件陣列 class Mynumber { private int number;
public void setnumber(int i) { number=i;} public int getnumber() { return number; } } class Ex2_13_1 { public static void main(String[] args) { int[] intArray; Mynumber[] MyArray; intArray = new int[2]; intArray[0] = 5; intArray[1] = 10; System.out.println("intArray[0]= "+intArray[0]); System.out.println("intArray[1]= "+intArray[1]); MyArray = new Mynumber[2]; MyArray[0] = new Mynumber(); MyArray[1] = new Mynumber(); MyArray[0].setnumber(15); MyArray[1].setnumber(20); System.out.println("MyArray[0].number= "+MyArray[0].getnumber()); System.out.println("MyArray[1].number= "+MyArray[1].getnumber()); }} intArray[0]=5 intArray[1]=10 MyArray[0].number=15 MyArray[1].number=20 2018/12/8 2018/12/8 48
49
Q13: 巢狀類別應用 類別的定義也可以放置於另一個類別之內,甚至是某個方法之內;這種類別稱為內部類別(巢狀類別) 2018/12/8
49
50
Q13: 巢狀類別應用-成員類別 class Ex2_14_1 { int i,j; private MyMember memb;
class MyMember { int m,n,o; MyMember() { i = 2; Ex2_14_1.this.j = 4; m = 12; this.n = 14; MyMember.this.o = 16; } public int getO() { return o; } } public Ex2_14_1() { memb = new MyMember(); System.out.println("m= "+memb.m + ","+"n= "+memb.n + ","+ "o= "+memb.getO()); } public int getJ() { return j; } public static void main(String[] args) { Ex2_14_1 a = new Ex2_14_1(); System.out.println("i= "+a.i +","+ "j= "+a.getJ()); } } M=12, n=14, o=16 I=2, j=4 2018/12/8 2018/12/8 50
51
Q13: 巢狀類別應用-成員類別 class MyClass { public class Pubmemb { private int i;
public Pubmemb() { i = 5; } public int getI() { return i; } } private class Primemb{ public Primemb() { i = 10; } class Ex2_14_2 { public static void main(String[] args) { MyClass a = new MyClass(); MyClass.Pubmemb b = a.new Pubmemb(); System.out.println("In Pubmemb i= "+b.getI()); In Pubmemb I =5 2018/12/8 2018/12/8 51
52
Q14: 巢狀類別應用-區域類別 定義於方法內的類別,稱為區域內部類別 使用區域類別時要注意其生存期,不在生存期範圍,是無法執行的
區域類別在宣告時不宜前置public、private、protected等存取設定 2018/12/8 2018/12/8 52
53
Q14: 巢狀類別應用-區域類別 class Ex2_15_1 { int i; public Ex2_15_1() {
class MyLocal { public MyLocal(){ Ex2_15_1.this.i = 5; i= 10; } MyLocal L = new MyLocal(); System.out.println("i of Local: "+L.i); public static void main(String[] args) { Ex2_15_1 m = new Ex2_15_1(); System.out.println("i of Ex2_15_1: "+m.i); I of Local: 10 I of Ex2_15_1: 5 2018/12/8 2018/12/8 53
54
Q15: 繼承—父類別與子類別 Java的繼承為「單一繼承」
當一類別繼承自另一類別,前者為子類別Sub Class),後者為父類別(Super Class) 子類別繼承父類別所擁有之內涵 單一繼承有先天的缺點,這個缺點由介面來補足,如此Java有多重繼承的優點,卻沒有多重繼承的缺點 Java的繼承以類別為單位,使用extends關鍵字 2018/12/8 2018/12/8 54
55
public void setNumber(int i) { number = i; } public int getNumber() {
class MyNumber{ private int number; public void setNumber(int i) { number = i; } public int getNumber() { return number; class E extends MyNumber {} class Ex3_1_1 { public static void main(String[] args) { E a = new E(); a.setNumber(5); System.out.println("a=: "+a.getNumber()); A=5 2018/12/8 2018/12/8 55
56
Q16: 繼承-產生不同物件關係 在繼承下,父類別或子類別各自所產生的新物件是各自獨立的,物件屬性亦是互不干擾的 2018/12/8
56
57
public void setNumber(int i) { number = i; }
class MyNumber { private int number=5; public void setNumber(int i) { number = i; } public int getNumber() { return number; } } class E1 extends MyNumber {} class E2 extends MyNumber {} class Ex3_1_2 { public static void main(String[] args) { E1 a1 = new E1(); E2 a2 = new E2(); a1.setNumber(10); System.out.println("The number of a1 is: "+a1.getNumber()); System.out.println("The number of a2 is: "+a2.getNumber()); The number of a1 is: 10 The number of a2 is: 5 2018/12/8 2018/12/8 57
58
Q17: 繼承-類別屬性 類別屬性是指類別屬性之前置有static而成為類別屬性
在繼承中,由父類別或子類別所產生的新物件,其類別屬性是指同一個變數;所以當任何一個物件更改了類別屬性值時,所有物件所看到的此物件值都是新值 2018/12/8 2018/12/8 58
59
private static int number=5;
class MyNumber { private static int number=5; public void setNumber(int i) { number = i; } public int getNumber() { return number; } } class E1 extends MyNumber {} class E2 extends MyNumber {} class S extends E2 {} class Ex3_1_3 { public static void main(String[] args) { E1 a1 = new E1(); E2 a2 = new E2(); S s = new S(); s.setNumber(20); System.out.println("The number of a1 is: "+a1.getNumber()); System.out.println("The number of a2 is: "+a2.getNumber()); System.out.println("The number of s is: "+s.getNumber()); The number of a1 is: 20 The number of a2 is: 20 The number of s is : 20 2018/12/8 2018/12/8 59
60
Q18: 繼承 子類別雖然有其本身自己之內容,但因是繼承自父類別,故亦具有父類別內容 2018/12/8 2018/12/8 60
61
public void setNumber(int i) { number = i; }
class MyNumber { private int number; public void setNumber(int i) { number = i; } public int getNumber() { return number; } } class MyString extends MyNumber { private String string; public void setString(String s) { string = s; } public String getString() { return string; } class Ex3_1_4 { public static void main(String[] args) { MyString a = new MyString(); a.setNumber(5); a.setString("I am in the SubClass"); System.out.println("The number of a is: "+a.getNumber()); System.out.println("The string of a is: "+a.getString()); The number of a is: 5 The string of a is: I am in the SubClass 2018/12/8 2018/12/8 61
62
Q19: Public/Protected/Private 存取限制
當變數前置private時,該變數不得被其他類別採用;在繼承過程中,以private宣告的父類別之物件成員,不被子類別所繼承。不被繼承的成員存在子類別物件中的父類別物件內,只是子類別物件無權使用 2018/12/8 2018/12/8 62
63
class myNumber {public int number;} class E extends myNumber {
public void setNumber(int i) {number = i;} public int getNumber() {return number;} } class Ex3_2_1 { public static void main(String[] args) { E a = new E(); a.setNumber(5); System.out.println("The number of a is: "+a.getNumber()); The number of a is: 5 如果第1行的public改成private可不可以? 2018/12/8 2018/12/8 63
64
Q20: super 與 this 關鍵字super為父類別之代名詞 關鍵字this為自己本身類別之代名詞
2018/12/8 2018/12/8 64
65
class E extends myNumber{ int number= 10;
class myNumber { int number= 5; } class E extends myNumber{ int number= 10; public int getsuperNumber() {return super.number;} public int getthisNumber() {return this.number;} class Ex3_3_1 { public static void main(String[] args) { E a = new E(); System.out.println("The myNumber_number of a is: " +a.getsuperNumber()); System.out.println("The E_number of a is: "+a.getthisNumber()); The myNumber_number of a is : 5 The E_number of a is : 10 2018/12/8 2018/12/8 65
66
Q21: super()用於建構子 關鍵字super()可視為父類別之建構子 2018/12/8 2018/12/8 66
67
myNumber (int number) {this.number = number;}
class myNumber { private int number; myNumber (int number) {this.number = number;} public int getNumber() { return number; } } class E extends myNumber { E() {super(5);} class Ex3_3_2 { public static void main(String[] args) { E a = new E(); System.out.println("number= "+a.getNumber()); Number=5 2018/12/8 2018/12/8 67
68
Q22: super() 子類別繼承父類別時,系統將會於子類別的第一列,自加上一行super(),即自動呼叫父類別之建構子
建構子是不被繼承的 在建立子類別物件時,父類別的預設建構子會先被呼叫,接著子類別的建構子才會被呼叫 This()和super()只能擇一使用,並且必須出現在建構子的第一個敘述 2018/12/8 2018/12/8 68
69
A() { System.out.println("A's constructor");} } class B extends A {
class A { A() { System.out.println("A's constructor");} } class B extends A { B() { System.out.println("B's constructor");} class C extends B { C() { System.out.println("C's constructor");} class Ex3_3_3 { public static void main(String[] args) { C c = new C(); A’s constructor B’s constructor C’s constructor 2018/12/8 2018/12/8 69
70
Q23: final 之應用 當類別前置final時,該類別將不允許被繼承 2018/12/8 2018/12/8 70
71
class E extends myNumber{ int number= 10;
final class myNumber { int number= 5; } class E extends myNumber{ int number= 10; public int getsuperNumber() {return super.number;} public int getthisNumber() {return this.number;} class Ex3_4_1 { public static void main(String[] args) { E a = new E(); System.out.println("The myNumber_number of a is: " +a.getsuperNumber()); System.out.println("The E_number of a is: "+a.getthisNumber()); 編譯錯誤,第4行中類別E不可以繼承自myNumber,因為它是final 2018/12/8 2018/12/8 71
72
Q24: abstract之應用 類別前加置abstract,該類別為抽象類別 抽象類別不得用於產生物件 2018/12/8
72
73
abstract class myNumber { private int number = 5;
public int getNumber() { return number; } } class Ex3_5_1 { public static void main(String[] args) { myNumber a = new myNumber(); System.out.println(a.getNumber()); 2018/12/8 2018/12/8 73
74
Q25: 抽象方法 方法若前置abstract,即所謂抽象方法 抽象方法沒有程式碼內容 抽象方法一定是會被覆蓋的方法
定義抽象方法時,不能同時使用final、static、private宣告 2018/12/8 2018/12/8 74
75
abstract class myNumber { public int number = 5 ;
public abstract int getNumber(); } class E extends myNumber { public int getNumber() {return number;} class Ex3_5_3 { public static void main(String[] args) { E a = new E(); System.out.println("the number of a= "+a.getNumber()); The number of a = 5 2018/12/8 2018/12/8 75
76
Q26: 抽象類別之應用 抽象類別用於被繼承,再由繼承之類別產生新物件 只要有一個方法(或以上)定義為抽象方法,則該類別為抽象類別
於繼承類別時,如果父類別中有抽象方法時,子類別中必有方法會完成抽象方法處理程序(程式),才可以建立物件 抽象類別的目的,主要是「制定固定的訊息接收管道」 2018/12/8 2018/12/8 76
77
abstract class myNumber { private int number = 5;
public int getNumber() { return number; } } class E extends myNumber {} class Ex3_5_2 { public static void main(String[] args) { E a = new E(); System.out.println("the number of a= "+a.getNumber()); The number of a = 5 2018/12/8 2018/12/8 77
78
Q27: interface 所謂介面,即是前置interface;是Java保有多重繼承特性的機制 介面內之方法,均是抽象方法(無程式碼)
介面不得用於產生新物件,介面是用於被實作(implement)的 當介面被類別承作時,須使用關鍵字implements,其他之繼承,要使用關鍵字extends 一個類別可同時承作一個(含)以上之介面,且使用介面內之方法時,在方法中必須加置程式碼 介面之承作,僅約定繼承之行為名稱,並不約束繼承行為;一般類別之繼承,是繼承父類別之行為 2018/12/8 2018/12/8 78
79
interface myITF1 {public void f();}
interface myITF2 {public void g();} class A implements myITF1,myITF2 { public void f() {System.out.println("In myITF1");} public void g() {System.out.println("In myITF2");} } class Ex3_6_1 { public static void main(String[] args) { A a = new A(); a.f(); a.g(); In myITF1 In myITF2 2018/12/8 2018/12/8 79
80
interface myITF1 {public void f();} class myNumber {
public void g() {System.out.println("In myNumber");} } class A extends myNumber implements myITF1 { public void f() {System.out.println("In myITF1");} class Ex3_6_2 { public static void main(String[] args) { A a = new A(); a.f(); a.g(); In myITF1 In myNumber 2018/12/8 2018/12/8 80
81
Q28: 物件的型別轉換 子類別物件也屬於父類別物件 使用父類別的參照變數指向子類別的物件時,無法使用該參照變數取用子類別定義的成員
2018/12/8 2018/12/8 81
82
public static void main (String [] args) Fish a = new Fish();
Class EX8_12 { public static void main (String [] args) Fish a = new Fish(); Vertebrate b = new Fish(); Animal c = new Fish(); // Fish d = new Vertebrate(); //錯誤 System.out.println(“a=“ + a); System.out.println(“b=“ + b); System.out.println(“c=“ + c); } Class Animal{ } Class Vertebrate extends Animal { } Class Fish extends Vertebrate { } 輸出結果是:三個不同的位址, 而其中資料架構是以fish, 但是父類別的參照變數不可以使用子類別定義的成員 2018/12/8 2018/12/8 82
83
public void f() {System.out.println("In f of myClass1"); }
class myClass1 { public void f() {System.out.println("In f of myClass1"); } class myClass2 extends myClass1 { public void g() {System.out.println("In g of myClass2"); class Ex3_7_2 { public static void main(String[] args) { myClass1 a = new myClass2(); a.f(); In f of myClass1 2018/12/8 2018/12/8 83
84
public void f() {System.out.println("In f of myClass1"); }
class myClass1 { public void f() {System.out.println("In f of myClass1"); } class myClass2 extends myClass1 { public void g() {System.out.println("In g of myClass2"); class Ex3_7_2 { public static void main(String[] args) { myClass1 a = new myClass2(); a.g(); 編譯錯誤,看不到g() 2018/12/8 2018/12/8 84
85
Q29: 方法的覆蓋(overridung) 子類別可以重新定義物件屬性,也可以重新定義物件方法,重新定義物件方法稱為方法的覆蓋
在方法覆蓋時,下列各項必須和父類別定義的方法相同: 方法的回傳型別 方法名稱 形式參數列中的型別及順序 覆蓋舊方法時,新定義的方法可以呼叫舊方法 使用final 宣告的父類別之物件方法不能被覆蓋 2018/12/8 2018/12/8 85
86
{ public static void main(String [] args) { new WolfDog().bark();
Class EX8_17 { public static void main(String [] args) { new WolfDog().bark(); new Doberman.bark(); new Dog().bark(); } Class Dog { void bark() {System.out.print(“汪汪”); } } Class WolfDog extends Dog { void bark() { System.out.println(“汪~汪~嗚~”); } } Class Doberman extends Dog { void bark() { super.bark(); System.out.println(“~汪汪汪~”); 汪~汪~嗚~ 汪汪~汪汪汪~ 汪汪 2018/12/8 2018/12/8 86
87
Q30: 多重形態(polymorphism)
多型是指「使用相同的訊息呼叫,可以進行不同的功能操作」 若子類別物件轉換成父類別物件,呼叫其方法時,若該方法為子類別定義的方法,則不允許被呼叫;若該方法被子類別覆蓋,則呼叫子類別的覆蓋方法。 不論參照的型別為何,呼叫方法時,呼叫最新的覆蓋方法 在異質集合中,若呼叫父類別被覆蓋的方法,則每個方法的反應會因為覆蓋的關係而有所不同 2018/12/8 2018/12/8 87
88
public void f() {System.out.println("In myClass1"); }
class myClass1 { public void f() {System.out.println("In myClass1"); } class myClass2 extends myClass1 { public void f() {System.out.println("In myClass2"); class Ex3_7_1 { public static void main(String[] args) { myClass1 a = new myClass2(); a.f(); In myClass2 2018/12/8 2018/12/8 88
89
{ public static void main(String [] args) { Dog[] d = new Dog[3];
Class EX8_19 { public static void main(String [] args) { Dog[] d = new Dog[3]; d[0] = new WolfDog(); d[1] = new Doberman(); d[2] = new Dog(); for (int I=0; I<d.length; I++) d[I].bark(); } Class Dog { void bark() {System.out.print(“汪汪”); } } Class WolfDog extends Dog { void bark() { System.out.println(“汪~汪~嗚~”); } } Class Doberman extends Dog { void bark() { super.bark(); System.out.println(“~汪汪汪~”); 汪~汪~嗚~ 汪汪~汪汪汪~ 汪汪 2018/12/8 2018/12/8 89
Similar presentations