Re: [問題] 多型的修飾詞?

看板java作者 (十年一夢)時間10年前 (2013/12/28 02:43), 編輯推噓0(002)
留言2則, 2人參與, 最新討論串5/5 (看更多)
※ 引述《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
不過如果實際用途是這樣應該還是interface比較好吧
12/29 00:27, 2F
文章代碼(AID): #1IlSetGx (java)
文章代碼(AID): #1IlSetGx (java)