作者pttnews (PTT新闻)
看板java
标题[问题] 如何帅帅地 downcast ?
时间Tue Aug 11 10:18:13 2015
起因我想要继承某个api framework, 替他增加某些Method, 但是现在做不下去,
所以做一个testcase,
如果我先upcast, 然後要用到ring再downcast, 可以成功, 但是我不喜欢这作法
phone pp = (phone) new android();
pp.run();
((android)pp).ring();
我想要这样做 ,但是在 b= (android)new phone(); 这一行,
会出现 java.lang.ClassCastException: phone cannot be cast to android
android b= (android)new phone();
b.run();
b.ring();
请问版上高手, 如何帅帅地向下转型?
原始马
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class extend {
@Test
public void extendDownCast(){
android b = new android();
if (b instanceof phone) {
b= (android)new phone();
b.ring();
}
}
}
class phone {
public void run() {
System.out.print("run");
}
@Override
public boolean equals(Object o) {
if(!(o instanceof phone)) return false;
return true;
}
}
class android extends phone {
public void ring() {
System.out.print("ring");
}
}
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 49.217.82.145
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/java/M.1439259495.A.03D.html
1F:→ ssccg: new phone()就是new了一个phone,怎麽会是downcast 08/11 10:29
2F:→ ssccg: 除非你还有其他种phone,不然一直用android不就好了 08/11 10:32
3F:→ ssccg: android就继承了phone了,可以run()啊 08/11 10:34
ring 就挂啦
4F:→ swpoker: 父不父,子不子,怎麽看都乱伦阿 08/11 10:43
可以严肃点吗,不要喧闹好吗
听无
5F:→ realmeat: 推乱伦 XD 08/11 10:55
6F:→ swpoker: 父 物件=new 子() 08/11 11:38
7F:→ swpoker: phone没有ring吗?我觉得OO的很怪阿?继承或动态都不是 08/11 11:42
8F:→ swpoker: 乾脆你用annotation好了 08/11 11:42
因为父没有实作ring 甚至根本没有ring,所以phone没有ring 很合理阿!
我再说明一次, 可能我没有表达清楚
我要继承某Class, 并且替他增加Method,
在OO上这作法很合理, 但实际运用时又会碰上CastException,
我真的不懂...所以诚心发问
9F:→ ssccg: 你全程变数类型都用android有问题? android有ring怎麽会挂 08/11 13:00
10F:→ ssccg: 原本需要phone的地方直接传android object进去也不用cast 08/11 13:00
11F:→ ssccg: android is phone, phone is not android 08/11 13:00
12F:→ ssccg: cast只是转reference型态,object new的时候是什麽就是什麽 08/11 13:01
是这样的..
我用org.jsoup 这个framework ,用jsoup来Parse Html File, 也就是把html转object
如何转换呢?
org.jsoup.nodes.Document doc = jsoup.parse(file.getPath());
所以我得到一个 doc Object, 里面有html File全部的tag Object
我想要帮 Document 增加新的Method, 叫做 newM
所以 new Paper() extends Document, Paper里面有 newM
如果我把
org.jsoup.nodes.Document doc = jsoup.parse(file.getPath());
那行改成
Paper paper = (Paper)jsoup.parse(file.getPath());
肯定castException
PS:jsoup.parse只会rerten Document
如果我改成
Document paper = new Paprt(file.getPath());
paper = Jsoup.parse((file.getPath());
Element hardDiv = paper.hade();
都没问题
但是一旦呼叫newM, 就像这样
((Paper)paper).newM();
castException 就会在RunTime时跑出来
我知道如果把 Document 放在Paper class 当成member,不要用extend, 就万事OK
但是我就是想用extend, 该怎麽办呢?
※ 编辑: pttnews (49.217.82.145), 08/11/2015 13:43:05
13F:推 ckvir: 应该要这样吧 08/11 14:36
14F:→ ckvir: Doc d = new Paper() 08/11 14:36
15F:→ ckvir: d = jsoup. parse(... ) 08/11 14:36
16F:→ ckvir: Paper p = (Paper) d 08/11 14:36
17F:→ ckvir: p. newM() 08/11 14:36
我试了 结果...
Paper p = (Paper) d; 这行castException
18F:推 cowbaying: 要不要弄个介面去继承phone 然後再实作ring? 08/11 16:00
可是瑞凡 interface 不能继承 phone, 我也不能做一个interface 让 doc implements
这等於去改别人的framework阿...
※ 编辑: pttnews (49.217.82.145), 08/11/2015 16:28:00
19F:→ ssccg: 回传回来的就是Document不是Paper,只能写个东西去转换 08/11 17:02
20F:→ ssccg: Paper p = new Paper(doc),然後自己把field copy过去 08/11 17:08
您说的没错,工很大,谢谢你,好像目前也只能这麽做了
21F:→ ssccg: 通常是把Paper做成wrapper(你说的doc当成member) 08/11 17:38
22F:→ ssccg: 但是一定要维持type是Document的话工也满大的 08/11 17:38
※ 编辑: pttnews (49.217.82.145), 08/11/2015 17:57:01
23F:→ qrtt1: 别傻的 copy 啊,IDE 有 generate delegate methods 啊 08/11 17:57
谢谢~又多学一招
25F:→ ssccg: 看了一下jsoup source,parse可以传Parse进去,Parse是用 08/11 18:25
26F:→ ssccg: TreeBuilder,然後Document是在initialiseParse new的 08/11 18:26
27F:→ ssccg: 也可以subclass TreeBuilder把doc的type换掉再拿来用 08/11 18:27
HtmlTreeBuilder 的 constructor is not public
只要new 或是 subclass 都会遇到
The constructor HtmlTreeBuilder() is not visible
谢谢你~我学到很多
※ 编辑: pttnews (220.135.143.146), 08/11/2015 22:07:31
28F:→ ssccg: 也不是private,真的要做的话放到同一个package下就可 08/12 14:43
29F:→ swpoker: (BXX)((Object)a) 08/13 10:27