这个问题可以这样说一下:
比如说有三个类:A是根类,B继承了A,C继承了B
现在有一个A的实例a,B的实例b,C的实例c
那么,很明显,c可以造型(转换)为A和B
b可以造型成A,不能造型为C(运行时会出错)
a不可以造型成B或者C但是,如果把c造型为A,得到一个新的实例ac(看起来是A,其实是C)
这个时候如果把ac造型为B,那么是正确的。因为这个时候,ac虽然看起来是A,但事实上是C这么说不知道你明白了没有?
比如说有三个类:A是根类,B继承了A,C继承了B
现在有一个A的实例a,B的实例b,C的实例c
那么,很明显,c可以造型(转换)为A和B
b可以造型成A,不能造型为C(运行时会出错)
a不可以造型成B或者C但是,如果把c造型为A,得到一个新的实例ac(看起来是A,其实是C)
这个时候如果把ac造型为B,那么是正确的。因为这个时候,ac虽然看起来是A,但事实上是C这么说不知道你明白了没有?
import javax.servlet.ServletContext;
import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/**
* <p>Title: HandlerBase abstract Class</p>
* <p>Description: 定义HandlerBase抽象类为导航基类所必须有的接口与功能定义</p>
* <p>Copyright: Copyright (c) 2003</p>
* <p>Company: bcstnet.com.cn</p>
* @author Micro.wu
* @version 1.0
*/
public abstract class HandlerBase{
/**
* 获取URL值
* @return abstract String
*/
protected abstract String getURL(); public void process (ServletContext sc,HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
}
/**
* 转发跳转实现
* @param HttpServletRequest request
* @param HttpServletResponse response
* @throws IOException
* @throws ServletException
*/
public void forward (HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{
_dispatch (request, response);
} /**
* 内部调用实现Dispatch
* @param HttpServletRequest request
* @param HttpServletResponse response
* @throws IOException
* @throws ServletException
*/
protected void _dispatch(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException{ RequestDispatcher rd = request.getRequestDispatcher(getURL());
if (rd == null) {
//write...
}
rd.forward (request, response);
}
}
究竟是怎么样的,能不能给一个正确的答案
public static void main(String[] args) {
A a = new A();
B b = new B();
C c = new C();
a.go();
b.go();
c.go();
A ac = (A)c;
ac.go();
// B ba = (B)a; // 这里a不能造型成B,父类不能造型成子类。
// ba.go();
B bc = (B)c;
bc.go();
// C ca = (C)a; // 同样,这里的a也不能造型为C
// ca.go();
C acc = (C)ac; // 这里,ac可以造型为C,这是因为虽然ac的类型看起来是A(声明的时候定义的类型是A),但事实上ac是从c造型来的,他仍然是C,所以这里没有错。
acc.go(); // 再看下面
A ab = (A)b;
ab.go();
C abc = (C)ab; // 这里,ab虽然看起来是A,但事实上是B,所以把它造型为B的子类C时,就会出错。因为父类不能造型为子类。
abc.go(); }
}
class A {
public void go() {
System.out.println("I am A");
}
}
class B extends A {
public void go() {
System.out.println("I am B");
}
}
class C extends B {
public void go() {
System.out.println("I am C");
}
}现在可以看明白了么?
那么请帮我看看你最上面的例子中:链表类LinkLst(抽象类),单向链表类(实现类),单向节点类(SNode)
this.pre=((SNode)this.pre).next;和return ((SNode)this.pre).data; //(*)
这2句,this.pre是Object 类型,然后强制转换成SNode,请你们解释一下这里为什么又能向下造型
private int x=100;
public int getX(){
return x;
}
}
class Subbie extends SuperClass{
private int y=200;
public int getY(){
return y;
}
}
public class p101{
public static void main(String[] args){
SuperClass superA=new SuperClass(),superB;
Subbie subA=new Subbie(),subB;
//用子类对象作为实际参数传递给应是父类对象的形参
(new p101()).useSubAsSuper(subA);
superB=subA; //把子类对象赋予父类对象
System.out.println("superB.getX():"+superB.getX());
//如果输出中用到方法getY()将出错,如下一句
//System.out.println(superB.getX()+" "+superB.getY());
//subB=superA; //把父类对象赋予子类对象将出错
//把指向子类地址的父类对象superB强制转换成子类对象,并赋予subB
subB=(Subbie)superB;
System.out.println(subB.getX()+" "+subB.getY());
}
public void useSubAsSuper(SuperClass x){ //该方法的形参是父类对象
System.out.println(x.getX()+"!!!!!!!");
}
}
...
}
Class Hongqi extends Car {
public String origin = "china";
...
}Car car = new Hongqi(); //红旗是一种车,不需要说明.
System.out.println( ((Hongqi)car).origin); // 车不一定是红旗,需要告诉编译器到红旗类中去找origin,所以需要转.但是如果car是奔驰时,编译能过,运行出错.
看了你的程序。是这样的:
你的单向链表类中,head元素肯定是在其他地方赋值的。而且肯定是一个SNode。
因此,head从开始就是个SNode,虽然在链表类中定义为object,但是其中放的是个SNode。
SNode的next也是个SNode,所以,很明显,单向链表类中的pre各个元素实质上都是SNode。
因此,看看我上边的范例程序就很明显了,这里是可以这样造型的。另外,造型错误通常编译器是无法发现的,所以应该慎重使用。