多态

134 阅读3分钟

概述

面向对象的三大特征:封装性,继承性,多态性。
extends继承,重写,向上转型是Java实现多态的三个必要条件。

  1.  子父类的继承关系或子类实现父类接口
    
  2. 必须有方法的重写
    
  3. 父类引用指向
    

简单理解:
一个对象的多种形态就是多态,比如一名张三是一名教师,那么他是老师的同时还是一名华夏子孙。这就是对象的多态性。

代码世界下的多态

    代码当中体现多态性,其实就是一句话:父类引用指向子类对象。

    格式:
    父类名称  对象名  =  new  子类名称();
    或者:
    接口名称  对象名  =  new  实现类名称();

简单使用一下吧

//先来创建一个父类(注意划分类哦)
public class Fu {
    public void method(){
        System.out.println("父类方法");
    }
    public void methodFu(){
        System.out.println("父类特有方法");
    }
}
//再来创建一个子类
public class Zi extends Fu {
    @Override
    public void method() {
        super.method();
        System.out.println("子类方法");
    }
}
//创建一个测试类
public class Multi {
    public static void main(String[] args) {
        //使用多态的写法
        //左侧父类的引用,指向了右侧子类的对象
        Fu obj = new Zi();

        obj.method();
        obj.methodFu();
    }
}

再向前拓展一点吧《多态中成员变量,成员方法的访问特点》

成员方法:编译看左边,运行还看左边。
成员变量:编译看左边,运行看右边。
//来吧,创建一个父类
public class Fu {

    int num=10;
    public void showNum(){
        System.out.println(num);
    }

    public void method(){
        System.out.println("父类方法");
    }

    public void methodFu(){
        System.out.println("父类特有方法");
    }
}

//再来一个子类
    public class Zi extends Fu{
    int num = 20;
    int age =16 ;

    @Override
    public void showNum() {
        System.out.println(num);
    }

    @Override
    public void method() {
        System.out.println("子类方法");
    }

    public void methodZi(){
        System.out.println("子类特有方法");
    }
}

//测试一下吧
    public class Ff {
    public static void main(String[] args) {
        Fu obj=new Zi();//多态

        obj.method();//父子都有,new的是子,优先用子
        obj.methodFu();//子类没有,父类有,向上找到父类
    }
}

对象的向上、下转型

先来一个向上转型

对象的向上转型,其实就是多态写法:

格式:父类名称  对象名  =  new  子类名称();                   Animal   animal  = new   cat();
    
含义:右侧创建一个子类对象,把它当做父类来看待使用。               创建一只猫,当做动物看待,没问题。
    
注意事项:向上转型一定是安全的。从小范围转向了大范围,从小范围的猫,向上转换成为更大范围的动物。

类似于:
double  num  =  100;//正确,int-->double,自动类型转换。
										
    向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端:
   对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。

再来一个向下转型

1·向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端:
        对象一旦向上转型为父类,那么就无法调用子类原本特有的内容。

解决方案:
        用对象的向下转型【还原】。

2·对象的向下转型,其实是一个【还原】的动作。
格式:子类名称  对象名  =  (子类名称)父类对象;
含义:将父类对象,【还原】成为本来的子类对象。
Animal  animal  =  new Cat();//本来是猫,向上转型成为动物
Cat cat  =(Cat)animal;//本来是猫,已经被当做动物了,还原回来成为本来的猫。
注意事项:
a·必须保证对象本来创建的时候,就是猫,才能向下转型成为猫。
b·如果对象创建的时候本来不是猫,现在非要向下转型成为猫,就会报错。
        // java.lang.ClassCastException.类转换异常
        类似于:    int num =int10.0//可以
 Int  num =int10.5//不可以,精度损失
 

最后通过代码理解一下这一块儿

//先来一个Animal类
    public abstract class Animal {
        public abstract void eat();
    }
//再来一个cat类
    public class Cat extends Animal{
        @Override
        public void eat() {
            System.out.println("猫吃鱼");
        }

    public static void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}
//再来一个dog类
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    public void watchHouse(){
        System.out.println("狗看家");
    }
}
//最后来一个测试类,来看看效果
public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }

    public void watchHouse(){
        System.out.println("狗看家");
    }
}