Java多态

目录

多态的概念与用法

方法重写

向上转型与向下转型

为什么需要向上转型:

实现向上转型的方式:

向下转型


继承虽然可以帮助我们提高代码的复用性,但还不够,比如说数学老师和语文老师都要去上课,但是他们上课的内容不同,那么怎么设计呢?如果按照继承的思想,应该在它们的父类老师中设计,但这时又会出现一个问题,父类中如何写呢?如果仅仅说“老师在上课”似乎不妥,但又实在没有一种合适的词汇来表示。那么就需要用到多态了。

多态的概念与用法

多态,即多种形态。当要完成某个确定的动作时,不同的对象实现方法不同,就像上面的例子,数学老师要上数学课,语文老师要上语文课。去上课的对象不同,上课的内容也就不同,这就是多态。

Java中要实现多态,需要满足以下条件:

  • 必须在继承体系下
  • 子类必须要对父类中方法进行重写
  • 通过父类的引用调用重写的方法

例如分别创建Teacher对象和其子类MathTeacher和ChineseTeacher对象:

 再对其调用:

public class Test {
    public static void main(String[] args) {
        ChineseTeacher chineseTeacher = new ChineseTeacher("张三", "男");
        MathTeacher mathTeacher = new MathTeacher("李四", "女");
        chineseTeacher.todo();
        mathTeacher.todo();
    }
    //输出:    
    //张三老师在上语文课!
    //李四老师在上数学课!
}

 可以发现虽然两个对象都调用了todo方法,但是实现的结果却不同。而造成这种不同的原因就在于方法重写。

方法重写

重写,也称覆盖(override)。即保持方法的外壳不变(方法名、参数、返回值不变),重新改写它的实现。比如说:

int i = 10;
i = 20;//可以理解为i的“重写”

也就是说int是它的外壳,不能改变,而它里面的值却可以改变。我们可以把方法的实现抽象理解为它的“值”。一个变量被static或final修饰后,它的值就不能再改变;类似的,一个方法被static和final修饰后也不能再重写。

对方法进行重写时,可以在前面加上@override,它可以帮助我们进行一些检验:如果找不到需要重写的方法,编译就会报错。这可以保证我们在重写的时候方法名、参数、返回值等都正确。

当然,IDEA也提供了一键重写的功能:(也可以通过快捷键重写)

由于重写是新的实现方法,因此设计重写应该在新的类中重写,这样可以保证在旧的类中依然可以正常使用。

重写和重载是两个不同的概念,重载仅仅是方法名相同,其他的部分都可以不同,重载不会覆盖原来的方法,因此重载后的方法是一个全新的(只有方法名相同)方法。

注意:

  • 重写的方法访问权限不能比原始权限低
  • 由于重写是在不同类中实现的,因此也不能重写由private修饰的类
  • 不要重写构造方法,否则会造成一些难以发现的问题

动态绑定:

动态绑定指的是通过实例化对象访问某个方法时,JVM会沿着继承关系链依次寻找,直到找到目标方法。因此动态绑定的实现必须要满足继承关系。

向上转型与向下转型

创建的子类对象,可以当成父类对象来使用。这种使用方法就叫做向上转型。

为什么需要向上转型:

其实还是多态的思想:进行共性抽取和提高代码的利用率。

比如说:

public static void todo(Teacher teacher) {
    teacher.todo();
}
public static void main(String[] args) {
    todo(new ChineseTeacher("张三", "男"));
    todo(new MathTeacher("李四", "女"));
}

由于发生了动态绑定,传入chineseTeacher对象时,访问的是ChineseTeacher类的todo方法,而传入mathTeacher对象时,访问的时MathTeacher类的todo方法。

实现向上转型的方式:

1、方法传参(如上述所示)

2、直接赋值,例如:

Teacher teacher = new ChineseTeacher();

3、方法返回值,当方法返回值类型时父类时,如果返回子类对象也会发生向上转型。

由于向上转型后不能再访问子类成员,若要在访问子类特有的成员,就要实现向下转型

向下转型

向下转型的实现与向上转型类似,不过一个类向上转型后,如果要再次向下转型,最好转为原来的类,否则不安全。比如:

为了确保向下转型的成功,可以使用instanceof关键字。因此上述代码可以改为:

—>

if (对象 instanceof 类) {}; 含义:

如果该对象是由该类向上转型得到,执行代码。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值