Java | 多态

Java的三大特性

java是一个面向对象的语言,所以java也有面向对象语言的三大特性:继承封装多态,任何一个java项目,都会用到这三种特性,所以掌握好这三大特性非常的重要。

多态 (polymorphism)

多态指的是同一个方法调用,由于对象不同可能会有不同的行为,比如,现实生活中同一个方法,有不同的具体实现。

多态的特点

  • 多态是方法的多态,属性没有多态。
  • 多态的存在要有3个必须条件:继承,方法重写,父类引用指向子类对象。
  • 父类引用指向子类对象后,该父类引用调用子类重写方法,比时多态就出现了。
public class Animal {
    public void call() {
        System.out.println("叫----");
    }
    public static void main(String[] args) {
        Animal a1 = new Animal();
        a1.call();
        //父类引用指向子类对象
        Animal a2 = new Cat();
        a2.call();      //输出:喵喵喵喵喵!!!
        //父类引用指向子类对象
        Animal a3 = new Dog();
        a3.call();      //输出:汪汪汪汪汪!!
    }
}
class Cat extends Animal{
    //重写父类的call方法
    @Override
    public void call() {
        System.out.println("喵喵喵喵喵!!!");
    }
}
class Dog extends Animal{
    //重写父类的call方法
    @Override
    public void call() {
        System.out.println("汪汪汪汪汪!!");
    }
}

  上面就是多态的使用,就是父类的引用指向子类对象。

向上转型

父类的引用指向子类对象,这个就是向上转型,是自动类型转换。
  向上转型后的父类引用变量只能调用它编译类型的方法,不能调用它运行时类型的方法,如果要调用子类里面别的方法,只能强制向下转型。上面的代码就是向上转型

向下转型

在子类对象里面有自己的方法,但是引用是父类对象,所以如果想要使用子类的独有方法,必须要转为子类的类型,所以要强制转型,这就是向下转型。
下面就是向下转型:
在cat里面加上一个独有的方法,然后调用这个方法

public class Animal {
    public void call() {
        System.out.println("叫----");
    }
    public static void main(String[] args) {
        Animal a1 = new Animal();
        a1.call();
        //父类引用指向子类对象
        Animal a2 = new Cat();
        a2.call();      //输出:喵喵喵喵喵!!!
        //强制类型转换,从而可以调用cat里面的独有方法
        Cat cat = (Cat)a2;
        cat.eat();
        //父类引用指向子类对象
        Animal a3 = new Dog();
        a3.call();      //输出:汪汪汪汪汪!!
    }
}
 class Cat extends Animal{
    //重写父类的call方法
    @Override
    public void call() {
        System.out.println("喵喵喵喵喵!!!");
    }

    //添加的一个新的方法
    public void eat() {
        System.out.println("吃猫儿粮!");
    }
}

  向下转型的过程中,必须将保证子类继承父类,然后才可以强制转型,不然会报类型转换异常。

多态的内存模型:

  在创建子类对象的时候,会调用构造方法,而构造方法的第一句话永远都是super();来调用父类的构造方法,父类的构造方法调用他的父类的构造方法,一直到object类为止。到现在,他们所有的类的地址都是指向子类的,所以不管再怎么向上转型,向下转型,都是调用的是子类的对象地址,只是在调用的时候,如果子类里面没有该方法,会自动去父类里面找。

下面有一个小例子:

public class HttpServlet {
    //父类里面建两个方法
    public void service() {
        System.out.println("HttpServlet.service()");
        doGet();
    }
    
    public void doGet() {
        System.out.println("HttpServlet.doGet()");
    }
}
//子类里面继承一个方法
public class MyServlet extends HttpServlet{
    @Override
    public void doGet() {
        System.out.println("MyServlet.doGet()");
    }
}
//下面测试
public class Test {
    public static void main(String[] args) {
        HttpServlet httpServlet = new MyServlet();
        httpServlet.service();
    }
}
//输出的结果:
//HttpServlet.service()
//MyServlet.doGet()

  原因是因为httpServlet再调用service()的时候,会隐性的传过去一个this,和一个super,这两个第一个指的是当前对象,后面指的是父类,所以通过调用当前对象的父类的方法的时候,在方法里面再一次调用子类重写的方法的时候,会直接调用子类的方法,而不是调用父类的方法。



关注公众号,随时获取最新资讯

细节决定成败!
个人愚见,如有不对,恳请斧正!

posted @ 2020-03-07 11:05  一点浩然气~  阅读(169)  评论(0编辑  收藏  举报