柔性多态

时间:2022-07-25
本文章向大家介绍柔性多态,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

柔性多态

以求圆和长方形面积为例 假设其类图如图

这是个常规的多态程序设计,在子类中重写父类的getArea即可;

但是如果随着时间的变迁,还需要求圆和长方形的周长该如何呢?重新定义一个方法getPerimeter

float getPerimeter()

然后再在子类中实现。这势必造成接口及实现模块 客户端程序都需要修改并重新编译。

普通多态编程局限性:如果接口函数内容发生变化,那么相应的各实现子类必须发生变化,导致相关联的各级模块必须重新编程及编译,这即是普通多态编程的局限性 造成这一结果的主要原因是父类 子类定义的多态函数关联过强,消除这种关联性是实现柔性多态功能的关键

修改后的代码如下:

package design;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * author:ycc
 * @param <T>
 * 描述: 柔性多态, 在父接口中定义转发方法,子类实现转发,具体转发规则由子类决定。实现增加规则时不需要重新编译接口。
 */
public interface Polymorphic<T> {

//Polymorphic function definition

    T dispatch(int nID, T in) throws ReflectiveOperationException;

}

class Flexible<T> implements Polymorphic<T> {
    private T in;
    static class Nid {
        public static List<String> methods = new ArrayList<>();
        static String method1 = "method1";
        static String method2 = "method2";

        static {
            methods.add(method1);
            methods.add(method2);
        }
    }

    @Override
    public T dispatch(int nID, T in) throws ReflectiveOperationException {
        this.in = in;
        Method declaredMethod = this.getClass().getDeclaredMethod(Nid.methods.get(nID));
        return (T) declaredMethod.invoke(this);
    }

    public  T method1(){
        //handler
        return in;
    }
    

    public  T method2(){
//handler
        return in;
    }

    public static void main(String[] args)throws Exception {
        Polymorphic polymorphicNonT  = new Flexible();
        Float dispatch = (Float) polymorphicNonT.dispatch(1, 1.0f);
        System.out.println(dispatch);
        Polymorphic<FlexibleBean> polymorphicHasT  = new Flexible<>();
        FlexibleBean dispatch1 = polymorphicHasT.dispatch(0, new FlexibleBean());
        System.out.println(dispatch1);
    }

}

class FlexibleBean{
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "FlexibleBean{" +
                "id=" + id +
                ", name='" + name + ''' +
                '}';
    }
}

在上面改写中,接口中的内容不变,而子类重写dispatch仅起到转发的作用,具体转发的函数是非多态函数。如果再需要一个方法就可以在子类中定义个方法,而接口无需再次编译。