Re: [問題] 多型的修飾詞?
※ 引述《broodstare (交給C4就對了)》之銘言:
:
: 我想請問的觀念是:
:
: 在main裡,我將new Derived2()指派給了Base2 b,雖然原先class Base2裡的method
:
: foo 是設為private,但就多型來說,我應該也把Drived2的public method foo給了b
:
: ,理當b.foo()應該是可以執行的吧?
:
: (ps. 紅色的部份就是不能執行)
:
: 謝謝!
:
: --
: ※ 發信站: 批踢踢實業坊(ptt.cc)
: ◆ From: 140.115.110.189
: ※ 編輯: broodstare 來自: 140.115.110.189 (12/27 11:28)
: → lovdkkkk:就多型來說, 是由 Base2 的觀點來看你要執行的 function 12/27 12:04
: → lovdkkkk:沒有把 Drived2 的方法給 b (反向繼承?) 這種事 @@ 12/27 12:05
: → jej:這幾個class的耦合性還是很高..不是學習泛型的好例子.. 12/27 12:37
: → jej:你的疑問 只要單純寫一個 new Base2() 然後看看能不能foo() 12/27 12:39
: → swpoker:要由上而下~而非由下而上 12/27 13:55
:
: 謝謝各位版大們回答!! (很抱歉因為今天下午忙碌,沒法即時回應)
:
: 我想自己也有點混亂了,那我想再請問一些追加的相關問題:
:
:
: Base2 b = new Derived2();
:
: 就這個範例,是個好的寫法嗎? 是因為super-class Base2 與sub-class Derived2
:
: 的method有所重疊(即便他們的modifier不同),導致這不是個很好例子?
:
: 所以要竟量避開這種寫法嗎?
:
:
: 謝謝Q___Q
: ※ 編輯: broodstare 來自: 140.115.5.114 (12/27 23:08)
: 推 PsMonkey:B b = new D() 這沒啥問題,很多時候都是這樣用 12/28 00:33
我蠻好奇是什麼導致你衍生出你在追加問題所提到的看法。
假如 Base2 b = new Derived2();(包括 Base2 是個 interface 的例子)是個不好
的寫法而去避免,那麼你自己寫出來的碼"幾乎"不會有多型的應用。
許多教學都把 reflection(或是根本沒有 reflection)放在很後面,我自己覺得
要說明多型使用 reflection 其實會比較好一點(比較有說服力,我個人覺得)。
這種把所有東西寫在單一 source file 裡的例子,除了比較無法體會其涵義外,
有時覺得有誤導的成分在裡頭。
我來寫範例的話,大概會是這樣:
先寫一個 class(本來應該是 interface,為了比較接近你目前讀的範例,故寫成
class)
MathOp.java
-------------
public class MathOp {
public double evaluate(double oprand1, double oprand2) {
return oprand1 * oprand2 * 0;
}
}
編譯且確認得到 MathOp.class
接著寫這個 class:
Computer.java
---------------
public class Computer {
public static double compute(MathOp op, double val1, double val2) {
return op.evaluate(val1, val2);
}
public static void main(String[] args) {
MathOp op = new MathOp();
if (args.length > 0) {
try {
op = MathOp.class.cast(Class.forName(args[0]).newInstance());
}
catch (Exception e) {
// I don't care why it fail
}
}
System.out.println(compute(op, 8, 7));
}
}
編譯並確認產出 Computer.class。
先執行看看 java Computer,輸出是 0.0,沒問題。
接著再寫以下兩個 class:
Add.java
-------------
public class Add extends MathOp {
public double evaluate(double oprand1, double oprand2) {
return oprand1 + oprand2;
}
}
Multiply.java
--------------
public class Multiply extends MathOp {
public double evaluate(double oprand1, double oprand2) {
return oprand1 * oprand2;
}
}
編譯 javac Add.java Multiply.java 得到 Add.class, Multiply.class。
你先想看看,你在寫 Add.java 與 Multiply.java 之前就已經寫好 Computer.java
並編譯成 Computer.class 且執行過,之後 Computer.java 與 Computer.class
檔案都沒有修改過。
現在你執行
java Computer Add
java Computer Multiply
分別得到
15.0
56.0
甚至你可以回過頭來去編輯 MathOp.java 然後再編譯 MathOp.java(同樣不會改變
到 Computer.java/Computer.class):
public class MathOp {
public double evaluate(double oprand1, double oprand2) {
return oprand1 * oprand1 + oprand2 * oprand2;
}
}
java Computer
輸出
113.0
如果你看不懂 Computer.java 內的 main method 在搞什麼,你可以幫 Add.java
加上一個 main method:
public class Add extends MathOp {
public double evaluate(double oprand1, double oprand2) {
return oprand1 + oprand2;
}
public static void main(String[] args) {
System.out.println(Computer.compute(new Add(), 8, 7));
}
}
編譯然後執行 java Add,得到輸出 15.0。
這整個例子的重點在於 Computer.java 在尚未有 Add/Multiply 這兩個 class
之前,在修改 MathOp.java 之前就已經編譯好(它的碼是固定),看起來是做固定
的一件事,但實際上它所做的事不是固定的,而是看實際上執行時他所拿到的
MathOp 是什麼而定。我認為這就是 polymorphism 的精神。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 1.172.188.13
※ 編輯: sbrhsieh 來自: 1.172.188.13 (12/28 02:45)
→
12/28 16:36, , 1F
12/28 16:36, 1F
→
12/29 00:27, , 2F
12/29 00:27, 2F
討論串 (同標題文章)