面向对象特征--多态[java]

⛳️基本概念

同一种事物,在不同时刻表现不同的状态

比如:水果表现出来的不同形态有:香蕉、猕猴桃、苹果

再比如:猫、狗、猴子可以把它们都归类为动物,每种动物都要吃东西,所以我们可以设置他们都必须吃,但是每种动物的习性又不一样,那么我们就可以设置每个动物自己特有的功能,多态对象只能调用父类中定义的子类中的重写的功能,不能调用子类中特有的功能,这样就实现了代码的统一性。

⛳️多态存在的三个必要条件 

1.要有继承(包括接口的实现)(前提条件)

2.要有重写(前提条件)

3.父类引用指向子类对象

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAY2hlbi53eA==,size_20,color_FFFFFF,t_70,g_se,x_16

当编译期类型是父类,运行期类型是子类时,被称为父类引用指向子类对象

class Animal{
  ......
}
class Cat extends Animal{
  ......
}
class Dog extends Animal {
  ......
}
//Animal的引用指向Cat的对象
Animal x = new Cat() 

⛳️多态环境下的调用

1.针对非静态成员方法:编译看左边,运行看右边

2.针对静态方法:编译期间看左边,运行期间还是看左边

3.针对成员变量:编译期间看左边,运行期间还是看左边

案例:

定义一个抽象类父类Animal:

public abstract class Animal {    
    int age = 10;
    public Animal(){
    }
    //定义一个抽象方法
    public abstract void eat();
    //定义一个成员方法
    public void sleep(){
         System.out.println("动物睡");
    }
    //静态方法,不能重写
    public static void play(){
         System.out.println("动物玩");
    }
}

定义子类Dog继承Animal:

public class Dog extends Animal{
    int age = 15;
    public Dog(){
    }
    //重写Animal中的eat方法
    @Override
    public void eat() {
        System.out.println("Dog重写Animalh中的eat()---狗吃骨头");
    }
}

定义子类Cat继承Animal:

public class Cat extends Animal {
    //重写Animal中的eat方法
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

定义子类Monkey继承Animal:

public class Monkey extends Animal{
    //重写Animal中的eat方法
    @Override
    public void eat() {
        System.out.println("猴子吃香蕉");
    }
}

测试:

public class Test {
    public static void main(String[] args) {
          
          Dog xh = new Dog();
          //编译期间  a.eat() a的类型是Animal类,调用的是抽象的eat()
          //运行期间  a执向的是一个Dog对象,运行的是Dog中重写的eat()方法
          Animal a = new Dog(); 
                 /*
                 针对非静态成员方法:编译看左边,运行看右边
                  */
                 a.eat();//Dog重写Animalh中的eat()---狗吃骨头
                 //不是直接调用父类的sleep,而是找dog对象父类的sleep() 
                 a.sleep();//动物睡
                 /*
                 针对静态方法:编译期间看左边,运行期间还是看左边
                  */
                 a.play();//动物玩  
                 /*
                 针对成员变量:编译期间看左边,运行期间还是看左边
                  */
                 System.out.println(a.age);//10
    }
}

注意:变量不存在被子类覆写这一说法,只有方法存在覆写。

⛳️方法参数具有多态性

方法参数多态性的好处:提高代码的扩展性

public class Test1 {
    public static void main(String[] args) {
​
          Dog dog = new Dog();
          Cat cat = new Cat();
          Monkey monkey = new Monkey();
​
          Test3 t = new Test3();
          t.feedAnimal(dog);
          t.feedAnimal(cat);
          t.feedAnimal(monkey);
    }
    /*
       喂动物
     */
    public void feedAnimal(Animal animal){
        animal.eat();
    }
}

⛳️向上转型和向下转型

在继承中,通过extends关键字,子类可以复用父类的功能,如果父类不能满足当前子类的需求,则子类可以通过重写父类中的方法来加以扩展,在这个过程中就存在多态的应用。

1.向上转型(自动转型:子继承父):可以把不同的子类对象都当作父类来看,进而屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,统一调用标准。

eg:父类Animal,子类dog 父类的引用指向子类对象:Animal dog = new dog();

说明:向上转型时,子类对象当成父类对象,只能调用父类的功能,如果子类重写了父类中声明过的方法,方法体执行的就是子类重写后的功能,但是此时对象是把自己看做是父类类型的,所以其他资源使用的还是父类型的。

eg:花木兰替父从军,大家都把花木兰看做她爸,但是实际从军的是花木兰,而且,花木兰只能做她爸能做的事,在军营里是不可以化妆的。

2.向下转型(强制转型:父类类型转为子类自己的类型):子类的引用的指向子类对象,过程中必须要采取到强制转型,之前向上转型过的子类对象仍然想执行子类的特有功能,所以需要重新恢复成子类对象。

Animal a = new dog();//向上转型,此时,a是Animal类型

Dog d = (Dog)p;//此时,把Animal类型的p转成小类型Dog 其实,相当于创建了一个子类对象一样,可以用父类的,也可以用自己的。

说明:向下转型时,是为了方便使用子类的特殊方法,也就是说当子类方法做了功能拓展,就可以直接使用子类功能。

eg:花木兰打仗结束,就不需要再看做是她爸了,就可以化妆了。

public class Test3 {
    public static void main(String[] args) {
          //向上转型
          Animal dog = new Dog();
          Cat cat = new Cat();
          Monkey monkey = new Monkey();
​
          Test3 t = new Test3();
          t.feedAnimal(dog);
          t.feedAnimal(cat);
          t.feedAnimal(monkey);
    }
    /*
       喂动物
     */
    public void feedAnimal(Animal animal){
        animal.eat();
        //判断animal中实际传入的是什么
        //父类引用 instanceof(是不是) 具体的子类类型
        //instanceof 判断父类引用实际表示的对象
        System.out.println(animal instanceof Dog);
        if(animal instanceof Dog){
            //向下转型
            Dog dog = (Dog)animal;
                dog.play();
        }
    }
}

优点:父类引用表示子类对象,提升程序的扩展性

缺点:父类类型不能调用子类中特有的方法

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chen☆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值