Вопрос

Учитывая следующие три класса, как я могу использовать отражение, чтобы вызвать функцию инициализации для родительского класса (ES), а затем подкласс:

public class Test {

    public static void main(String[] args) {
        ExtendedElement ee = new ExtendedElement();
        initialize(ee);
     }

    public static void initialize(Element element) {
        System.out.println(element.getClass());
        initialize(element.getClass());
    }

    public static void initialize(Class clazz) {
        System.out.println(clazz.getClass());
    }
}

public class Element {
    protected String value;
    public String getValue() { return value; }
    public void setValue(String value) { this.value = value; }
}

public class ExtendedElement extends Element {
    protected String extendedValue;
    public void setExtendedValue(String extendedValue) {
        this.extendedValue = extendedValue;
    }
    public String getExtendedValue() { return extendedValue; }
}

Я не совсем уверен, как парамеризировать функцию инициализации в тестовом классе, так как параметр Clazz является необработанным типом.

По сути, мне нужно назвать инициализировать иерархию класса, если то, что я перехожу в инициализацию, является подклассом элемента.

Что -то вроде следующего:

public void initialize(Class clazz) { 
    if (Element.class.isInstance(clazz.getClass().getSuperclass()) {
         initialize(clazz.getClass().getSuperclass());
    }
    //Work to call initialize function 
}

РЕДАКТИРОВАТЬ 1:

Разве я не параметризует вышеуказанную псевдо функцию по -разному, чтобы сохранить тип объекта, а затем вызвать функцию, которая мне нужна?

То, что я пытаюсь сделать, - это избегать необходимости переопределить один и тот же метод для каждого из моих классов и позволить некоторое наследство для моих объектов Selenium 2 страниц. Что мне нужно сделать, так это иметь возможность, так это индивидуальная суперкласс (ES) моего себя и инициализировать каждое из моих полей WebElement до проведения тестов на этих областях.

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

Мне пришлось обернуть WebElements с помощью пользовательского объекта, чтобы я мог внедрить стратегии местоположения, используя Spring (мы повторно используем множество частей, но у них разные имена идентификаторов / классов, зависящие от того, где они используются в приложении; это было сделано ранее Для меня попасть сюда и не будет изменен в это время, несмотря на мои аргументы в пользу последовательности). Например, у нас есть виджет свиданий, который имеет разные детали, иногда нам нужно всего месяц, иногда месяц и год и т. Д. Было бы неплохо, если бы я мог использовать абстрактный класс и разорвать эти общие черты до их наименее общего знаменателя и простирайтесь оттуда. Для этого мне нужно иметь возможность сделать следующее в моем базовом классе:

public abstract class PageObject implements InitializingBean {
    ...
    public void afterPropertiesSet() {
        //Pass in concrete impl we are working with - this allows me to initialize properly
        initializeWebElements(this.getClass());
    }
    ...
    public void initializeWebElements(Class clazz) {
        //This does not grab inherited fields, which also need to be initialized
        for (Field field : clazz.getDeclaredFields()) {
            if (WidgetElement.class == field.getType()) {
                Method getWidgetElement = clazz.getDeclaredMethod("get" +
                    StringUtils.capitalize(field.getName()), new Class [] {});
                    WidgetElement element = 
                      (WidgetElement) getWidgetElement.invoke(this, new Object [] {});
                    element.initElement();
    }
}
Это было полезно?

Решение 3

Вот мое временное решение, оставляя вопрос открытым, чтобы, мы надеемся, собрать некоторые лучшие ответы для моего варианта использования.

public abstract class PageObject implements InitializingBean {
...
public void afterPropertiesSet() {
    Class clazz = this.getClass();
    do {
        initializeElements(clazz);
        clazz = clazz.getSuperclass();
    } while (clazz != null);
}

Другие советы

Вы не можете вызвать метод на определенном уровне. Единственное, что у вас есть доступ к super Ключевое слово внутри самого класса.

Чтобы сделать эту работу, вы хотите позвонить super.initialize() Изнутри каждого подкласса, затем просто назовите его через отражение.

Это не C ++, где вы Можно Вызовите конкретный метод на определенном уровне иерархии наследования.

Я не совсем уверен, как параметризировать функцию инициализации в тестовом классе, так как параметр Clazz является необработанным типом.

Ничто в вашем примере не требует использования параметра общего типа, поэтому объявите его как Class<?>.

Я не понимаю, что на самом деле пытаются сделать ваши методы инициализации, но есть ряд проблем:

Кажется, у тебя есть один initialize метод, который принимает экземпляр (из Element) как аргумент, и другой, который берет Class объект как аргумент. Это действительно яблоки и апельсины ... и вам нужно объяснить, что вы пытаетесь сделать.

Ваша попытка вывести метод содержит это:

Element.class.isInstance(clazz.getClass().getSuperclass())

Это никогда не оценивается до правды, потому что он спрашивает, есть ли некоторые Class объект пример принадлежащий Element учебный класс. (Более того, clazz.getClass().getSuperclass() на самом деле будет таким же, как java.lang.Object.class. Анкет Класс Class объект java.lang.Class И его суперкласс java.lang.Object).

Но я не могу понять, что это должно быть, потому что вы не четко описываете, чего вы пытаетесь достичь.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top