jmultimethod

multimethods for Java using annotations
git clone https://logand.com/git/jmultimethod.git/
Log | Files | Refs | LICENSE

DispatchTest.java (5506B)


      1 // Copyright (c) 2009, 2015 Tomas Hlavaty All rights reserved.
      2 
      3 // Redistribution and use in source and binary forms, with or without
      4 // modification, are permitted provided that the following conditions
      5 // are met:
      6 
      7 // Redistributions of source code must retain the above copyright
      8 // notice, this list of conditions and the following
      9 // disclaimer. Redistributions in binary form must reproduce the above
     10 // copyright notice, this list of conditions and the following
     11 // disclaimer in the documentation and/or other materials provided
     12 // with the distribution.
     13 
     14 // Neither the name of jmultimethod nor the names of its contributors
     15 // may be used to endorse or promote products derived from this
     16 // software without specific prior written permission.
     17 
     18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     21 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     22 // COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     23 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     24 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     27 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     29 // OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // FLAW: Java reasons about types of variables instead of values
     32 
     33 // for asteroid example see wikipedia visitor pattern
     34 
     35 package jmultimethod;
     36 
     37 public class DispatchTest {
     38     static class Asteroid {
     39         String id;
     40         public Asteroid(String id) {this.id = id;}
     41         public String id() {return id;}
     42     }
     43     static class Spaceship {
     44         String name;
     45         public Spaceship(String name) {this.name = name;}
     46         public String name() {return name;}
     47     }
     48     static class Static {
     49         static void colide(Asteroid x, Asteroid y) {
     50             System.out.println("AA colide " + x.id() + " with " + y.id());
     51         }
     52         static void colide(Asteroid x, Spaceship y) {
     53             System.out.println("AS colide " + x.id() + " with " + y.name());
     54         }
     55         static void colide(Spaceship x, Asteroid y) {
     56             System.out.println("SA colide " + x.name() + " with " + y.id());
     57         }
     58         static void colide(Spaceship x, Spaceship y) {
     59             System.out.println("SS colide " + x.name() + " with " + y.name());
     60         }
     61         static void colide(Object x, Object y) {
     62             System.out.println("OO colide " + x + " with " + y);
     63         }
     64         static void run() {
     65             run1();
     66             run2();
     67         }
     68         static void run1() {
     69             System.out.println("Static: explicitly typed");
     70             Asteroid a1 = new Asteroid("A1");
     71             Asteroid a2 = new Asteroid("A2");
     72             Spaceship s1 = new Spaceship("S1");
     73             Spaceship s2 = new Spaceship("S2");
     74             colide(a1, a2);
     75             colide(a1, s1);
     76             colide(s1, a1);
     77             colide(s1, s2);
     78         }
     79         static void run2() {
     80             System.out.println("Static: superclass typed");
     81             // here is the problem: the declared variable type is used
     82             // but it should be infered by the compiler instead
     83             Object a1 = new Asteroid("A1");
     84             Object a2 = new Asteroid("A2");
     85             Object s1 = new Spaceship("S1");
     86             Object s2 = new Spaceship("S2");
     87             colide(a1, a2);
     88             colide(a1, s1);
     89             colide(s1, a1);
     90             colide(s1, s2);
     91         }
     92     }
     93     static class Dynamic {
     94         void colide(Asteroid x, Asteroid y) {
     95             System.out.println("AA colide " + x.id() + " with " + y.id());
     96         }
     97         void colide(Asteroid x, Spaceship y) {
     98             System.out.println("AS colide " + x.id() + " with " + y.name());
     99         }
    100         void colide(Spaceship x, Asteroid y) {
    101             System.out.println("SA colide " + x.name() + " with " + y.id());
    102         }
    103         void colide(Spaceship x, Spaceship y) {
    104             System.out.println("SS colide " + x.name() + " with " + y.name());
    105         }
    106         void colide(Object x, Object y) {
    107             System.out.println("OO colide " + x + " with " + y);
    108         }
    109         void run() {
    110             run1();
    111             run2();
    112         }
    113         void run1() {
    114             System.out.println("Dynamic: explicitly typed");
    115             Asteroid a1 = new Asteroid("A1");
    116             Asteroid a2 = new Asteroid("A2");
    117             Spaceship s1 = new Spaceship("S1");
    118             Spaceship s2 = new Spaceship("S2");
    119             colide(a1, a2);
    120             colide(a1, s1);
    121             colide(s1, a1);
    122             colide(s1, s2);
    123         }
    124         void run2() {
    125             System.out.println("Dynamic: superclass typed");
    126             // here is the problem: dispatch is on the declared
    127             // variable type instead of the run-time value type
    128             Object a1 = new Asteroid("A1");
    129             Object a2 = new Asteroid("A2");
    130             Object s1 = new Spaceship("S1");
    131             Object s2 = new Spaceship("S2");
    132             colide(a1, a2);
    133             colide(a1, s1);
    134             colide(s1, a1);
    135             colide(s1, s2);
    136         }
    137     }
    138     public static void main(String args[]) {
    139         Static.run();
    140         new Dynamic().run();
    141     }
    142 }