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() {
        System.out.println("父类方法重写)");
    }
}

测试类

public class Demo01Multi {
    public static void main(String[] args) {

    //多态: 父类名称 对象名 = new 子类名称();
    //左侧父类引用,右侧子类对象
    Fu obj = new Zi();
    //调用父类方法,实际是子类重写后的
    obj.method();
    //调用父类特有方法
    obj.methodFu();
    }
}

运行结果

父类方法重写)
父类特有方法

Process finished with exit code 0

三、多态访问成员变量和方法

访问成员变量的两种方式:

1. 直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找。
2. 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找。

上代码

创建父类

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 = 30;
    @Override
    public void method() {
        System.out.println("子类方法");
    }

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


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

创建测试类访问成员变量

public class Demo01MultiField {
    public static void main(String[] args) {
        Fu obj  = new Zi();
        //子类不能覆盖重写父类的成员变量
        //直接通过对象名访问成员变量,等号左边是谁,就优先用谁,没有向上找
        System.out.println(obj.num);//10
        //父类成员变量没有,子类有不能访问。错误写法
//        System.out.println(obj.age);
        System.out.println("============");

        //间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找。
        obj.showNum();//10 覆盖重写前
        obj.showNum();//20 覆盖重写后

    }
}

创建测试类访问成员方法

public class Demo02MultiField {
    public static void main(String[] args) {
        //多态
        Fu obj = new Zi();
        //编译看左,运行看右
        obj.method();//父子都有,优先用子
        obj.methodFu();//父有子没有,向上找父类
//        obj.methodZi();  编译看左,左边父类没有这个方法
    }
}

四、多态的好处

实际开发的过程中,父类类型作为方法形式参数,传递子类对象给方法,进行方法的调用,更能体现出多态的扩展
性与便利。

五、引用类型转换

多态的转型分为向上转型与向下转型两种:
向上转型
向上转型 :多态本身是子类类型向父类类型向上转换的过程,这个过程是默认的。
当父类引用指向一个子类对象时,便是向上转型。
使用格式:
父类类型 变量名 = new 子类类型 ();
如: Animal a = new Cat ();
向下转型
向下转型 :父类类型向子类类型向下转换的过程,这个过程是强制的。
一个已经向上转型的子类对象,将父类引用转为子类引用,可以使用强制类型转换的格式,便是向下转型。
使用格式:
子类类型 变量名 = ( 子类类型 ) 父类变量名 ;
: Cat c = ( Cat ) a ;

上代码

创建父类:

public abstract class Animal {
    public abstract void eat();
}

创建子类1:

public  class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void play(){
        System.out.println("特有方法:猫抓老鼠");
    }
}

创建子类2:

public class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }
    public void play(){
        System.out.println("汪汪汪");
    }
}

创建测试类1:

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

解决方案:用对象的向下转型【还原】。
 */
public class Demo01Main {
    public static void main(String[] args) {
        //向上转型就是父类引用指向子类对象
        Animal animal = new Cat();//本来创建的时候是一只猫
        animal.eat();
//        animal.play();//错误写法

        //向下转型,类似于强制类型转换
        //格式: 子类名称  新对象名 = (子类名称)老对象名
        Cat cat = (Cat)animal;
        //这时可以调用子类特有方法
        cat.play();//特有方法:猫抓老鼠

        //错误的向下转型
        Dog dog = (Dog)animal;//此处未报错
        //dog.eat();//运行时出现异常:ClassCastException:类转换异常


    }
}

创建测试类2:

/*
如何才能知道一个父类引用的对象,本来是什么子类?
格式:
对象 instanceof 类名称
这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例。
 */
public class Demo02Instanteof {
    public static void main(String[] args) {
        //向上转型
        Animal animal = new Cat();
//        Animal animal = new Dog();

        //向下转型
        //判断这个动物是猫是狗
        //如果是狗就转换成狗
        if(animal instanceof Dog){
            System.out.println("这个动物是狗");
            Dog dog = (Dog)animal;
            dog.eat();
            dog.play();
        }
        else if(animal instanceof Cat){
            System.out.println("这个动物是猫");
            Cat cat = (Cat)animal;
            cat.eat();
            cat.play();
        }
        sendAnimal(animal);
    }
    public static void sendAnimal(Animal animal){
        //向下转型
        //判断这个动物是猫是狗
        //如果是狗就转换成狗
        if(animal instanceof Dog){
            System.out.println("这个动物是狗");
            Dog dog = (Dog)animal;
            dog.eat();
            dog.play();
        }
        else if(animal instanceof Cat){
            System.out.println("这个动物是猫");
            Cat cat = (Cat)animal;
            cat.eat();
            cat.play();
        }
    }
}

六、接口,多态的综合案例:笔记本电脑

笔记本电脑:

笔记本电脑(
laptop )通常具备使用 USB 设备的功能。在生产时,笔记本都预留了可以插入 USB 设备的 USB 接口,
但具体是什么 USB 设备,笔记本厂商并不关心,只要符合 USB 规格的设备都可以。
定义 USB 接口,具备最基本的开启功能和关闭功能。鼠标和键盘要想能在电脑上使用,那么鼠标和键盘也必须遵守
USB 规范,实现 USB 接口,否则鼠标和键盘的生产出来也无法使用。

案例分析:

进行描述笔记本类,实现笔记本使用 USB 鼠标、 USB 键盘
USB 接口,包含开启功能、关闭功能
笔记本类,包含运行功能、关机功能、使用 USB 设备功能
鼠标类,要实现 USB 接口,并具备点击的方法
键盘类,要实现 USB 接口,具备敲击的方法
图例:

代码实现:

创建USB接口

public interface USB {
    public abstract void open();
    public abstract void close();
}

创建鼠标类

public class Mouse implements USB{
    @Override
    public void open() {
        System.out.println("打开鼠标");
    }

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

创建键盘类

public class Keyboard implements USB{
    @Override
    public void open() {
        System.out.println("打开键盘");
    }

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

创建电脑类

public class Computer {
    public void putOn(){//打开电脑
        System.out.println("开机");
    }
    public void putOff(){//关闭电脑
        System.out.println("关机");
    }
    public void usbMain(USB usb){//使用USB的方法
        usb.open();
        if(usb instanceof Keyboard){
            Keyboard keyboard = (Keyboard) usb;
            keyboard.play1();
        }
        else if(usb instanceof Mouse){
            Mouse mouse = (Mouse) usb;
            mouse.play2();
        }
        usb.close();
    }
}

创建测试类

public class DemoMain {
    public static void main(String[] args) {
        //创建电脑
        Computer computer = new Computer();
        //打开电脑
        computer.putOn();
        //准备鼠标供电脑使用
//        Mouse mouse = new Mouse();
//        USB  usb = mouse;
        //或者
        USB usb = new Mouse();
//        usb.open();
        computer.usbMain(usb);

      //创建一个键盘
        Keyboard keyboard = new Keyboard();
        computer.usbMain(keyboard);
        //关闭电脑
        computer.putOff();
    }
}

 本篇完结,有喜欢的小伙伴我们可以一起交流讨论技术问题。谢谢支持!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值