2012-04-10 10 views
2

Ich habe eine abstrakte Java-Klasse, die ein Hashcode-Feld hat, das von den konkreten Unterklassen initialisiert werden sollte. Ich dachte, das Initialisierungsverfahren abstrakt zu machen, dhEinstellung von Oberklassenfeldern in der Unterklasse

abstract class A { 
    protected int hashcode; 
    // hashcode should be initialized in constructor 
    protected A() { hashcode = setHashcode(); } 
    abstract int setHashcode() {} // implemented by subclasses 
} 

Aber leider verschiedene Unterklassen müssen für setHashcode in unterschiedlicher Anzahl von Argumenten zu übernehmen, zum Beispiel könnte die Klasse B berechnen hashcode zwei seine Felder und Klasse C könnte mit brauche drei, aber da der Aufruf von super die erste Zeile in Bs Konstruktor sein muss, wird dieses Schema nicht funktionieren. Ich frage mich also, ob es ein anderes Weg/Design-Muster gibt, um dieses Problem zu lösen?

+0

Als Hinweis auf Stil: es umständlich ist, ein Verfahren mit dem Namen 'setSomething()', die keinen Wert gesetzt, sondern gibt den berechneten Wert. 'calculateHashcode' oder' determinateHashcode' könnte die Absicht der Methode besser ausdrücken. –

+0

Sie finden die Informationen möglicherweise in [diese Frage] (http://stackoverflow.com/questions/7223435/java-call-base-method-from-base-constructor) und [diese Frage] (http: // stackoverflow com/questions/7477553/in-java-ist-da-ein-legitim-grund-zu-call-a-non-final-method-from-a-class-co) nützlich. –

Antwort

2

aber da der Aufruf von super dieses Schema die erste Zeile in B Konstruktor sein muss, wird nicht funktionieren

Warum es nicht funktionieren würde? Wenn Sie Berechnungen des Hash-Codes in eine statische Funktion einer Unterklasse eingeben, könnten Sie vorgefertigten Hash-Code an den Konstruktor Ihrer Oberklasse übergeben.

class BaseClass { 
    private int hashCode; 
    protected BaseClass(int hashCode) {this.hashCode = hashCode;} 
} 
class DerivedClass : BaseClass { 
    private static int calcHash(String str) { 
     return str.hashCode(); 
    } 
    public DerivedClass(String s) { 
     super(calcHash(str)); 
    } 
} 
2

Sie nicht wirklich brauchen den Wert in der übergeordneten Klasse zu speichern, erklärt nur ein abstraktes getHashCode, die Unterklassen außer Kraft gesetzt werden.

public abstract class Base { 
    protected abstract int getHashCode(); 
} 

Dies ist besser, weil die "Absicht" der Methode beibehalten wird, unabhängig von ihren Speicheranforderungen.

Übrigens ist hashCode bereits in Object definiert und kann durch Unterklassen überschrieben werden. Wenn Ihr Hash-Code-Konzept anders ist als das, was Object bietet, sollten Sie es vielleicht umbenennen.

1

Es klingt wie eine Schnittstelle für die Initialisierung geeignet sein könnte, so dass alle von Ihnen erstellten Unterklassen die Schnittstellenimplementierung einfach überlasten können.

0

Wechsel:

abstract int setHashcode(); 

An:

abstract int getHashcode(Object...objects); 

Und die Unterklasse muss die Zählung und die Art der Objekte übergeben inspizieren.

Dann machen Sie Anrufe wie:

hashcode = getHashcode(); 
    hashcode = getHashcode(o1); 
    hashcode = getHashcode(o1,o2); 
Verwandte Themen