Skip to content

Instantly share code, notes, and snippets.

@nicolas-zozol
Created July 20, 2017 12:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicolas-zozol/37748839e4bcfeaaf7cec914fb2442ce to your computer and use it in GitHub Desktop.
Save nicolas-zozol/37748839e4bcfeaaf7cec914fb2442ce to your computer and use it in GitHub Desktop.
Working PECS heritage
public class ContravariantHeritage {
public static void main(String[] args) {
new ContravariantHeritage().launch();
}
void launch() {
List<Bamboo> food = new OhPanda().getMeals();
System.out.println(food);
}
abstract class Restaurant<F extends Food> {
Kitchen<F> kitchen;
public Restaurant(Kitchen kitchen) {
this.kitchen = kitchen;
}
abstract List<? extends Food> getMeals();
}
interface Kitchen<F extends Food> {
void build(List<? super F> plate);
}
class PandaKitchen implements Kitchen<Bamboo>{
@Override
public void build(List<? super Bamboo> dessert) {
System.out.println("Adding Bamboo to plate");
dessert.add(new Bamboo());
}
}
class MeatKitchen implements Kitchen<Meat>{
@Override
public void build(List<? super Meat> plate) {
System.out.println("Adding Meat to plate");
plate.add(new Meat());
}
}
class OhPanda extends Restaurant {
public OhPanda() {
super(new PandaKitchen());
}
@Override
List<Bamboo> getMeals() {
List<Bamboo> bamboos = new ArrayList<>();
this.kitchen.build(bamboos);
return bamboos;
}
}
class Food {
@Override
public String toString() {
return this.getClass().getSimpleName();
}
}
class Meat extends Food {}
class Bamboo extends Food {}
}
@tobit800
Copy link

You can get rid of ? extends ...
`
import java.util.ArrayList;
import java.util.List;

public class ContravariantHeritage {

public static void main(String[] args) {
	new ContravariantHeritage().launch();
}
void launch() {
    List<Bamboo> food = new OhPanda().getMeals();
    System.out.println(food);
}


abstract class Restaurant<F extends Food>  {
    Kitchen<F> kitchen;

    public Restaurant(Kitchen kitchen) {
        this.kitchen = kitchen;
    }

    abstract List<? extends Food> getMeals();
}

interface Kitchen<F extends Food>  {
    void build(List<F> plate);
}

class PandaKitchen implements Kitchen<Bamboo>{

    @Override
    public void build(List<Bamboo> dessert) {
        System.out.println("Adding Bamboo to plate");
        dessert.add(new Bamboo());
    }
}

class MeatKitchen implements Kitchen<Meat>{

    @Override
    public void build(List<Meat> plate) {
        System.out.println("Adding Meat to plate");
        plate.add(new Meat());
    }
}


class OhPanda extends Restaurant {

    public OhPanda() {
        super(new PandaKitchen());
    }

    @Override
    List<Bamboo> getMeals() {
        List<Bamboo> bamboos = new ArrayList<>();
        this.kitchen.build(bamboos);
        return bamboos;
    }
}


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