值参数化和行为参数化

来源:互联网 发布:mac war3 局域网 编辑:程序博客网 时间:2024/06/03 07:16

在值参数化和行为参数化问题上,可以引申出很多的道理。这里,请同学们先搞清楚怎么做,然后再加以思考和总结。


先自己做,不要看分割线后面的结果。

上机练习的要求:

1.编写判断n是否包含7的函数isInclude7(int n)

2.合并函数isInclude7(int n)和isInclude5(int n)——要点:值的参数化

3.接口类型X,它有boolean test(int n)。将foo方法中可以变化的、if( is3X(i) && isInclude5(i))中的判断条件用X的实现类型实现。

4.将foo方法修改为foo(int x,X ... conditions),编写main打印0-x之间 3的倍数而且含5、而且含7、而且含8的数.将判断条件变成方法的参数——行为参数化

5.使用java.util.function.Predicate替代类型X。

有问题提出来,我们讨论。

《3.1.2 方法》中介绍功能分解的例子:输出0-x之间 3的倍数而且含5的数,如15,54,555等等(或者输出这种数的个数)。对于较复杂的问题,分解成较简单的小问题.

书上给出了代码:

package semantics.method;/** * HelperMethodDemo.java. * 对于较复杂的问题,分解成较简单的小问题. * 出于功能分解目的而得到的方法,可以称之为助手方法(Helper Method), * 一般而言,常常设定为private方法(最多是protected * 关键词:Structured Decomposition。 * @author yqj2065 * @version 2012.02 */public class HelperMethodDemo{    ///////////////////// 简单情况:输出0-x之间 3的倍数而且含5的数.///////////////////////////    /**     * 该数是否3的倍数     * @param n 自然数n     * @return n是3的倍数返回true。     */    private static boolean is3X(int n){        return ( n%3 == 0);    }    /**     * 判断该数是否包含5     * @param n 自然数n     * @return n包含5返回true。     */    public /*private*/ static boolean isInclude5(int n){        while ( n != 0){            if (n % 10 == 5) return true;            n /=10;        }        return false;    }    /**     * 采用功能分解。我觉得这个问题有点难,需要分解     */    static void foo(int x){        for(int i=0;i < x;i++){            if( is3X(i) && isInclude5(i) ){                System.out.print(" "+i);            }        }    }}


1.编写函数isInclude7(int n)

复制粘贴isInclude5(int n)的代码,按照情况加以修改,ok,这是学习编程时很重要的手段。设计师在设计程序时,则会避免复制-粘贴-修改方式。


2.值参数化,判断n包含5、7或者其他数。所谓值参数化,就是将可变的条件值加以参数化,如判断数n是否含i(自然数0-9的验证代码暂时忽略)

    /**     * 判断数n是否含i     * @param n 自然数n     * @param i 自然数0-9     * @return  n包含i返回true,否则false。     */    private static boolean include(int n,int i){//        while ( n != 0){            if (n % 10 == i) return true;            n /=10;        }        return false;    }

思考:

判断数n是否i 的倍数boolean isMultipleOf (int n,int i)

思考:是否需要合并isXX(int n,int i)和include(int n,int i)为一个通用接口test(int n,int i),对数n和数i 的关系进行判断?比较下一步的test(int n)


3.接口类型X

注意:接口类型X将对某个数n进行某种判断,不是对数n和数i 的关系进行判断

package semantics.method;public interface X{    boolean test(int n);}

将foo方法中可以变化的、if( is3X(i) && isInclude5(i) )中的判断条件用X的实现类型实现,这是为下一步的编程做准备。

编写X的独立子类Include5,而判断 是否3的倍数用匿名类

package semantics.method;public class Include5 implements X{    public boolean test(int n){        while ( n != 0){            if (n % 10 == 5) return true;            n /=10;        }        return false;    }}
if( is3X(i) && isInclude5(i) )中的判断条件用X的实现类型实现
    static void bar(int x){        for(int i=0;i < x;i++){            if( (new X(){                    @Override public boolean test(int n){                        return ( n%3 == 0);                    }                }).test(i) && new Include5().test(i) ){                System.out.print(" "+i);            }        }    }


4.行为参数化

将foo方法修改为foo(int x,X ... conditions)

    static void foo(int x,X ... conditions){        for(int i=0;i < x;i++){            boolean b =true;            for(X c :conditions){                b = b&& c.test(i);//            }            if( b ){                System.out.print(" "+i);            }        }    }    static void main(){        X c1 =new X(){            @Override public boolean test(int n){                while ( n != 0){                    if (n % 10 == 5) return true;                    n /=10;                }                                return false;            }        };        X c2 = ( n)->{            while ( n != 0){                if (n % 10 == 7) return true;                n /=10;            }                            return false;        };//n % 10 == 8 ,自己加上去        X c3 = (n)-> ( n%3 == 0);        foo(100,c1,c2,c3);    }

思考:

X有哪些不方便的地方?


5.使用java.util.function.Predicate替代类型X。

    static void foo(int x,Predicate<Integer> condition){        for(int i=1;i < x;i++){                       if( condition.test(i) ){                System.out.print(" "+i);            }        }    }
Predicate有default方法and、or,因此替代类型X时,不再需要变长参数而使用Predicate<Integer> condition为参数。

    static void main(){               Predicate<Integer> p1 =( n)->{            while ( n != 0){                if (n % 10 == 7) return true;                n /=10;            }                            return false;        };        foo(100,p1.and((n)-> ( n%3 == 0)));            }


了解/提高题:

1.输出含7或3的倍数,而且它还是7的倍数【 7 21 42 63 70 77 84】

2.为X添加defaule方法and,or,参考Predicate的源代码

X and(X x)




 


0 0
原创粉丝点击