面向对象的多态性(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 Multi {
    public static void main(String[] args) {
        //使用多态的写法
        //左侧父类的引用,指向了右侧子类的对象
        Fu obj = new Zi();

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

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

  • 访问成员变量的两种方式;
    1、直接通过对象名称访问成员变量,看等号左边是谁,优先用谁,没有则向上找
    2、间接通过成员方法访问,该方法属于谁,优先用谁,没有则向上找

  • 代码示例:
    父类:

public class Fu {
    int num = 10;

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

子类:

public class Zi extends Fu {
    int num = 20;
    int age = 16;

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

主函数:

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

        //子类没有覆盖重写,就是父:10
        //子类如果覆盖重写,就是子:20
        obj.showNum();
    }
}

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

  • 在多态的代码当中,成员方法的访问规则是:

  •   看new的是谁,就优先用谁,没有则向上找
    口诀:编译看左边,运行看右边

  • 对比一下:
    成员变量:编译看左边,运行还看左边
    成员方法:编译看左边,运行看右边

  • 代码示例:
    主函数:

public class Multi {
    public static void main(String[] args) {
        Fu obj = new Zi();	多态
       
        obj.method();	//父子都有,优先用子
        obj.methodFu();	//子类没有,父类有,向上找父类
        
        //编译看左边,左边是Fu,Fu当中没有methodZi方法,所以编译报错
//         	obj.methodZi();	//错误写法!
    }
}

使用多态的好处

使用多态图示
多态好处

对象的向上转型

向上转型
对象向上转型

  • 代码示例:

动物类:

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

猫:

public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

主函数:

public class Main {
    public static void main(String[] args) {
        //对象向上转型,就是:父类引用指向子类对象
        Animal animal = new Cat();
        animal.eat();
    }
}

对象的向下转型

  • 向上转型一定是安全的,没有问题的,正确的。但是也有一个弊端:
    对象一旦向上转型为父类,那么久无法调用子类原本特有的内容
  • 解决方案:
    用对象的向下转型【还原】
    向下转型
    对象向下转型
  • 代码示例:
    猫:
public class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    //特有方法
	public void catchMouse() {
        System.out.println("猫抓老鼠");
    }
}

狗:

public class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗吃骨头");
    }
    //特有方法
	public void watchHouse() {
        System.out.println("狗看家");
    }
}

主函数:

public class Main {
    public static void main(String[] args) {
        //对象向上转型,就是:父类引用指向子类对象
        Animal animal = new Cat();	//本来创建的时候是一只猫
        animal.eat();	//猫吃鱼

//		  animal.catchMouse();	//错误写法!

		//向下转型,进行“还原”动作
		Cat cat = (Cat) animal;
		cat.catchMouse();	//猫抓老鼠

		//下面是错误的向下转型
		//本来new的时候是一只猫,现在非要当做狗
		//错误写法!编译不会报错,但是运行会出现异常
		//java.lang.ClassCastException,类转换异常
		Dog dog = (Dog) animal;
    }
}

用instanceof关键字进行判断

  • 如何才能知道一个父类引用的对象。本来是什么子类?
  • 格式:

对象 instanceof 类名称

这将会得到一个boolean值结果,也就是判断前面的对象能不能当做后面类型的实例。

  • 代码示例:
public class Main {
    public static void main(String[] args) {
        Animal animal = new Dog();  //本来是一只狗
        animal.eat();   //狗吃骨头

        //如果希望调用子类特有的方法,需要向下转型
        //判断一下父类引用animal本来是不是Dog
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.watchHouse();
        }
        //判断一下animal本来是不是Cat
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.catchMouse();
        }

        giveMeAPet(new Dog());
    }

    public static void giveMeAPet(Animal animal) {
        if (animal instanceof Dog) {
            Dog dog = (Dog) animal;
            dog.watchHouse();
        }
        
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.catchMouse();
        }
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值