Interfejs kontra klasa abstrakcyjna w kontekście superklasy

0

Dzień dobry.

Z pewnego powodu potrzebuję wymusić nadpisanie metody toString(). Spróbowałem zrobić to interfejsem, jednak z racji tego, że toString jest w klasie Object to ten kod się skompiluje:

interface MyInterface {
    public abstract String toString(); //wiem, ze public i abstract sa niepotrzebne, ale chce pokazac, ze kod jest prawie taki sam jak nizej
}

public class MyClass implements MyInterface{
}


I do tej pory wszystko jasne, metoda jest w superklasie więc nie mogę oczekiwać, że kompilator mi się wywali. Jednak chce zrobic to samo z klasą abstrakcyjną:

abstract class MyAbstractClass {
    public abstract String toString();
}

public class MyClass extends MyAbstractClass{
}

I już kompilator zgłosi błąd.

Chciałbym prosić o dokładne wytłumaczenie, dlaczego klasa abstrakcyjna będzie wymagała nadpisania metody, która już jest w klasie wyżej, a interface już nie.

1

(będzie potrzebowało potwierdzenia bardziej doświadczonej osoby)
Klasa może mieć tylko jedną bezpośrednią nadklasę. W przypadku z interfejsem tą nadklasą jest Object i wszystko pasuje, jest tam ta metoda.
Ale w przypadku z klasą abstrakcyjną twoją nadklasą staje się właśnie klasa abstrakcyjna i to, co było w Object, już cię nie obchodzi - musisz nadpisać wszystkie abstrakcyjne metody nadklasy, a w tym przypadku twoje toString z klasy abstrakcyjnej nadpisało toString z klasy Object.

0

Brałem to pod uwagę, tyle że jakbym nazwał metodę toStringJeden() to mogę korzystać z metody zwykłej toString(). Wszelkie artykuły interface vs abstract mi nie udzielają odpowiedzi, a ja po prostu z natury jestem ciekawski i się zastanawiam, CZEMU KURCZE TAK.

0

No napisałem ci, że nadpisujesz toString z klasy Object swoim abstrakcyjnym toString. Nadpisujesz, czyli pozbywasz się całkiem tej, która była wcześniej.

Jak robisz tak:

class Tester {
    public String toString() {
        return "tester";
    }
}

to domyślnie klasa Tester dziedziczy po Object i mamy tu nadpisanie metody toString, dzięki czemu użyjesz metody z tej klasy:

Object ob = new Tester();
ob.toString(); //zwróci "tester"

W twoim przypadku klasa abstrakcyjna dziedziczy po Object i też nadpisuje metodę toString. Twoja metoda jest jednak abstrakcyjna, więc wymaga nadpisania później.

2
  1. Wszystkie klasy dziedziczą po Object, także abstrakcyjne. Object nie ma metod abstrakcyjnych. Metoda toString() też jest nieabstrakcyjna. Metody nieabstrakcyjnej nie możesz nadpisać metodą abstrakcyjną.
  2. Interfejsy nie mają wspólnego interfejsu czy klasy nadrzędnej z której by dziedziczyły. Jednak każdy interfejs, który nie rozszerza żadnego innego ma implicite zadeklarowane wszystkie metody z klasy Object, ale w wersji abstrakcyjnej. Szczegóły tutaj: https://stackoverflow.com/a/6227003
0
abstract class MyAbstractClass {
    public abstract String toString();
}

public class MyClass extends MyAbstractClass{
}

I już kompilator zgłosi błąd.

No ale przecież kompilator [pewnie] zgłosił Ci błąd że brak implementacji metody toString().
Chyba w ogóle nie wiesz czym się różni klasa od interfejsu, a o klasach abstrakcyjnych myśl dopiero później.
Interfejs to kontakt - to jakbyś miał urządzenie które wiesz co robi ale nie wiesz czym jest, bardziej opisuje czynności a nie obiekt.
Klasa to takich szablon obiektów, natomiast klasa abstrakcyjna to taki szablon obiektów który nie ma wszystkich części, dlatego w ostatecznej implementacji musisz jej dodać.
I tak tu musisz dodać metodę toString()

0

@ShookTea: znam zasadę, pytałem tylko o ten jeden przypadek, bo przecież interfejs też ma domyślnie oznaczone swoje metody jako abstrakcyjne.
@Slepiec ee przecież napisałem, że kompilator zgłosi błąd w takim wypadku. Zastanawiał mnie brak spójności.
@Wibowit - dzięki, to odpowiada na pytanie i wyczerpuje temat, proszę o zamknięcie.

0
Slepiec napisał(a):

natomiast klasa abstrakcyjna to taki szablon obiektów który nie ma wszystkich części,

to jest nieprawda
moze miec wszystko, ale nie mozesz utworzyc instancji tej klasy.

0
Ponton napisał(a):
Slepiec napisał(a):

natomiast klasa abstrakcyjna to taki szablon obiektów który nie ma wszystkich części,

to jest nieprawda
moze miec wszystko, ale nie mozesz utworzyc instancji tej klasy.

Czyli nie ma wszystkiego -- bo dlaczego nie możesz utworzyć instancji? Czegoś brakuje. Nie zawsze jest to koreślone wprost, czego...

0
Ponton napisał(a):
Slepiec napisał(a):

natomiast klasa abstrakcyjna to taki szablon obiektów który nie ma wszystkich części,
to jest nieprawda
moze miec wszystko, ale nie mozesz utworzyc instancji tej klasy.

a po co wtedy komuś taka klasa abstrakcyjna ?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.