2016-07-22 11 views
7

Ich möchte einen Typ namens App in einem Satz speichern. App muss eine Enumeration sein, die die App Schnittstelle implementiert.Erzwingen der Implementierer einer Schnittstelle zu einem Enum

Set<App> myApps; 

ich die Schnittstelle wie so definiert haben ...

interface App<T extends Enum<T>> {} 

Dies ist fast arbeiten, zum Beispiel, können Sie dies ... aber

class MyClass implements Application<MyClass> {} 

nicht tun können, können Sie tun Sie dies ...

enum MyEnum implements Application<MyEnum> {} 
class Myclass implements Application<MyEnum> {} 

Was ist falsch. Ich möchte nur, dass Enums diese Schnittstelle implementieren können. Wie kann ich das durchsetzen?

+0

Und genau welche Fehlermeldung erhalten Sie vom Compiler? Bitte bearbeiten Sie Ihren Beitrag, um uns einheitlich * alle * Ihrer Erklärungen zu zeigen. –

+1

@MikeRobinson er bekommt keine Fehlermeldung, das ist das Problem - er will den Compiler über die letzte Deklaration beschweren. ;) – Thomas

+0

@MikeRobinson lies die Frage noch einmal. Es gibt keinen Fehler vom Compiler. OP möchte nur den Implementierer einschränken. – Mena

Antwort

11

eine Methode definieren, die Sie Elemente in dem Satz hinzufügen können, aber eine Einschränkung für diesen Parameter verwenden ...

public <E extends Enum<E> & IMyInterface> void addToSet(final E value) { } 

jetzt danach

addToSet(MyEnum.K) will compile 

aber

addToSet(new Myclass()) will NOT compile 
+2

Schöne Workaround. – Mena

+1

Also ist es fast der gleiche Typ Parameter Zeug außer als Teil einer Methode Deklaration und nicht eine Schnittstelle Deklaration - ordentlich :) – Ogen

+0

Was wird der Typ meines Satzes sein? – Ogen

1

AFAIK es ist nicht möglich, einen Implementierer einer Schnittstelle zu erzwingen, bestimmte Eigenschaften wie Enum zu haben.

jedoch abhängig von Ihrem Code und wie Sie diese Schnittstelle verwenden, können Sie machen es schwer für jemanden nicht Implementierer eine ENUM zu machen:

  • T Erfordern App<T> auch zu implementieren, um vorbei jede Enum zu verhindern die Klassendeklaration (dh App<T extends Enum<T> & App<T>>)
  • Verwenden zusätzliche Grenzen, wenn möglich (siehe ΦXocę 웃 Пepeúpa Antwort)
  • Methoden hinzufügen, die von Enum wie name(), bereits implementiert sind ordinal() , getDeclaringClass() usw.
  • Lassen Sie verlängern Comparable<T>.
  • Wenn möglich, rufen Sie getClass().isEnum(), um diese Eigenschaft zur Laufzeit zu überprüfen. Dies ist nicht ideal, aber es gibt ähnliche Lösungen, die üblicherweise verwendet werden, wie beispielsweise Collections.unmodifiableSet().