美文网首页
Java 面向对象——多态

Java 面向对象——多态

作者: BitterOutsider | 来源:发表于2020-12-03 21:27 被阅读0次

什么是多态

多态调用表现为:表面看起来你对父类调用了一个方法,实际上在方法的响应过程中由子类(方法的接收者)根据自己是谁,自行决定要怎么去响应它。其中方法的接收者是xxx.f()中的xxx

Shape shape = new Circle(1);
shape.getArea();
  • 静态方法是没有多态的
  • 参数是静态绑定的,接收者是动态绑定的。换句话说多态只对方法的接收者生效。又换句话说多态只选择接收者的类型,不选择参数的类型。
    举个例子:如下代码,试想会输出什么结果?答案是:I am Sub, the param is ParamBase。参数的选择是由方法重载所决定的,选择的参数是最不用转换(匹配度最高)的那一个。
public class Base {
    public void print(ParamBase param){
        System.out.println("I am Base, the param is ParamBase");
    }

    public void print(ParamSub param){
        System.out.println("I am Base, the param is ParamSub");
    }
}
public class Sub extends Base {
    @Override
    public void print(ParamBase param) {
        System.out.println("I am Sub, the param is ParamBase");
    }

    @Override
    public void print(ParamSub param) {
        System.out.println("I am Sub, the param is ParamSub");
    }
}
public class Main {
    public static void main(String[] args) {
        Base obj = new Sub();
        ParamBase param = new ParamSub();
        obj.print(param);
    }
}

再举一个实际的例子:HashSet.addAll方法。HashSet的addAll方法是从AbstractCollection中继承过来的,它本身没有重写。AbstractCollection有一个add方法,addAll方法又调用了add方法。Hashset重写了add方法。这可能听起来有点绕,我们用一张图说明清楚。问题是HashSet.addAll()这个语句调用的add方法是HashSet还是AbstractCollection的?答案是:Hashset

总结一下:多态的意思是根据当前的类型决定调用哪个方法。任何时候实例方法的选择,都是由当前对象根据自己实际的类型来决定去调用哪个方法的。

多态实战:策略模式

使用策略模式重构这个方法,实现三个策略:

  • NoDiscountStrategy 不打折
  • Discount95Strategy 全场95折
  • OnlyVipDiscountStrategy 只有VIP打95折,其他人保持原价
public class PriceCalculator {
    public static int calculatePrice(DiscountStrategy strategy, int price, User user){
        // 这里体现了多态的思想。
        return strategy.discount(price, user);
    }
}
public class DiscountStrategy {
    public int discount(int price, User user) {
        throw new UnsupportedOperationException();
    }
}
public class NoDiscountStrategy extends DiscountStrategy {
    @Override
    public int discount(int price, User user) {
        return price;
    }
}
public class Discount95Strategy extends DiscountStrategy {
    @Override
    public int discount(int price, User user) {
        return (int)(price * 0.95);
    }
}
public class OnlyVipDiscountStrategy extends DiscountStrategy {
    @Override
    public int discount(int price, User user) {
        if (user.isVip()) {
            return (int) (price * 0.95);
        } else {
            return price;
        }
    }
}

再举一个JDK中线程池ThreadPoolExecutor的例子:其中几个个构造器中有RejectedExecutionHandler这样一个参数,这个参数就是一种策略模式。


分别有以下几种策略:

相关文章

网友评论

      本文标题:Java 面向对象——多态

      本文链接:https://www.haomeiwen.com/subject/sryvwktx.html