Re: [問題] 繼承與物件使用的問題?
我也要來賺 PO 文數……
※ 引述《henry4343 (henry)》之銘言:
: public Class Main {
: private Father obj;
: private void function_A {
: obj = new Child_A;
: obj.string_A //這行認不到
: }
: private void function_B {
: obj = new Child_B;
: obj.arrayList_B //這行認不到
: }
: }
: public Class Main {
: Child_A a;
: Child_B b;
: private void function_A {
: a = new Child_A;
: a.string_A //OK
: }
: private void function_B {
: b = new Child_B;
: b.arrayList_B //OK
: }
: }
老實說我看不懂你上面兩個例子的不同處,如果你在其他地方根本
不會用到 obj 的話,幹嘛特地把他宣告成成員變數,而不是直接在 function_A
或 function_B 裡宣告成相對應的 Child_A 和 Child_B 就好?
如果你只是單純不想要重覆寫相同的共用程式碼的話,那麼你的 Child
本來就可以呼叫 Father 裡的東西了,沒必要特地宣告他的型別為 Father。
Java 是 static type 的程式語言,他的目的就是要在一定程度上保證你
不會呼叫到不存在的函式會存取到不存在的變數。
對,Ruby / Python 這類動態型別語言可以達到你要的功能,像下面這樣寫:
class Father
end
class ChildA < Father
def str_A
"AAA"
end
end
class ChildB < Father
def str_B
"BBB"
end
end
x = ChildA.new
puts x.str_A
x = ChildB.new
puts x.str_B
但如果你把 x = ChildB.new 給拿掉的話,執行的時候就會爆掉,而 Java 則
是強制你一開始就定義好 x 到底有哪些東西可以用,例如如果你宣告成 Father x,
那 x 就只能用 Father 裡存在的東西,不管他實際上的物件是 ChildA 或 ChildB。
相反的,如果你宣告成 ChildB x,那 x 就只能呼叫 Father + ChildB 裡面的東西,
其他的都不能用。
如果你真的很堅持要把 x 宣告成 Father 但又硬要使用 ChildB 裡的東西,你可以這
樣做(有的時候會需要,但大部份的時候出現這種狀況代表你的程式架構一開始就有
問題):
Father x = new ChildB
(ChildB) x).strB
只是相同的,這種情況下如果你的 x 實際上指到的是 ChildA 的物件,編譯器不會抱
怨,但執行的時候會爆炸,這麼一來你等於自廢編譯器幫你檢查錯誤的武功,不如直
接去用動態型別的語言比較快。XD
另外,還有一個問題要思考的是,就算你不想要寫重覆的程式碼,覺得很多程式碼可
以共用,你也要問自己一個很重要的問題:
他 真 的 是 繼 承 關 係 嗎 ?
舉例來講,我維護過一個前人寫的 Java 系統,在這個系統裡我們常常需要印
出目前的進度 % 數,於是就有人這樣寫:
class CommonUtils {
public void printProgress(int current, int total) {
// 印出進度條
}
}
class SomeA extends CommonUtils {
public void doSomethingA() {
printProgress(....)
}
}
class SomeB extends CommonUtils {
public void doSomethingB() {
printProgress(....)
}
}
對,這可以動也省下重覆的程式碼,但你仔細想的話,printProgress 根本就和
SomeA 或 SomeB 沒有任何關係,CommonUtils 不會用到 SomeA 或 SomeB 的任
何狀態,反之亦然,換句話說 CommonUtils 根本就是單純的 statless 工具類別。
這個時候,為什麼不直接把 printProgress 宣告成 static,而讓 SomeA 和 SomeB
直接呼叫就好呢?
class CommonUtils {
public static void printProgress(int current, int total) {
// 印出進度條
}
}
class SomeA {
public void doSomethingA() {
CommonUtils.printProgress(....)
}
}
繼承確實可以省下重覆的程式碼,不過用的時候最好還是要思考清楚,我們要省下的
程式碼是不是真的有需要用繼承的方式來做……
--
~ 白馬帶著她一步步地回到中原。白馬已經老了,只能慢慢地走,
'v' Brian Hsu 但終是能回到中原的。江南有楊柳、桃花,有燕子、金魚……
// \\ ( 墳 墓 )
/( )\ 但這個美麗的姑娘就像古高昌國人那樣固執。 【白馬嘯西風】
^`~'^
http://bone.twbbs.org.tw/blog 『那都是很好很好的,可我偏不喜歡。』
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.109.19.84
※ 編輯: brianhsu 來自: 140.109.19.84 (05/22 15:53)
推
05/22 16:10, , 1F
05/22 16:10, 1F
推
05/22 20:56, , 2F
05/22 20:56, 2F
加上去了 XD
※ 編輯: brianhsu 來自: 1.160.217.194 (05/22 21:24)
推
05/22 23:52, , 3F
05/22 23:52, 3F
推
05/23 10:28, , 4F
05/23 10:28, 4F
討論串 (同標題文章)