作者TonyQ (骨头)
看板java
标题Re: [J2SE] 多型与转型
时间Sat Feb 16 21:20:57 2008
※ 引述《forris (乔巴)》之铭言:
: class Father{
: String name = "Father";
: String getName(){
: return name;
: }
: String greeting(){
: return "class Father";
: }
: }
: class Son extends Father{
: String name = "Son";
: String greeting(){
: return "class Son";
: }
: void foo(){
: System.out.println((Son)this).greeting();
: System.out.prtinln((Father)this).greeting();
这两行code是手打的? 错误不少orz
System.out.println(( (Son)this).greeting());
System.out.println( ((Father)this).greeting());
: }
: }
: 要问印出来的讯息
: ((Son)this).greeting() 是指 Son 类别的 greeting(), 所以讯息为 class Son.
: ((Father)this).greeting() 是指 Son 类别的 greeting(), 但是为 Father 型别,
: 出现的讯息不应该跟着转型後的型别走吗?
: 怎麽不是 class Father 而是 class Son ?
这是overridding(覆盖)的问题
子类别继承父类别的时候如果复写掉父亲的方法,
则由子类别产生的物件实体就只会具有子类别所时做的方法.
(如果需要使用父类别的方法,只能在子类别内透过super关键字呼叫。)
如果你单纯记实体不实体的话,可能会翻船。
比方说下列的状况
void foo(){
Father father = ((Father) this);
Son son = ((Son) this);
System.out.println(father.greeting());
System.out.println(son.greeting());
System.out.println(father.name);
System.out.println(son.name);
}
请问後面两个name印出来的会是什麽? :)
这个就自己试试看吧
这跟method的差异是method是直接被覆盖,
member的话,只是被子member给「遮掩」而已。
(有点类似local variable跟member variable需要透过this区隔的差异)
所以当我在son内如果有需要取得father的greeting()的时候
要尽量透过super.greeting() 来处理,而避免透过转型。
同样的要存取父类别name也是透过super.name来处理
System.out.println(super.name);
最後再说一个有趣的问题,
如果原po所认为的跟着型态成立,
当Father是abstract Class, 没有实做greeting(),
转型回Father再呼叫greeting() , 这时候就会有问题了,
会连带的影响abstract Class不能藉由转型来操作。
所以还是随时搞懂自己再用那个类别,类别有哪些属性跟方法,
按照它提供给你的文件去处理,按照不同类别的功能去处理,
不要任意去猜测它应该提供给你什麽,这样会比较好。
这样也可以保持他的黑盒子特性~
--
I am a person, and I am always thinking .
Thinking in love , Thinking in life ,
Thinking in why , Thinking in worth.
I can't believe any of what ,
I am just thinking then thinking ,
but worst of all , most of mine is thinking not actioning...
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.117.162.40