java---面向对象编程2(多态)

多态存在的意义

  • 多态的设计思想:(本质为"封装"的更进一步)
    封装的目的:让类的使用者不需要知道类的实现细节,就能使用该类,但使用者仍应该知道该类是什么类型
    *多态:*类的使用者不仅不需要知道类的实现细节,也不需要知道这个类究竟是什么类型,只需要知道有即将使用的方法即可

  • 方便扩展:
    新增一个类时,让子类去重写要使用的方法即可,类的调用者这里的代码不需要做出任何修改/只需做很小的修改

  • 减少一些分支语句(if/else switch/case)

多态的实现:

  • 向上转型
  • 动态绑定
  • 方法重写
    注意:三者缺一不可

一、向上转型---------------“is-a”

  • 所谓向上转型,就是使用父类的引用指向一个子类的实例(也可以说是子类的引用转成了父类的引用)
    1、语法规则:
  //方式一
       Animal animal=null;
       Cat cat=new Cat("喵喵");
       animal=(Animal)cat;//不同类型的引用之间一般不可相互赋值(要进行强制类型转换),除非两者是父子关系
                   //所以此处(Animal)可省略
     //方式二
       Animal animal=new Cat("喵喵");

以上代码中,animal是父类Animal的引用,指向子类Cat的实例,这种写法为向上转型
2、发生的时机

  • 直接赋值
 Animal animal=new Cat("喵喵");
  • 方法传参
public class Test {
    public static void main(String[] args) {
        Cat cat=new Cat("喵喵");
        func(cat);
    }

    public static void func(Animal animal) {
        
    }
}
  • 方法返回
public class Test {
    public static void main(String[] args) {
        Animal animal=func();
    }

    public static Animal func() {
        Cat cat=new Cat("喵喵");
        return cat;
    }
}

以上代码方法func返回的是一个Animal类型的引用,但实际对应到Cat的实例

注意:父类的引用只能访问到父类的属性和方法,访问不到子类独有的属性和方法,
若非要访问子类的属性,可借助方法重写,由父类的引用触发调用子类的方法,再由子类的方法间接操作子类的属性(方法重写后面会介绍)

二、动态绑定

1.发生时机
父类中包含的方法在子类中有同名,同参数,同返回值(特殊情况除外)的方法,就会进行动态绑定
例如:
父类:Animal
子类:Cat
二者共有同名,同参数,同返回值的eat()方法,在执行如下代码时就会触发动态绑定

public class Test {
    public static void main(String[] args) {
        Animal animal1 = new Animal("1");
        animal1.eat("food");
        Animal animal2 = new Bird("2");
        animal2.eat("food");
    }
}

以上代码中,animal1调用的是父类的eat方法
animal2调用的是子类的eat方法

----------->在Java中,调用某个类的方法时,究竟执行的是父类方法的代码还是子类方法的代码,就要看这个引用指向的是父类的对象还是子类的对象,这个过程是程序运行时决定的,而不是在编译期决定的,因此这个过程被称为动态绑定

三、方法重写

  • 对于上述提到的eat方法,子类实现父类的同名方法,并且参数类型和个数,返回值类型完全相同(特殊情况除外),这种情况被称为重写/覆写/覆盖,此时若通过父类调用该方法,就会触发重写,具体执行那个版本的方法就由动态绑定的规则来决定

  • 注意事项:
    1、普通方法可以重写,static修饰的静态方法不能重写
    2、重写中子类方法的访问权限不能低于父类方法的访问权限
    例如:将子类方法中的eat方法的权限改为private,编译就会出错
    3、重写的方法返回值类型不一定和父类方法相同(特殊情况除外),最好写成相同的
    4、在代码中进行重写方法时显示加上@Override注解,以便明确此处为方法重写

  • 重载和重写的区别:

区别重载重写
概念方法名相同,参数类型及个数不同方法名,参数类型及个数,返回值类型完全相同
范围同一个类中继承关系中
限制没有权限要求被重写的方法不能拥有比父类更加严格的访问控制权限

**注意:**方法的返回值类型并不影响重载,如果两个方法参数相同而返回值类型不同,会出现编译报错

-------------------------------------------------------------------------------------------------------------------------动态绑定和方法重写:
方法重写是Java语法层次上的规则,而动态绑定是方法重写这个语法规则的底层实现,两者本质上描述的是相同的事情,只是侧重点不同

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值