Polimorfizm - interfejsy, specyficzne metody.

0

Dzień dobry,
Przerabiam aktualnie interfejsy i w javastart jest napisane "Dodawanie własnych metod (do klasy implementującej interfejs) nie jest jednak dobrym podejściem, ponieważ tracimy w ten sposób nieco możliwości jakie niesie ze sobą polimorfizm - aby móc korzystać z metod, których nie ma w interfejsie zarówno typ referencji jak i typ obiektu muszą być zgodne - użycie interfejsu wydaje się wtedy zbędne.". Nie rozumiem tego zdania po myślniku jest ktoś w stanie to wyjaśnić?

Druga sprawa:

Interfejsy mogą być wykorzystywane polimorficznie, tzn można ich używać jako typu ogólniejszego klas, które go implementują, poprawne zapisy na podstawie powyższych przykładów to:

1 Pojazd rower = new Rower();
2 Pojazd samochod = new Samochod();

Obowiązkiem jest tworzenie w taki sposób obiektów? Co jeśli klasa implementuje kilka interfejsów, co wtedy ma być w miejscu Pojazd przy tworzeniu obiektu? Jak napisalem Rower rower = new Rower(); też zadziałało więc w czym rzecz?

Dziękuje wam za wszelaką pomoc. Pozdrawiam i Życzę Wesołych Świąt ;).

0
Mały Polityk napisał(a):

Druga sprawa:

Interfejsy mogą być wykorzystywane polimorficznie, tzn można ich używać jako typu ogólniejszego klas, które go implementują, poprawne zapisy na podstawie powyższych przykładów to:

1 Pojazd rower = new Rower();
2 Pojazd samochod = new Samochod();

Obowiązkiem jest tworzenie w taki sposób obiektów? Co jeśli klasa implementuje kilka interfejsów, co wtedy ma być w miejscu Pojazd przy tworzeniu obiektu? Jak napisalem Rower rower = new Rower(); też zadziałało więc w czym rzecz?

Prędzej czy później trafisz na mechanizm wstrzykiwania zależności, w którym unika się używania słowa kluczowego "new". Podajemy nazwę interfejsu i kontener/framework, sam utworzy dany obiekt i wówczas wygląda to następująco:

 @Inject
private Pojazd pojazd;

W tym przypadku operujesz jedynie na interfejsie i w przypadku zmiany implementacji (stwierdzamy jednak, że pojazdem nie będzie rower, a hulajnoga) w klasie wykorzystującej interfejs nie musimy wykonywać żadnych modyfikacji.
Inna sprawa, że zdefiniowanie typu zmiennej, jako typu, który implementuje interfejs sprawia, że możesz mieć dostęp do metod, które są dostępne jedynie w tej klasie, a nie w interfejsie, co utrudnia później zmianę pojazdu na inny.

0

Pierwszy problem rozumiem, dodawanie specyficznych metod koliduje z polimorfizmem. Jak dodałem do klasy Cross.java własną metodę to przy obiekcie Pojazd cross = new Cross(); ta metoda nie działała tylko jedynie te z interfejsu. Ale jeśli utworzyłem obiekt Cross cross = new Cross(); to działała już tak samo jak reszta metod z interfejsu. Jak dodałem interfejs Teren do klasy Cross.java a w nim metodę teren to w obiekcie Pojazd cross = new Cross(); metoda teren nie działała a z Cross cross = new Cross(); działała. I co zrobić w takim wypadku? W ogóle Cross cross = new Cross(); jest dozwolone jeśli klasa Cross implementuje interfejsy...?

10

Twój kod i przykład jest za prosty, żeby zobaczyć sens polimorfizmu. Dodatkowo interfejs Pojazd to bardzo kiepski interfejs.
**Interfejs ** powinien opisywać - co chciałbyś z obiektem zrobić.
Załóżmy np. że chciałbyś zapisywać do pliku Identyfikator przejeżdzającego pojazdu. Bo np. robisz oprogramowanie dla Parkingu.
I mogłbyś napisać metodę: (uwaga kody nie są kompletne i się nie kompilują)


 public void zapisz(Samochód jakisSamochod) {
... 
   plik.write("identyfikator to:" + jakisSamochód.dawajNoTabliceRejestracyjną());

}
 

I powiedzmy, że masz już taki samochód to mozesz wtedy tą metodę wywołać:


Samochod  mojaUlubionaŁada = new Łada("KSU 8590");
//i potem 
zapisz( mojaUlubionaŁada);

działa proste. I nie ma interfejsów. I dobrze.

Ale załóżmy, żę twój parkingowy interes się rozkręca i teraz wchodzisz na rynek międzyplnetarny. Mogą już parkować nie tylko samochody, ale tez rakiety (ba !na jednym parkingu. I rozlicza się wszystko w jednym automacie (pozostaje pytanie jak zrobisz szlaban wyjazdowy dla rakiety, ale to problem gości od hardware).
No i ląduje jakiś Bogdan swoją rakietą.

 Rakieta rakietaBogdana = new Orzeł(7);

I chcesz zapisać numery rejestracyjne... a tu problem metoda zapisz potrzebuje Samochodu... Pech.
Ale w sumie wiemy, że to hipotetyczny problem, bo byłeś sprytny i tak naprawdę zrobiłeś metodę zapisz tak:


 public void zapisz(IdentyfikowalnaRzecz cośTam) {
... 
   plik.write("identyfikator to:" + cośTam.dawajNoIdentyfikator());

}
 

Wtedy Samochod i Rakieta wyglądają tak:

class Samochód implements IdentyfikowalnaRzecz {

    private final String tablica;
   ... 

    public String dawajNoIdentyfikator() {
             return this.tablica;
    }
}

class Rakieta implements IdentyfikowalnaRzecz {


    priate final int id;
   ... 

    public String dawajNoIdentyfikator() {
             return this.getTyp()+ ":" + this.is ;
    }

    abstract String getTyp() ;

}

class Orzeł extends Rakieta {
     ..
  Strign getTyp()  {
     return "Orzeł";
  }

}

Przy okazji Orła widać, że klasy implementujące interfejsy mogą dodawać własne metody, czasem jest to użyteczne, wskazane.

A co z implementowaniem dwóch lub więcej interfejsów. To tak np. jakbyś miał w parkingu jeszcze jedną usługe - mycie.
I wtedy piszesz metodę -

CośCzystego myj (CośUmywalnego brudnaRzecz) {
  return susz(polejWodą(woskowanie(polejWodą(szamponem(polejWodą(brudnaRzecz))))));

}

No i wtedy np. Samochód implements CośIdentyfikowalnego, CośUmywalnego
i Rower też,
a Rakieta nie (bo brud i tak odpadnie przy wchodzeniu w atmosferę).

0

Wielkie dzieki szczegolnie dla Jarka za dobry przyklad i opis! Temat mozna zamknac.

1 użytkowników online, w tym zalogowanych: 0, gości: 1