前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【测开技能】Java系列(二十 七)多态

【测开技能】Java系列(二十 七)多态

作者头像
雷子
发布2022-09-29 20:24:24
2310
发布2022-09-29 20:24:24
举报

前一篇:

【测开技能】Java系列(二十 六)继承(二)

这一篇,我们开始去分享多态。

在继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为覆写(Override)。

假如,在food中定义了eat

代码语言:javascript
复制
class Food {

    public  void eat(){
        System.out.println("you can eat food");
    }

}

在子类中,可以复写下这个方法

代码语言:javascript
复制
class Mantou extends Food{    @Override    public  void eat(){
        System.out.println("you can eat Mantou");
    }
}

执行结果:

这样就完成了复写了Food类的eat方法。

不加Override的也是可以的,但是有一个好处就是,Override可以检查重写的方法是否正确,

写了错误,就会给我们报错。

在上一节中,我们已经知道,引用变量的声明类型可能与其实际类型不符,例如:

代码语言:javascript
复制
public class main {
    public static void main(String[] args) {
        Food food = new Mantou();
       food.eat();
    }
}

那么,一个实际类型为Mantou,引用类型为Food的变量,调用其eat()方法,调用的是Food还是Mantourun()方法?

执行下:

运行一下上面的代码就可以知道,实际上调用的方法是Mantourun()方法。因此可得出结论:

Java的实例方法调用是基于运行时的实际类型的动态调用,而非变量的声明类型。这个非常重要的特性在面向对象编程中称之为多态。。

多态

多态是指,针对某个类型的方法调用,其真正执行的方法取决于运行时期实际类型的方法。

代码语言:javascript
复制
public class main {

    public static void main(String[] args) {
        Food food = new Mantou();
       food.eat();
    }
}

这样,很简单,我们就可以看到,实际运行 的方法是Mantou的方法。但是假设有这样的一个方法

代码语言:javascript
复制
  public void runTwice(Food p) {
            p.eat();
            p.eat();
        }

它传入的参数类型是Food,我们是无法知道传入的参数实际类型究竟是Food,还是Mantou,还是Food的其他子类,因此,也无法确定调用的是不是Food类定义的run()方法。

所以,多态的特性就是,运行期才能动态决定调用的子类方法。对某个类型调用某个方法,执行的实际方法可能是某个子类的覆写方法。这种不确定性的方法调用,究竟有什么作用?

我们还是来举栗子。

假设我们有一个食物,原始价格是100,可以打折,初始时一折。

代码语言:javascript
复制
class Food {

    protected double income=100;
    public double getTax() {
        return income * 0.1;
    }

}

此时我们有一个mantou,需要打8折。

代码语言:javascript
复制
class Mantou extends Food{
        @Override
        public  double getTax(){
            return  income*0.8;
        }
    }

最近几天时中秋,开始打折促销了。我们打9折

代码语言:javascript
复制
class yuebing extends Food{
    @Override
    public  double getTax(){
        return  income*0.9;
    }
}

那么我们最后要算某个食物最后的价格,

代码语言:javascript
复制
 public  double zhekou(Food food){
        return food.getTax();
    }

最后,我们去计算的时候,就可以

代码语言:javascript
复制
public static void main(String[] args) {
    yuebing yuebing=new yuebing();
    Main ne=new Main();
   System.out.println( ne.zhekou(yuebing));
}

这样结果返回月饼的钱数

getTax。就是利用的多态。getTax只需要和income打交道就可以。

可见,多态具有一个非常强大的功能,就是允许添加更多类型的子类实现功能扩展,却不需要修改基于父类的代码。

通常类都是继承Object方法,那么有哪些比较重要的Object方法呢

  • toString():把instance输出为String
  • equals():判断两个instance是否逻辑相等;
  • hashCode():计算一个instance的哈希值。

在必要的情况下,我们可以覆写Object的这几个方法。

代码语言:javascript
复制
class yuebing extends Food{
    @Override
    public  double getTax(){
        return  income*0.9;
    }
    @Override
    public String toString(){
        return "price:"+String.valueOf(income);
    }
}

其他的覆写可以根据需要来。

调用super

在子类的覆写方法中,如果要调用父类的被覆写的方法,可以通过super来调用

代码语言:javascript
复制
class yuebing extends Food{
    @Override
    public  double getTax(){
        return  super.getTax();
    }
}

final

继承可以允许子类覆写父类的方法。如果一个父类不允许子类对它的某个方法进行覆写,可以把该方法标记为final。用final修饰的方法不能被Override

代码语言:javascript
复制
class Food {

    protected double income=100;
    public final double getTax() {
        return income * 0.1;
    }

}

同时,我们可以看到

直接就无法继承了。

放在类上效果也是一样的。

final修饰的field必须在创建对象时初始化,随后不可修改

所以针对

代码语言:javascript
复制
final修饰符有多种作用:
final修饰的方法可以阻止被覆写;

final修饰的class可以阻止被继承;

final修饰的field必须在创建对象时初始化,随后不可修改。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-09-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 雷子说测试开发 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 调用super
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档