Home | History | Annotate | Download | only in DefaultMethods
      1 /*
      2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  *   - Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  *
     11  *   - Redistributions in binary form must reproduce the above copyright
     12  *     notice, this list of conditions and the following disclaimer in the
     13  *     documentation and/or other materials provided with the distribution.
     14  *
     15  *   - Neither the name of Oracle nor the names of its
     16  *     contributors may be used to endorse or promote products derived
     17  *     from this software without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
     20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /**
     33  * The sample illustrates rules to resolve conflicts between inheritance
     34  * candidates with <b>default methods</b>. There are two simple rules:
     35  * <ul>
     36  * <li>Class wins. If the superclass has a concrete or abstract declaration of
     37  * this method, then it is preferred over all defaults.</li>
     38  * <li>Subtype wins. If an interface extends another interface, and both provide
     39  * a default, then the more specific interface wins. </li>
     40  * </ul>
     41  */
     42 public class Inheritance {
     43 
     44     /**
     45      * The behavior of an creature that can swim
     46      */
     47     public interface Swimable {
     48 
     49         /**
     50          * Return string representation of the swim action for a creature that
     51          * can swim
     52          *
     53          * @return string representation of the swim action for a creature
     54          * that can swim
     55          */
     56         default String swim() {
     57             return "I can swim.";
     58         }
     59     }
     60 
     61     /**
     62      * The abstract class that overrides {@link #swim} method
     63      */
     64     public abstract static class Fish implements Swimable {
     65 
     66         /**
     67          * Return string representation of the swim action for a fish
     68          *
     69          * @return string representation of the swim action for a fish
     70          */
     71         @Override
     72         public String swim() {
     73             return this.getClass().getSimpleName() + " swims under water";
     74         }
     75     }
     76 
     77     /**
     78      * This class is used for the illustration rule of 1. See the source code
     79      * of the {@link #main} method.
     80      * <pre>
     81      *      System.out.println(new Tuna().swim()); //"Tuna swims under water" output is suspected here
     82      * </pre>
     83      */
     84     public static class Tuna extends Fish implements Swimable {
     85     }
     86 
     87     /**
     88      * The behavior of an creature that can dive: the interface that overrides
     89      * {@link #swim} method (subtype of {@link Swimable})
     90      */
     91     public interface Diveable extends Swimable {
     92 
     93         /**
     94          * Return string representation of the swim action for a creature that
     95          * can dive
     96          *
     97          * @return string representation of the swim action for a creature
     98          * that can dive
     99          */
    100         @Override
    101         default String swim() {
    102             return "I can swim on the surface of the water.";
    103         }
    104 
    105         /**
    106          * Return string representation of the dive action for a creature that
    107          * can dive
    108          *
    109          * @return string representation of the dive action for a creature
    110          * that can dive
    111          */
    112         default String dive() {
    113             return "I can dive.";
    114         }
    115     }
    116 
    117     /**
    118      * This class is used for the illustration of rule 2. See the source code
    119      * of the {@link #main} method
    120      * <pre>
    121      *      //"I can swim on the surface of the water." output is suspected here
    122      *      System.out.println(new Duck().swim());
    123      * </pre>
    124      */
    125     public static class Duck implements Swimable, Diveable {
    126     }
    127 
    128     /**
    129      * Illustrate behavior of the classes: {@link Tuna} and {@link Duck}
    130      *
    131      * @param args command line arguments
    132      */
    133     public static void main(final String[] args) {
    134         // Illustrates rule 1. The Fish.swim() implementation wins
    135         //"Tuna swims under water" is output
    136         System.out.println(new Tuna().swim());
    137 
    138         // Illustrates rule 2. The Diveable.swim() implementation wins
    139         //"I can swim on the surface of the water." is output
    140         System.out.println(new Duck().swim());
    141     }
    142 }
    143