zoukankan      html  css  js  c++  java
  • 枚举应用篇

    《Java编程思想》这本书已经看到19章枚举,之前的很多难点被我略过了。在此章学到了新概念,多路分发。先说说单路分发: Java只支持单路分发,即如果要执行的操作包含多个不确定的类型类型对象时,Java只能处理其中一个的类型。N个未知类型需要N个方法调用以确定其类型即分发。所以编程思想中的多路分发严格讲应该叫“伪多路分发”即多次单路分发。单路分发实质上是多态特性的一种体现。

    举个梨子:例如有A、B、C、三种类型a.compete(b),a、b的类型未知,执行此句时只能确定a的类型

    代码为证:

    package com.houjun.enum1;
    
    import java.util.Random;
    
    /**
     * @Author: HouJun
     * @Date: 2019/10/8 17:29
     * @Description: 多路分发例子
     * @version: 1.0
     */
    enum Outcome {
        WIN, LOSE, DRAW;
    }
    
    interface Item {
    //    Outcome compete(Item it);//完成方法
    
        Outcome eval(Paper p);
    
        Outcome eval(Scissors s);
    
        Outcome eval(Rock r);
    
        Outcome eval(Item r);
    }
    
    class Paper implements Item {
    
    //    @Override
    //    public Outcome compete(Item item) {
    //        return item.eval(this);
    //    }
    
        @Override
        public Outcome eval(Paper p) {
            return Outcome.DRAW;
        }
    
        @Override
        public Outcome eval(Scissors s) {
            return Outcome.LOSE;
        }
    
        @Override
        public Outcome eval(Rock r) {
            return Outcome.WIN;
        }
    
        @Override
        public Outcome eval(Item r) {
            System.out.println(r.getClass().getName());
            System.out.println("c");
            return null;
        }
    }
    
    class Scissors implements Item {
    //    @Override
    //    public Outcome compete(Item it) {
    //        return it.eval(this);
    //    }
    
        @Override
        public Outcome eval(Paper p) {
            return Outcome.LOSE;
        }
    
        @Override
        public Outcome eval(Scissors s) {
            return Outcome.DRAW;
        }
    
        @Override
        public Outcome eval(Rock r) {
            return Outcome.WIN;
        }
    
        @Override
        public Outcome eval(Item r) {
            System.out.println(r.getClass().getName());
            System.out.println("b");
            return null;
        }
    }
    
    class Rock implements Item {
    //    @Override
    //    public Outcome compete(Item it) {
    //        return it.eval(this);
    //    }
    
        @Override
        public Outcome eval(Paper p) {
            return Outcome.LOSE;
        }
    
        @Override
        public Outcome eval(Scissors s) {
            return Outcome.WIN;
        }
    
        @Override
        public Outcome eval(Rock r) {
            return Outcome.DRAW;
        }
    
        @Override
        public Outcome eval(Item r) {
    //        if ( r instanceof Rock){
    //            return  this.eval(new Rock());
    //        }
    //        if ( r instanceof Scissors){
    //            return  this.eval(new Scissors());
    //        }if ( r instanceof Paper){
    //            return  this.eval(new Paper());
    //        }
            System.out.println("a");
            return null;
        }
    }
    
    public class RoShaamBo {
        static final int SIZE = 20;
        private static Random random = new Random(47);
    
        public static Item newItem() {
            switch (random.nextInt(3)) {
                default:
                case 0:
                    return new Scissors();
                case 1:
                    return new Paper();
                case 2:
                    return new Rock();
            }
    
        }
    
        public static void match(Item a, Item b) {
            System.out.println(a.getClass().getName() + "          vs       " + b.getClass().getName() + " ; " + a.eval(b));
        }
    
        public static void main(String[] args) {
            for (int i = 0; i < 20; i++) {
                match(newItem(), newItem());
            }
        }
    }

    上面match()方法中可以正确调用a.eval(b),确定a的类型,而b则不去确定其具体类型,一直使用其基类Item类型。传统的方法是重载eval(),在其中使用instanceOf来判断b的类型然后指定调用方法,这样很繁琐。
    书中给出了这种再次使用单路分发的方式,巧妙的解决了这个问题。
    代码为证:
    // enums/Outcome.java
    package enums;
    public enum Outcome { WIN, LOSE, DRAW }
    // enums/RoShamBo1.java
    // Demonstration of multiple dispatching
    // {java enums.RoShamBo1}
    package enums;
            import java.util.*;
            import static enums.Outcome.*;
    interface Item {
        Outcome compete(Item it);
        Outcome eval(Paper p);
        Outcome eval(Scissors s);
        Outcome eval(Rock r);
    }
    class Paper implements Item {
        @Override
        public Outcome compete(Item it) {
            return it.eval(this);
        }
        @Override
        public Outcome eval(Paper p) { return DRAW; }
        @Override
        public Outcome eval(Scissors s) { return WIN; }
        @Override
        public Outcome eval(Rock r) { return LOSE; }
        @Override
        public String toString() { return "Paper"; }
    }
    class Scissors implements Item {
        @Override
        public Outcome compete(Item it) {
            return it.eval(this);
        }
        @Override
        public Outcome eval(Paper p) { return LOSE; }
        @Override
        public Outcome eval(Scissors s) { return DRAW; }
        @Override
        public Outcome eval(Rock r) { return WIN; }
        @Override
        public String toString() { return "Scissors"; }
    }
    class Rock implements Item {
        @Override
        public Outcome compete(Item it) {
            return it.eval(this);
        }
        @Override
        public Outcome eval(Paper p) { return WIN; }
        @Override
        public Outcome eval(Scissors s) { return LOSE; }
        @Override
        public Outcome eval(Rock r) { return DRAW; }
        @Override
        public String toString() { return "Rock"; }
    }
    public class RoShamBo1 {
        static final int SIZE = 20;
        private static Random rand = new Random(47);
        public static Item newItem() {
            switch(rand.nextInt(3)) {
                default:
                case 0: return new Scissors();
                case 1: return new Paper();
                case 2: return new Rock();
            }
        }
        public static void match(Item a, Item b) {
            System.out.println(
                    a + " vs. " + b + ": " + a.compete(b));
        }
        public static void main(String[] args) {
            for(int i = 0; i < SIZE; i++)
                match(newItem(), newItem());
        }
    }

     

  • 相关阅读:
    ABP框架系列之三十六:(MVC-Views-MVC视图)
    ABP框架系列之三十五:(MVC-Controllers-MVC控制器)
    ABP框架系列之三十四:(Multi-Tenancy-多租户)
    ABP框架系列之三十三:(Module-System-模块系统)
    2-kong的preserve_host和strip_uri解析
    2-Consul简介
    1-Consul系列文章
    1-Kong文章记录
    1-ES学些教程
    0-Jenkins系列学习文章
  • 原文地址:https://www.cnblogs.com/houj/p/11640627.html
Copyright © 2011-2022 走看看