对象的多态性是怎么体现的,与重载有什么不同

对象的多态性是怎么体现的,与重载有什么不同

\quad \quad 现在有这样一个需求:
\quad \quad 要求结合对象的多态性,对一个简易的商场打折系统的代码进行重构:

public static int calculatePrice(String discountStrategy, int price, User user) {
        switch (discountStrategy) {
            case "NoDiscount":
                return price;
            case "Discount95":
                return (int) (price * 0.95);
            case "OnlyVip":
                {
                    if (user.isVip()) {
                        return (int) (price * 0.95);
                    } else {
                        return price;
                    }
                }
            default:
                throw new IllegalStateException("Should not be here!");
        }
    }

\quad \quad 其实题目想表达的意思说直白点就是:当我们将上面的代码写完后,我们会觉得该实现的需求都实现了,很好。但是,当我们需在里面增加一种情况,比如5折时,我们就需要在case中新增一个情况,如果有1000种情况,那么就有1000个case,可读性非常差。那么根据题目的意思,我们需要做的就是把每一种情况,单独放到一个方法中,单独实现。
\quad \quad 实现思路:
\quad \quad 1.定义父类方法,可以任意实现一种折扣方法。后面可以根据该父类方法,利用子类对父类方法的重写,在子类中实现其他方法。
\quad \quad 举例说明:对于意外情况的实现

public class DiscountStrategy {
   public int discount(int price, User user) {
       throw new UnsupportedOperationException();//异常情况的处理(2019.07.06)
   }
}

\quad \quad 2. 为每种情况建立一个单独的方法,分别返回该种折扣情况下的应付金额。
\quad \quad 举例说明:对于VIP用户实行95折的情况的实现

public class OnlyVipDiscountStrategy extends DiscountStrategy{
   @Override//重写父类的方法
   public int discount(int price, User user) {
       if (user.isVip()){
           price*=0.95;
           //由于方法的返回值类型为int,故乘以0.95会损失精确度,这里仅仅作为教学。
       }
       return price;
   }
}

\quad \quad 3.到这里应该可以发现,在每一种方法中都有price、user这两个参数,每次不同的就是调用的方法不同。那么将方法中的公共部分提取出来,用以提供一个统一的对外接口,让该接口去根据传入该方法的参数选择不同的实现方式。
\quad \quad 代码如下:

public class PriceCalculator {
     public static int calculatePrice(DiscountStrategy strategy, int price, User user){
         return strategy.discount(price, user);
     }
}

\quad \quad 最后,生成一下test测试,检查代码的实际效果:

package com.github.hcsp.polymorphism;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class PriceCalculatorTest {
    @Test
    public void test() {
        Assertions.assertEquals(
                95, PriceCalculator.calculatePrice(new Discount95Strategy(), 100, User.dios("屌丝")));
        Assertions.assertEquals(
                100,
                PriceCalculator.calculatePrice(
                        new OnlyVipDiscountStrategy(), 100, User.dios("屌丝")));
        Assertions.assertEquals(
                95,
                PriceCalculator.calculatePrice(new OnlyVipDiscountStrategy(), 100, User.vip("土豪")));
        Assertions.assertEquals(
                100, PriceCalculator.calculatePrice(new NoDiscountStrategy(), 100, User.vip("土豪")));
    }
}

\quad \quad 总结:自己在刚开始接触到对象三大特性之一,"多态"时,总是不明白重载与多态的关系,有些地方说重载是多态的体现。在我的理解中,多态就是同一方法对不同参数所执行的不同的操作。比如代码中的方法:

public static int calculatePrice(DiscountStrategy strategy, int price, User user)

当我们调用该方法时,传入的参数为:

PriceCalculator.calculatePrice(new Discount95Strategy(), 100, User.dios("屌丝"))

则调用全场95折的方法。从这个方面讲,多态可以说是同一行为具有多个不同表现形式的能力。这样说可能与重载有些类似,那么重载是如何表现的,举个例子:

public class Test {
    public int caculate(int s1,int s2){
        return s1*s2;
    }
    public int caculate(int s1,int s2,int s3){
        return s1*s2*s3;
    }

    public static void main(String[] args) {
        Test test=new Test();
        System.out.println(test.caculate(1,2));
        System.out.println(test.caculate(1,2,3));
    }
}

\quad \quad 同一函数名,对不同的参数列表(包括参数的类型不同)所表现出不同的方法。可以看出,上面重载的过程中,没有继承关系的发生,是一个静态的过程,那么是不是可以说重载的过程是一种静态的多态,可以参考百度百科的说法:https://baike.baidu.com/item/重载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值