2016-03-31 5 views
0

Я работаю над проектом, где есть список классов, которые наследуются от абстрактного класса Generator. Он работает как цепочка , где каждый класс создается после другого, вызывая метод generate(). Единственная особенность заключается в том, что каждый Generator передается следующему, так что следующий способ может вызвать некоторые методы предыдущего, чтобы обеспечить непрерывность его работы с теми же предположениями.Как обеспечить аргумент реализует интерфейс

С помощью этой установки я хотел бы разрешить каждому классу в цепочке определять интерфейс, который должен быть реализован предыдущим, чтобы он знал, какие методы он имеет.

Если класс не реализует такой интерфейс, будет отображаться просто ошибка (это инструмент командной строки).

Я изучал несколько возможностей, но я действительно не знаю, как выполнить правильную реализацию этого. Можете ли вы придумать способ сделать это во время компиляции? Должен ли я делать проверки во время выполнения, например instanceof?

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

public abstract class Generator { 
    protected Generator(Object somePrivateStuff) {/* ... */} 
    public abstract void generate(); 
} 

public class SpecialGenerator extends Generator { 
    protected SpecialGenerator(Object o) { super(o); } 
    public void generate() { 
     // Some actual implementation 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     // Dynamically load all the classes extending Generator 
     // via the Reflections library, and call the method generate() 
     // on each one 
    } 
} 

Любая идея будет оценена по достоинству. Заранее спасибо.

+0

Вы можете использовать API отражения для получения и активации методов предыдущего генератора. см. Здесь: https://docs.oracle.com/javase/tutorial/reflect/ –

+0

Я не совсем понимаю дизайн. Вы хотите реализовать какой-то гибридный «цепочка ответственности», где объекты цепочки автоматически обнаруживают некоторые особенности их преемников? – Mena

+0

Это идея @Mena, но со ссылкой на предшественников. Каждый элемент в цепочке должен иметь возможность гарантировать, что предыдущий (который должен быть как-то доступным к текущему) имеет определенные методы. Итак, вы предлагаете мне делать все проверки во время выполнения, @YoavGur? – DanielM

ответ

0

Если вы загружаете классы динамически, e. г. по String имена, instanceof бесполезны, потому что вы не знаете их во время компиляции. Вместо этого, вы должны использовать Class#isAssignableFrom():

for (Class<?> clazz : loaded) { 
    if (Generator.class.isAssignableFrom(clazz)) { 
     // instantiate 
    } else { 
     // print error 
    } 
} 

Не зная, как именно должна быть выполнена конкретизация, то трудно предположить более точный код.