Java基础——面向对象三大特征之多态性

一、概述

代码当中体现多态性,其实就是一句话:父类引用指向子类对象。
格式:
父类名称 对象名 =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() {
        System.out.println("子类方法!");
    }
}
public class Demo01 {
    public static void main(String[] args) {
        //使用多态的写法
        //左侧父类的引用,指向右侧子类的对象
        Fu obj=new Zi();

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

多态直白点就是左父右字。

二、多态中成员变量的使用特点:

访问成员变量的两种方式:
1、直接通过对象名称访问成员变量,看等号左边是谁,优先用谁,没有则向上找。
父类和子类分别定义一个成员变量10和20,测试类:

 public static void main(String[] args) {
        //使用多态的写法,父类的引用,指向右侧子类的对象
        Fu obj=new Zi();
        System.out.println(obj.num);//10

    }
2、间接通过成员方法访问成员变量,该方法属于谁就用谁,没有则向上找。

在父类当中写方法:

 public void showNum(){
            System.out.println(num);
      }
子类没有覆盖重写就是父类,子类覆盖重写就是子类
  public static void main(String[] args) {
        //使用多态的写法,父类的引用,指向右侧子类的对象
        Fu obj=new Zi();
        System.out.println(obj.num);//10
//子类没有覆盖重写就是父类,子类覆盖重写就是子类
        obj.showNum();//20

    }

三、多态中成员方法的使用特点:

在多态的代码当中,成员方法的访问规则是:
    看new的是谁,就优先用谁,没有则向上找。
口决:编译看左边,运行看右边。

父类:

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;

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

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

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

父类和子类有相同的成员方法method和特有的方法,测试类中的访问特点如下:

public static void main(String[] args) {
        Fu obj=new Zi();//多态

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

        //编译看左,左边是Fu,Fu当中没有methodZi方法,所以编译报错
        //obj.methodZi();//错误写法
    }
对比一下:
成员变量:编译看左边,运行看右边。
成员方法:编译看左边,运行看右边。

四、向上转型:

对象的向上转型,其实就是多态的写法:
格式:父类的名称 对象名=new 子类的名称();
含义:右侧创建一个子类的对象,把他当作父类来看待。
比如:Animal animal=new Cat();
创建一只猫,把他当作动物来看待,没问题。
注意事项:向上转型一定是安全的,从小范围转向大范围,从小范围的猫,向上转成更大范围的动物。

类似于:
double num=100;//int转向成double,自动类型转换

猫吃鱼案例:

public abstract  class Animal {
    public abstract void eat();
}
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
 public static void main(String[] args) {
        Animal animal=new Cat();
        animal.eat();
    }

五、对象的向下转型:

向上转型一定是安全的,没有问题的,正确的,但是也有一个弊端:
对象一旦向上转型为父类,那么就无法调用子类特有的内容,比如猫抓老鼠。
解决方案:
用对象的向下转型还原。

2、对象的向下转型,其实就是一个(还原)的动作。
格式:子类名称 对象名=(子类名称)父类对象;
含义:将父类对象,[还原]成为本来的子类对象。

Animal animal=new Cat();//本来是猫,向上转型为动物
Cat cat=(Cat) animal;//本来是猫,已经被当作动物了,还原成为本来的猫
注意事项:
a、必须保证对象本来创建的时候,就是猫,才能向下转型为猫
b、如果对象创建的时候本来不是猫,现在非要向下转型成为猫,就会报错。
public static void main(String[] args) {
        Animal animal=new Cat();
        animal.eat();

        //向下转型
        Cat cat=(Cat)animal;
        cat.catchmouse();
        //错误向下转型,animal原型是猫
        Dog dog=(Dog)animal;//编译不报错,运行报错
    }

六、笔记本USB接口案例:

创建USB接口:

public interface USB {

    public abstract void open();//打开设备

    public abstract void close();//关闭设备
}

创建键盘、鼠标继承USB:

//鼠标就是一个USB设备
public class Mouse implements USB {
    @Override
    public void open() {
        System.out.println("打开鼠标");
    }

    @Override
    public void close() {
        System.out.println("关闭鼠标");

    }

    public void click(){
        System.out.println("鼠标点击");
    }
}
//键盘也是一个USB设备
public class KeyBoard implements USB {
    @Override
    public void open() {
        System.out.println("打开键盘");
    }

    @Override
    public void close() {
        System.out.println("关闭键盘");
    }

    public void type(){
        System.out.println("键盘输入");
    }
}

笔记本:

public class Computer {

    public void powerOn(){
        System.out.println("笔记本开机");
    }

    public void powerOff(){
        System.out.println("笔记本关机");
    }

    //使用USB设备的方法,使用接口作为方法的参数
    public void useDevice(USB usb){
        usb.open();//打开设备
        if (usb instanceof Mouse){//先判断
            Mouse mouse=(Mouse)usb;//向下转型
            mouse.click();
        }else if (usb instanceof KeyBoard){
            KeyBoard keyBoard=(KeyBoard)usb;//向下转型
            keyBoard.type();
        }
        usb.close();//关闭设备
    }
}

进行测试:

public class DemoMain {
    public static void main(String[] args) {
        //创建一个笔记本电脑
        Computer computer=new Computer();
        computer.powerOn();

        //准备一个鼠标,供电脑使用,使用向上转型,使用多态
        USB usbMouse=new Mouse();
        computer.useDevice(usbMouse);

        //准备一个键盘,向上转型
        KeyBoard keyBoard=new KeyBoard();
        //方法参数是USB类型,传递进去的是实现类的对象
        computer.useDevice(keyBoard);

        computer.powerOff();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值