多态的向上转型和向下转型
多态的三大必要条件:有继承,有方法重写,父类引用指向子类对象。
public class Animal {
String str;
public void voice(){
System.out.println("普通动物叫声!");
}
}
class Cat extends Animal{
public void voice(){
System.out.println("喵喵喵");
}
public void catchMouse(){
System.out.println("抓老鼠");
}
}
class Tiger extends Animal {
public void voice(){
System.out.println("哇哇哇");
}
}
//****************
public class Test {
public static void testAnimalVoice(Animal c){
c.voice();
if(c instanceof Cat){
((Cat) c).catchMouse();
}
}
public static void main(String[] args) {
Animal a = new Cat(); //向上转型
Cat a2 = (Cat)a; //向下转型,若父类对象希望使用子类方法,在此对象属于子类实例对象时,可强制转型进行调用
testAnimalVoice(a);
// Animal b = new Tiger();
// Cat a2 = (Cat)b;
// a2.catchMouse();-->程序不会报错,编译器只认申明的局部变量Animal,但是如果要运行的话就会报错
}
}
多态的内存分析
public class HttpServlet{
public void service(){
System.out.println("HttpServlet.service()");
doGet();
}
public void doGet(){
System.out.println("HttpServlet.doGet()");
}
public static void main(String[] args){
HttpServlet s = new MyServlet();
s.service(); //问题是调用的doGet是父类中的还是子类中重写的????
}
}
class MyServlet extends HttpServlet{
public void doGet(){
System.out.println("MyServlet.doGet");
}
}
------运行结果------
HttpServlet.service()
MyServlet.doGet
内存图如下所示:
观看上面的内存图,其实每个方法中都会存在两个隐形的参数也就是(this,super),顾名思义,super如同上面的箭头一级一级往上面的父类调用,而要特别注意的一点是this永远指向当前对象!意思就是无论是HttpServlet还是MyServlet中方法的this都是指向这个大框框住的整个对象,this引用的是当前对象,他们所指的地址都是S1的地址adasd。