2012-03-01 17 views
7

Załóżmy, że mam interfejs o nazwie Interface i konkretną klasę o nazwie Base, która, aby uczynić rzecz nieco bardziej skomplikowaną, ma ctor, który wymaga pewnych argumentów.Anonimowe rozszerzanie klasy i jednoczesne wdrażanie interfejsu?

Chciałbym stworzyć anonimową klasę, która rozszerzy interfejs Bazy i implementacji.

Coś

Interface get() 
{ 
    return new Base (1, "one") implements Interace() {}; 
} 

To wygląda rozsądne do mnie, ale to nie działa!

(P.S: Faktycznie, Interfejs i baza są również zajęcia Generic: d. Ale będę ignorować faktu, że do tej pory)

+0

Generic rzeczy mogą stać się koszmary, jeśli nie jest zbyt dużo abstrakcji. Niech to będzie proste;) –

Odpowiedz

1

ten scenariusz ma dla mnie niewielki sens. Oto dlaczego: Zakładamy klasę Base to:

class Base { 
    public void foo(); 
} 

i Interface to:

interface Interface { 
    public void bar(); 
} 

Teraz chcesz utworzyć anonimową klasę, która byłaby tak:

class MyClass extends Base implements Interface { 
} 

to oznaczałoby, że MyClass dziedziczy (lub prawdopodobnie przesuwa) metodę bar z Base i musi wdrożyć m etykieta foo z Interface. Jak dotąd tak dobrze, twoja klasa ma te dwie metody w obu kierunkach.

teraz pomyśleć, co się dzieje, kiedy wracają obiekt typu Interface od wybranej metody: można dostać tylko funkcjonalność, która Interface oferty, a mianowicie metoda foo. bar jest zgubione (niedostępne). To prowadzi nas do dwóch przypadkach:

  1. Rozszerzanie Base jest bezużyteczny, ponieważ nie dostać się do wykorzystania jego metod, ponieważ nowy obiekt jest postrzegany jako Interface.
  2. Interface ma także sposób foo, ale oznaczałoby to, że sama Base powinny wdrożyć Interface, więc można po prostu rozszerzyć Base bezpośrednio:
class Base implements Interface { 
    public void foo(); 
    public void bar(); 
} 

class MyClass extends Base { 
} 
+0

Cóż, myślę, że celem "implements Interface" było jedynie wykonanie obsady. Użyję konkretnych przykładów. Mam ViewClass, który rozszerza klasy Collection. Następnie używam tego ViewClass do implementacji zestawu kluczy i zestawu wartości. Załóżmy, że w jakiś sposób mam wszystkie implementacje w ViewClass, co oznacza, że ​​technicznie nie muszę wstawiać żadnego dodatkowego kodu dla zestawu kluczy ani zestawu wartości. Pozostaje mu tylko jeden typ. Oczywiście keySet() musi zwrócić zestaw, podczas gdy values ​​() musi zwrócić kolekcję. Więc, ujmując to inaczej, czy mogę po prostu zrobić [return (Set ) new Base (...)]? – user113454

+0

W jaki sposób anonimowy jest "MyClass"? Ma imię! –

+0

@Jon Skeet, właśnie użyłem nazwy, więc mogę się do tego odnieść w wyjaśnieniu. – Tudor

11

Nie, nie można zrobić z anonimową klasę. Można utworzyć klasę o nazwie w sposób, jeśli naprawdę chcą jednak:

class Base { 
} 

interface Interface { 
} 

public class Test { 
    public static void main(String[] args) { 
     class Foo extends Base implements Interface { 
     }; 

     Foo x = new Foo(); 
    } 
} 

Osobiście bym zazwyczaj ciągnąć to na zewnątrz do statycznej klasy zagnieżdżonej siebie, ale to twój wybór ...

+0

Nie wiedziałem, że możemy mieć klasę wewnątrz metody !!! – user113454

+0

@ user1064918: Jest rzadko używany i nie bez powodu - trudno go odczytać. –

+0

@JonSkeet Mam tę konfigurację, nie wiem, jak to zrobić, niż korzystać z nazwanych klas wewnątrz metody. Są używane tylko do tego, aby typ obsada spełniała oczekiwany typ. https: //gist.github.com/imminent/5248440 Ciekaw jestem, czy znasz inny sposób, czy też uważasz, że jest to uzasadnione uprawnione użycie nazwanych klas za pomocą metody. –