2013-02-06 4 views
0

После выполнения некоторого чтения, кажется, что можно использовать оператор & требует многократного распространяется: Class<T extends Class1 & Class2> classObj;Java: не оператор подстановки ограничивающей

Однако я искал способ для обеспечения «не» функциональность во время компиляции. У меня есть пример, где Банан расширяет Фрукты. Тем не менее, я после того, как что-то вдоль линий:

public abstract class Fruit 
{ 
    public abstract String getFlavour(); 
} 

public class Lemon extends Fruit 
{ 
    @Override 
    public String getFlavour() 
    { 
     return "sour"; 
    } 
} 

public abstract class Banana extends Fruit 
{ 
    @Override 
    public String getFlavour() 
    { 
     return "very sweet!"; 
    } 

    public abstract String getBananaRipeness(); 
} 

public class UnripeBanana extends Banana 
{ 
    @Override 
    public String getBananaRipeness() 
    { 
     return "unripe"; 
    } 
} 

... 
    public String methodThatTakesFruitClassButNotBanana(Class<? extends Fruit ! Banana> fruitClass) 
    { 
     Fruit fruit = fruitClass.newInstance(); 
     return fruit.getFlavour(); 
    } 

... 
     methodThatTakesFruitClassButNotBanana(Lemon.class); // I want this to compile. 
     methodThatTakesFruitClassButNotBanana(UnripeBanana.class); // I want this not to compile. 

Очевидно Class<? extends Fruit ! Banana> не является допустимым синтаксисом. Какие подходы вы могли бы рекомендовать для обеспечения такого типа иерархии типов во время компиляции?

+5

Я не думаю, что есть простой способ сделать это - легче было бы сделать исключение во время выполнения. Но я бы поставил под вопрос дизайн, прежде чем пытаться найти обходное решение. Если вы можете что-то сделать с фруктами, которые нельзя сделать с бананом, то либо ваш банан не является плодом, либо, скорее всего, вы добавили слишком много материала в Фрукты, который не применим ни к каким фруктам. – assylias

+0

@assylias -> вы ударили ноготь по голове. Банан действительно есть Фрукты, но в нашем дизайне это похоже на то, что он расширил еще один Фрукт - его нужно было наклеить выше в иерархии, а не там, где он есть. – studro

ответ

4

общественность Строка methodThatTakesFruitClassButNotBanana

Это полная противоположность Лиск принципа замещения и как полиморфизм работает. Начиная с Banana extends Fruit существует требование, чтобы любой метод, принимающий Fruit, принимает Banana.

Если вам нужно, вам нужно проверить динамический тип и исключить исключение, компилятор не сможет этого сделать для вас.

+0

Я полностью согласен. У нас есть единая тестовая структура, которая берет Бананы (среди других вещей, которые не являются плодами), и мне нужно расширить ее для работы с лимонами, апельсинами, яблоками и т. Д. Бананы в этой структуре обрабатываются по-разному с другими фруктами. Проблема с дизайном - неотъемлемая проблема, которая на самом деле больше похожа на бананов, которые расширяют лимон. Бананы были слишком завышены в иерархии. Тем не менее, это не то, что я могу изменить, поэтому мне придется идти с жестким (runtime) сбоем. Большое спасибо. :) – studro

 Смежные вопросы

  • Нет связанных вопросов^_^