Frage

In Anbetracht der folgenden drei Klassen, wie ich Reflektion verwenden, um die Initialisierungsfunktion für die Elternklasse aufzurufen (n) und dann die Unterklasse:

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; }
}

Ich bin nicht ganz sicher, wie die Initialisierungsfunktion in der Test-Klasse paramertize, da die clazz Parameter ein Roh-Typ ist.

Was ich im Wesentlichen notwendig ist, initialize bis der Klassenhierarchie zu nennen, wenn was passieren ich in initialize einer Unterklasse von Element ist.

So etwas wie die folgenden:

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

Bearbeiten 1:

Kann ich die obige Pseudo-Funktion nicht parametrieren unterschiedlich die Art des Objekts zu erhalten und rufe dann die Funktion, die ich brauche?

Was ich versuche zu tun, zu vermeiden, die die gleiche Methode für jede meiner Klassen überschrieben haben und einige Erbe für meine Selen 2 Page Objekte zu ermöglichen. Was ich tun muß, ist in der Lage sein zu introspect der übergeordneten Klasse ist (es) von mir selbst und initialisieren jedem meines WebElement zu laufen Tests auf diesen Feldern vor Feldern.

Diese werden mit Feder injiziert und weiter zu komplizieren Dinge, die ich bin so dass Tests geschrieben werden mit Spring Expression Sprache. Ich bin faul Laden meiner Bohnen, und mit Hilfe des InitializingBean Schnittstelle mein WebElements, um zu versuchen, bevor vermeiden NPE ihre Verwendung zu initialisieren.

ich die WebElements mit einem benutzerdefinierten Objekt zu wickeln hatte, so dass ich die Standortstrategien Frühjahr mit injizieren könnte (wir wieder verwenden eine Menge Stücke, aber sie haben unterschiedliche ids / Klassennamen abhängig davon, wo sie in der Anwendung verwendet werden; dies vor mir wurde hier immer getan und wird zu diesem Zeitpunkt nicht trotz meiner Argumente für Konsistenz) geändert werden. Zum Beispiel haben wir ein Datum Widget, das unterschiedliche Körnungen hat, manchmal brauchen wir nur einen Monat, manchmal Monat und Jahr, etc ... Es wäre schön, wenn ich eine abstrakte Klasse verwenden könnte und brechen diese Gemeinsamkeiten bis auf ihren kleinsten gemeinsamen Nenner und erstrecken sich von dort aus. Um das zu tun Ich muss in der Lage, die folgenden in meiner Basisklasse zu tun:

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();
    }
}
War es hilfreich?

Lösung 3

Hier ist meine vorübergehende Lösung, so dass Frage offen, um hoffentlich einige bessere Antworten zu sammeln obwohl für meinen Anwendungsfall.

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

Andere Tipps

Sie können keine Methode auf einem bestimmten Niveau nennen. Das einzige, was ist es, Ihnen den Zugang zum super Schlüsselwort innerhalb der Klasse selbst haben.

Um diese Arbeit zu machen, möchten Sie super.initialize() aus jeder Unterklasse nennen, dann ist es nur durch Reflexion zu nennen.

Dies ist nicht C ++, wo Sie können rufen Sie eine bestimmte Methode auf einer bestimmten Ebene der Vererbungshierarchie.

Ich bin nicht ganz sicher, wie die Initialisierungsfunktion in der Test-Klasse zu parametrieren, da die clazz Parameter ein Roh-Typ ist.

Im Moment in Ihrem Beispiel erfordert, dass Sie die Verwendung des generischen Typparameters zu machen, so erklärt es als Class<?>.

Ich verstehe nicht, was Ihre initialize Methoden wirklich versuchen zu tun, aber es gibt eine Reihe von Problemen:

Sie scheinen eine initialize Methode zu haben, die eine Instanz (von Element) als Argument übernimmt, und eine andere, die ein Class Objekt als Argument. Das ist wirklich Äpfel und Orangen Sachen ... und Sie müssen erklären, was Sie zu tun versuchen.

Ihr Versuch, die Methode Ausfüllung enthält diese:

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

Das wird nie als wahr ausgewertet, weil es zu fragen, wenn einige Class Objekt ein Instanz der Element Klasse. (Was mehr ist, clazz.getClass().getSuperclass() ist eigentlich vor sich geht gleich wie java.lang.Object.class sein. Die Klasse eines Class Objekt ist java.lang.Class und seiner übergeordneten Klasse ist java.lang.Object).

Aber ich kann nicht herausfinden, was es sein sollte, weil man nicht eindeutig beschreiben, was Sie erreichen wollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top