2013-12-14 7 views
5

Ich brauche eine Variable in einer Klasse, die eine Instanz der Klasse "ClassA" ist, die aber auch die Schnittstelle "InterfaceI" implementiert.Membervariable, die Klasse A erweitern und eine Schnittstelle implementieren muss

Offensichtlich kann dies für den einen oder anderen leicht getan werden:

private ClassA mVariable; 
private InterfaceI mVaraible; 

aber wie kann ich das Objekt erzwingen sowohl erweitert KlasseA und implementiert InterfaceB? Etwas wie:

private <? extends ClassA & InterfaceI> mVaraible; 

ist was ich brauche aber ich habe keine Ahnung von der Syntax oder ob es überhaupt möglich ist. Ich werde auch eine Get- und Set-Verfahren benötigen, aber das kann mit Generika erfolgen (ich glaube?)

Die offensichtliche Lösung ist

public class ClassB extends ClassA implements InterfaceI{ 
    //whatever here 
} 

jedoch beide InterfaceI und KlasseA Teil eines externen libary sind, diese Bibliothek hat Klassen, die ClassA und InterfaceI erweitern und ich kann sie nicht bearbeiten, um sie ClassB zu erweitern, daher wird diese Lösung nicht funktionieren.

+1

Sie können nicht, im Grunde. Sie können dies überprüfen, wenn Sie die Variable festlegen, und dann bei Bedarf ..., aber Sie können diese Einschränkung nicht für die Variable selbst ausdrücken, ohne die Klasse als generisch zu definieren. –

+0

In Java8 gibt es etwas Magie, um Mehrfachvererbung oder eine Art Mix-In zu ermöglichen ... – Thufir

+0

@Jon Skeet Wie würden Sie es überprüfen, wenn Sie die Variable setzen? – jtedit

Antwort

1

Ich habe eine ziemlich hacky Abhilfe gefunden.

Die Klasse enthält sowohl einen KlasseA und InterfaceI Referenz wie folgt:

private ClassA mItemClassA; 
private InterfaceI mItemInterfaceI; 

Die Set-Methode dann wie folgt aussieht:

public void setVaraible(ClassA item){ 
    assert (item instanceof InterfaceI); 
    mItemClassA = item; 
    mItemInterfaceI = (InterfaceI) item; 
} 

Andere Variationen könnte dies eine Ausnahme werfen, false zurückgibt usw. wenn das Element keine Instanz von InterfaceI ist

Andere Methoden in der Klasse können dann Funktionen von InterfaceI und ClassA mithilfe von mItemClassAa aufrufen nd mItemInterfaceI.

Ich werde nicht eine get-Methode für jetzt implementieren, aber wenn ich es getan hätte, müsste wahrscheinlich eine Version sein, um die Schnittstelle und eine Version zu erhalten, um die Klasse zu bekommen.

+0

verwenden, stattdessen würde ich Ausnahmen verwenden. Assertions werden standardmäßig nicht aktiviert. Es ist eine zusätzliche Flagge, die Sie einschalten müssen. +1 zw. –

0

Sie können mit den generischen Klasse Typen, da dies tun:

private class ClassB <R extends ClassA & InterfaceI> { 
    R mVaraible; 
}