Last active
July 20, 2017 13:19
-
-
Save nicolas-zozol/8c66352cbbad0ab67474a776cf007427 to your computer and use it in GitHub Desktop.
Failing PECS conversion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.robusta.java.pecs; | |
import java.util.ArrayList; | |
import java.util.Collections; | |
import java.util.List; | |
/** | |
* Created by nicorama on 20/07/2017. | |
*/ | |
public class ContravariantHeritage { | |
public static void main(String[] args) { | |
new ContravariantHeritage().launch(); | |
} | |
void launch() { | |
// With super, you don't care what is already in the list | |
// as long as it will allow a Thing to be added; | |
List<? super Bamboo> pandaFood = new ArrayList<>(); | |
pandaFood.add(new Bamboo()); | |
List<Bamboo> food = new OhPanda().getMeals(); } | |
abstract class Restaurant { | |
Kitchen kitchen; | |
public Restaurant(Kitchen kitchen) { | |
this.kitchen = kitchen; | |
} | |
List<? extends Food> getMeals() { | |
List<Food> food = new ArrayList<>(); | |
this.kitchen.build(food); | |
return food; | |
} | |
} | |
interface Kitchen { | |
void build(List<? super Food> dessert); | |
} | |
class PandaKitchen implements Kitchen{ | |
@Override | |
public void build(List<? super Food> dessert) { | |
// PandaRestaurant is a Producer, but here we talk about List | |
// the List IS a consumer of bamboos | |
System.out.println("miam"); | |
dessert.add(new Bamboo()); | |
} | |
} | |
class MeatKitchen implements Kitchen{ | |
@Override | |
public void build(List<? super Food> main) { | |
// PandaRestaurant is a Producer, but here we talk about List | |
// the List IS a consumer of bamboos | |
System.out.println("miam"); | |
main.add(new Meat()); | |
} | |
} | |
class OhPanda extends Restaurant { | |
public OhPanda() { | |
super(new PandaKitchen()); | |
} | |
/** | |
* Huge difference between parameter and return | |
* a return from extended class can be more precise than Original | |
* But as a param, the contract MUST be the same | |
* Example: the equals() function | |
*/ | |
@Override | |
List<Bamboo> getMeals() { | |
List<? super Food> bamboos = new ArrayList<>(); | |
this.kitchen.build(bamboos); | |
return bamboos; /// <<<==== FAIL: would NOT compile | |
} | |
} | |
class Food { | |
@Override | |
public String toString() { | |
return this.getClass().getSimpleName(); | |
} | |
} | |
class Meat extends Food { | |
} | |
class Bamboo extends Food { | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment