Podczas jednego z moich wywiadów zapytano mnie: „Czy możemy stworzyć instancję abstrakcyjną?”
Moja odpowiedź brzmiała: „Nie, nie możemy”. Ale ankieter powiedział mi: „Źle, możemy”.
Trochę się o to spierałem. Potem kazał mi sam to wypróbować w domu.
abstract class my {
public void mymethod() {
System.out.print("Abstract");
}
}
class poly {
public static void main(String a[]) {
my m = new my() {};
m.mymethod();
}
}
Tutaj tworzę instancję mojej klasy i wywołuję metodę klasy abstrakcyjnej. Czy ktoś może mi to wyjaśnić? Czy naprawdę się myliłem podczas mojego wywiadu?
B
z abstrakcyjnego jedenA
, w trakcie części konstrukcji zB
instancji, który składa się z systememA
„s konstruktora typu wykonawcze obiektu jest faktycznieA
. Jednak tylko tymczasowo.Odpowiedzi:
Nie, nie tworzysz tutaj instancji swojej klasy abstrakcyjnej. Zamiast tego tworzysz instancję anonimowej podklasy swojej klasy abstrakcyjnej. Następnie wywołujesz metodę z referencyjnego odwołania do klasy, wskazując obiekt podklasy .
To zachowanie jest wyraźnie wymienione w JLS - sekcja # 15.9.1 : -
Podkreśl moje.
Ponadto w JLS - sekcja # 12.5 można przeczytać o procesie tworzenia obiektów . Zacytuję tutaj jedno stwierdzenie: -
O pełnej procedurze możesz przeczytać na podanym przeze mnie linku.
Aby praktycznie zobaczyć, że instancja klasy jest anonimową podklasą , wystarczy skompilować obie klasy. Załóżmy, że umieścisz te klasy w dwóch różnych plikach:
My.java:
Poly.java:
Teraz skompiluj oba pliki źródłowe:
Teraz w katalogu, w którym skompilowałeś kod źródłowy, zobaczysz następujące pliki klas:
Zobacz tę klasę
Poly$1.class
. Jest to plik klasy utworzony przez kompilator odpowiadający anonimowej podklasie utworzonej przy użyciu poniższego kodu:Jest więc jasne, że tworzy się inną klasę. Tyle, że ta klasa otrzymuje nazwę dopiero po kompilacji przez kompilator.
Ogólnie rzecz biorąc, wszystkie anonimowe podklasy w twojej klasie zostaną nazwane w następujący sposób:
Liczby te oznaczają kolejność, w jakiej te anonimowe klasy pojawiają się w klasie zamykającej.
źródło
instance of
ainstantiating
. Tworzysz tylko jedną klasę, a tworzony obiekt może być instancją wielu klas z powodu dziedziczenia.Powyższe tworzy instancję anonimowej klasy wewnętrznej, która jest podklasą
my
klasy abstrakcyjnej. Nie jest to jednoznacznie odpowiednik tworzenia instancji samej klasy abstrakcyjnej. OTOH, każda instancja podklasy jest instancją wszystkich jej superklas i interfejsów, więc większość klas abstrakcyjnych jest rzeczywiście tworzona przez utworzenie jednej z ich konkretnych podklas.Jeśli osoba przeprowadzająca wywiad powiedziała „źle!” bez wyjaśnienia i podając ten przykład, jako wyjątkowy kontrprzykład, myślę, że nie wie o czym mówi.
źródło
subclassInstance instanceof SuperClass
zwróci wartość true, więc obiekt jest instancją nadklasy, co oznacza, że nadklasa została zaszczepiona. Ale to tylko semantyczne nitpicking.= my() {};
oznacza, że jest anonimowy realizacji, nie jest proste instancji obiektu, który powinien być:= my()
. Nigdy nie można utworzyć instancji klasy abstrakcyjnej.źródło
Tylko obserwacje, które możesz zrobić:
poly
rozszerzamy
? To jest bezużyteczne ...my.class
,poly.class
ipoly$1.class
Czy możemy utworzyć instancję klasy abstrakcyjnej?
Nie możemy. Możemy stworzyć anonimową klasę (to trzeci plik) i utworzyć ją.
Co o super klasy instancji?
Abstrakcyjna superklasa nie jest tworzona przez nas, ale przez java.
EDYCJA: Poproś go, aby to przetestował
Wyjście jest:
źródło
Serializable s = new Serializable() {};
(co jest całkiem bezużyteczny) i jeśli oznaczone na kod dałobyclass my$3
(lub cokolwiek załączając klasę i numer)Możesz po prostu odpowiedzieć w jednym wierszu
Ale ankieter nadal nie zgadza się, wtedy możesz mu / jej powiedzieć
I, zgodnie z klasą Anonimową, klasa zadeklarowała i utworzyła instancję w tym samym miejscu / linii
Możliwe więc, że osoba przeprowadzająca wywiad byłaby zainteresowana sprawdzeniem poziomu pewności siebie i tego, ile wiesz o operacjach operacyjnych.
źródło
Część techniczna została dobrze omówiona w innych odpowiedziach, a kończy się głównie na:
„Myli się, nie wie rzeczy, poproś go, aby przyłączył się do SO i wszystko wyjaśnił :)”
Chciałbym odnieść się do faktu (wspomnianego w innych odpowiedziach), że może to być stresujące pytanie i jest ważnym narzędziem dla wielu ankieterów, aby dowiedzieć się więcej o tobie i jak reagujesz na trudne i nietypowe sytuacje. Podając ci nieprawidłowe kody, prawdopodobnie chciał sprawdzić, czy się odezwałeś. Aby dowiedzieć się, czy masz pewność, że przeciwstawisz się swoim seniorom w podobnych sytuacjach.
PS: Nie wiem dlaczego, ale mam wrażenie, że osoba przeprowadzająca wywiad przeczytała ten post.
źródło
Klasy abstrakcyjne nie mogą być tworzone, ale można je podklasować. Zobacz ten link
Najlepszym tego przykładem jest
Chociaż klasa Calender ma abstrakcyjną metodę getInstance () , ale kiedy mówisz
Calendar calc=Calendar.getInstance();
calc odnosi się do instancji klasy klasy GregorianCalendar, ponieważ „GregorianCalendar rozszerza Kalendarz ”
Rzeczywiście annonymous typ wewnętrzna pozwala na stworzenie no-name podklasę klasy abstrakcyjnej i instancję tego.
źródło
Odpowiedź techniczna
Klasy abstrakcyjne nie mogą być tworzone - z definicji i projektu.
Z JLS, rozdział 8. Klasy:
Z JSE 6 java doc dla Classes.newInstance ():
Można oczywiście utworzyć konkretną podklasę klasy abstrakcyjnej (w tym anonimową podklasę), a także przeprowadzić rzut typu odwołania do obiektu na typ abstrakcyjny.
A Different Angle Na To - Teamplay & Social Intelligence:
Tego rodzaju nieporozumienia technicznej często zdarza się w prawdziwym świecie, gdy mamy do czynienia z skomplikowanych technologii i specyfikacji legalistycznych.
„Umiejętności ludzkie” mogą być tutaj ważniejsze niż „umiejętności techniczne”. Jeśli rywalizujesz i agresywnie próbujesz udowodnić swoją stronę argumentu, możesz teoretycznie mieć rację, ale możesz także zrobić więcej obrażeń, walcząc / niszcząc „twarz” / tworząc wroga, niż jest to warte. Bądź pojednawczy i wyrozumiały w rozwiązywaniu różnic. Kto wie - może „masz rację”, ale pracujesz nad nieco innym znaczeniem terminów?
Kto wie - choć mało prawdopodobne, to możliwe, że osoba przeprowadzająca wywiad celowo wprowadziła mały konflikt / nieporozumienie, aby postawić cię w trudnej sytuacji i zobaczyć, jak zachowujesz się emocjonalnie i społecznie. Bądź uprzejmy i konstruktywny w stosunku do współpracowników, postępuj zgodnie z radami seniorów i postępuj zgodnie z wywiadem, aby rozwiązać wszelkie problemy / nieporozumienia - za pośrednictwem poczty elektronicznej lub telefonu. Pokazy jesteś zmotywowany i zorientowane na szczegóły.
źródło
Jest dobrze znanym faktem, że
abstract class
może nie być instancja jak wszyscy odpowiedzieli.Gdy program definiuje anonimową klasę, kompilator faktycznie tworzy nową klasę o innej nazwie (ma wzór, w
EnclosedClassName$n
którymn
jest anonimowy numer klasy)Więc jeśli zdekompilujesz tę klasę Java, znajdziesz kod jak poniżej:
moja klasa
poly $ 1.class (wygenerowana klasa „anonimowej klasy”)
ploly.cass
źródło
Nie, nie można utworzyć instancji klasy abstrakcyjnej, tworzymy tylko klasę anonimową. W klasie abstrakcyjnej deklarujemy metody abstrakcyjne i definiujemy tylko konkretne metody.
źródło
O klasach abstrakcyjnych
Celem klasy abstrakcyjnej jest zachowanie się jak baza. W hierarchii dziedziczenia zobaczysz klasy abstrakcyjne u góry.
źródło
Można powiedzieć:
nie możemy utworzyć instancji klasy abstrakcyjnej, ale możemy użyć
new
słowa kluczowego, aby utworzyć anonimową instancję klasy, po prostu dodając{}
jako implementację treści na końcu klasy abstrakcyjnej.źródło
Rozszerzenie klasy nie oznacza, że tworzysz instancję klasy. Właściwie w twoim przypadku tworzysz instancję podklasy.
Jestem całkiem pewien, że klasy abstrakcyjne nie pozwalają na inicjowanie. Powiedziałbym więc „nie”: nie można utworzyć instancji klasy abstrakcyjnej. Ale możesz go rozszerzyć / odziedziczyć.
Nie można bezpośrednio utworzyć instancji klasy abstrakcyjnej. Ale to nie znaczy, że pośrednio nie można uzyskać instancji klasy (a nie instancji oryginalnej klasy abstrakcyjnej). Mam na myśli, że nie możesz utworzyć oryginalnej klasy abstrakcyjnej, ale możesz:
Dzięki temu uzyskujesz dostęp do wszystkich metod i właściwości w klasie abstrakcyjnej za pośrednictwem instancji klasy pochodnej.
źródło
Nie można utworzyć instancji klasy abstrakcyjnej. To, co naprawdę możesz zrobić, to zaimplementować niektóre typowe metody w klasie abstrakcyjnej i pozwolić innym nie zaimplementować (uznając je za abstrakcyjne) i pozwolić konkretnemu zstępującemu zaimplementować je w zależności od ich potrzeb. Następnie możesz stworzyć fabrykę, która zwraca instancję tej abstrakcyjnej klasy (właściwie jego implementatora). Następnie w fabryce decydujesz, który dostawca wybrać. Jest to znane jako wzór fabryczny:
Konkretny implementator musi tylko zaimplementować metody zadeklarowane jako abstrakcyjne, ale będzie miał dostęp do logiki zaimplementowanej w tych klasach w klasie abstrakcyjnej, które nie są zadeklarowane jako abstrakcyjne:
Wreszcie fabryka wygląda mniej więcej tak:
Odbiorca AbstractGridManager wywoływałby na nim metody i uzyskałby logikę, zaimplementowaną w konkretnym descendencie (i częściowo w metodach klasy abstrakcyjnej), nie wiedząc, jaką konkretną implementację otrzymał. Jest to również znane jako inwersja kontroli lub wstrzykiwanie zależności.
źródło
Nie, nie możemy utworzyć obiektu klasy abstrakcyjnej, ale stworzyć zmienną referencyjną klasy abstrakcyjnej. Zmienna referencyjna służy do odwoływania się do obiektów klas pochodnych (podklasy klasy Abstract)
Oto przykład ilustrujący tę koncepcję
Widzimy tutaj, że nie możemy utworzyć obiektu typu Figure, ale możemy utworzyć zmienną odniesienia typu Figure. Tutaj stworzyliśmy zmienną odniesienia typu Rysunek i Rysunek Zmienna odniesienia klasy służy do odniesienia do obiektów klasy Prostokąt i Trójkąt.
źródło
W rzeczywistości nie możemy bezpośrednio stworzyć obiektu klasy abstrakcyjnej. To, co tworzymy, jest zmienną referencyjną wywołania abstrakcyjnego. Zmienna referencyjna służy do odwoływania się do obiektu klasy, który dziedziczy klasę abstrakcyjną, tj. Podklasę klasy abstrakcyjnej.
źródło