2016-06-10 43 views
1

Es ist eine ziemlich lange Zeit her, seit ich mit Java Abstraction und/oder Interfaces herumgespielt habe, aber ich komme jetzt zurück für ein Projekt und etwas geht mir auf die Nerven. Unten ist ein Ausschnitt meines Codes.Java Abstraktion und Interfaces

public class A { 

    private static String name = "None"; 
    private static String description = "No description"; 

    public A() {} 

    public A(User user) { 
     user.setData(this); 
    } 

    public static String getName() { 
     return name; 
    } 

    public static String getDescription() { 
     return description; 
    } 

} 

public class B extends A { 

    private static String name = "B"; 
    private static String description = "This is B"; 

    public B() {} 

    public B(User user) { 
     super(user); 
    } 

} 

public class User { 

    private A a; 

    public void setData(A a) { 
     this.a = a; 
    } 

    public A getData() { 
     return a; 
    } 

} 

Als ich B.getName() verwende ich erwarten, dass es "B" zurückzukehren, aber es ist stattdessen "None" zurück.

Jetzt mache ich offensichtlich etwas falsch, und die Suche herum half nicht ein bisschen. Ich bin ziemlich sicher, dass dies irgendwie möglich ist, wenn ich nicht mit einer anderen Sprache verwechselt werde.

Könnte mir bitte jemand in die richtige Richtung zeigen? Vielen Dank.

+0

Statische Felder funktionieren nicht so. – SLaks

Antwort

2

Willkommen zurück in Java wieder. Sie verwenden statische Variable in Klasse A und B. Diese Variablen sind der Klasse statt den Objekten zugeordnet.

Wenn Sie Ihre Methode ändern, um den Namen vom Benutzer zu erhalten, wird es wie erwartet funktionieren.

4

Sie haben die getName-Methode für die Klasse B aufgerufen. B hat keine statische Methode namens getName, also sucht sie in der Oberklasse A, was der Fall ist.

Vielleicht erwarten Sie, dass Bs Version des Namens A's überschreibt? Variablen werden nicht außer Kraft gesetzt. A greift auf den Namen der statischen Variable zu, der auf A definiert ist. Die Methode, die ursprünglich von B aufgerufen wurde, beeinflusst dies nicht.

Vererbung und statische Methoden funktionieren nicht gut zusammen. OO-Konzepte wie Polymorphismus beruhen auf Laufzeit-Dispatching, das Wort static sollte das Gegenteil davon implizieren. Beim Polymorphismus arbeitet das Programm auf einer hohen Abstraktionsebene, indem es sich auf die Objekte durch einen Super-Typ bezieht und die Unterklassen die Details ausarbeiten lässt. Bei statischen Methoden müssen Sie auf die spezifische Unterklasse verweisen, für die die Methode aufgerufen werden soll, sodass Sie diese Abstraktionsebene nicht haben.

0

Sie müssen die Methode getName außer Kraft zu setzen():

public class B extends A { 

    private static String name = "B"; 
    private static String description = "This is B"; 

    public B() {} 

    @Override 
    public static String getName() { 
     return name; 
    } 

    public B(User user) { 
     super(user); 
    } 

} 
0

Das Problem Sie konfrontiert sind, liegt in der Definition der Methoden getName und getDescription: Sie sind in der Klasse definiert A als statische Mitglieder. Dies bedeutet, dass selbst beim Aufruf von B.getName() der tatsächliche Aufruf A.getName() ist und der Wert für die statische Elementvariable name auf None gesetzt ist.

Wenn Sie über Vererbung nachdenken, müssen Sie vorsichtig sein, was Sie als statisch deklarieren. Dies hat nichts mit Interfaces oder abstrakten Klassen zu tun.

public class A { 

    protected String name = "None"; 
    protected String description = "No description"; 

    public A() {} 

    public A(User user) { 
     user.setData(this); 
    } 

    public String getName() { 
     return name; 
    } 

    public String getDescription() { 
     return description; 
    } 

} 

public class B extends A { 

    public B() { 
     name = "B"; 
     description = "This is B" 
    } 

    public B(User user) { 
     super(user); 
    } 

} 

public class User { 

    private A a; 

    public void setData(A a) { 
     this.a = a; 
    } 

    public A getData() { 
     return a; 
    } 

} 

Mit dem protected Schlüsselwort können Sie die Felder aus der erweiterten Klasse zugreifen.

Siehe auch:

0

Ein paar Dinge in der Klasse zu beachten:

  1. Namen und eine Beschreibung sind statische Variablen sowohl in der A und B
  2. getName ist eine statische Methode in einer

statischen Variablen werden auf die Klasse und den statischen Methoden gebunden ist, kann nicht

0

Dies ist außer Kraft gesetzt werden, da das erwartete Verhalten getName() Methode der Klasse A hat Zugriff auf Member-Variable seiner eigenen Klasse, die "Name" der Klasse A ist. Es ist NICHT wegen des Namens ist statische selbst wenn Sie es nicht-statische machen und Sie darauf zugreifen, wie in unten Code-Snippet angezeigt würde es "None" zurückgeben. Denken Sie daran, dass nur Methoden nicht Membervariablen überschrieben werden. Also "Name" der Klasse B überschreibt nicht "Name" der Klasse "A".

B b = new B(); 
    System.out.println(b.getName()); --> "None" ("name" is non-static) 
    ---------------------------------------------- 
    System.out.println(B.getName()); --> "None" ("name" is static) 

Auch, wenn Sie wollen „B“ als Ausgabe zu erhalten, außer Kraft setzen Methode getName() der Klasse A in der Klasse B und machen Methode und variable nicht-statisch.