作者brianhsu (坟墓)
看板java
标题Re: [问题] 继承与物件使用的问题?
时间Wed May 22 15:49:36 2013
我也要来赚 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)
1F:推 PsMonkey:你这赚文章数也赚的太辛苦... XD 05/22 16:10
2F:推 kewang:printProgress忘了加static XD 05/22 20:56
加上去了 XD
※ 编辑: brianhsu 来自: 1.160.217.194 (05/22 21:24)
3F:推 a60301:推用心,这篇写得不错www 05/22 23:52
4F:推 dou0228:因为有人认为不用继承就是不懂 OO 05/23 10:28