Polimorfizm , funkcje i ich argumenty

0

Cześć Jakoś wcześniej na to nie zwracałem uwagi. Jak widziałem argument funkcji czy w konstruktorze jakąś klasę to ładowałem po prostu tą instancje tej klasy co chcą. Ewentualnie było to tak że parametrem funkcji był jakiś interfejs i nie dało się stworzyć instancji więc robiłem klasę dziedziczącą interfejs. Ale mogła to też być klasa zamiast interfejsu. Doszedłem do wniosku że tak naprawdę nigdy nie wiadomo jaki ma się stworzyć instancje. Bo może trzeba stworzyć instancje jakiejś lepszej klasy która dziedziczy klasę w argumencie jakejś funkcji. Tu zarysowałem problem. Ktoś może pomyśleć że trzeba stwożyć instancję klasa ale tak nie jest bo twórca biblioteki tak zrobił że tak nie jest. Ja stworzyłem jeszcze jedną klasę klasa2 lepsza od klasy. Osoba która widzi tylko zamieniam_zmienne funkcjię pomyśli że trzeba stworzyć klasa() ale to błąd bo trzeba klasa2(). Zilustrowałem problem. Akurat nie używam javy ale język w tych aspektach jest do niej zbliżony. Twórcy frameworków mogli by robić tak jak ja to pokazałem bo dlaczego nie jak coś jest możliwe to prędzej czy później ktoś tak zrobi .

Tu wszystko jest publiczne zaznaczam.

 String zamieniam_zmienne(klasa obiekt) {
  obiekt.funkcja();
  return obiekt.zmienna.toString();
}

class klasa {
int zmienna = 1;
  klasa(int zm) {
    zmienna = zm << 2;
  }
  
  void funkcja() {
    print("nic nie robię");
  }
}

class klasa2 extends klasa {
  klasa2(int zmienna) : super(zmienna);
  void funkcja()//następuje nadpisanie funkcji
  {
    print("robię coś ważnego ważniejszego niż klasa sama nie zapomnij o mnie");
  }
}

void main()
{
 zamieniam_zmienne(klasa2(4));
 zamieniam_zmienne(klasa(4));

}


1

Ktoś może pomyśleć że trzeba stwożyć instancję klasa ale tak nie jest bo twórca biblioteki.

Totalnie nie rozumiem tego zdania XD mógłbyś rozwinąć ?

Osoba która widzi tylko zamieniam_zmienne funkcjię pomyśli że trzeba stworzyć klasa ale to błąd.

Jaki błąd? Nie rozumiem :(

klasa2(int zmienna) : super(zmienna);

Co to za język ma być jak nie Java? Nie trzymaj nas w niepewności.

I podstawowe moje pytanie - jakie jest twoje pytanie w twoim poście? Chociaz podejrzewam jaka może być odpowiedź Zasada podstawienia Liskov

2

Chodzi o to że ktoś pomyśli że trzeba jako argument dać klasa(3) ale to nie będzie działać bo trzeba klasa2(3). Bo ta klasa2 ma funkcje która coś wykonuje. Coś dla nas ważnego. Czego nie robi klasa(3) jako argument

cóż, zawsze jest taki problem i trzeba z tym żyć. Jeśli masz w javie sort które przyjmuje komparator (funkcję porównującą dwa elementy) i zamiast prawdziwej funkcji porównującej napiszesz coś w rodzaju (sorry, napiszę w Scali, bo Javy już nie umiem pisać)

def myComparator[E](element1: E, element2: E): Boolean = true

i w rezultacie zamiast posortownej kolekcji dostaniesz taką samą nieposortowaną jak podałeś jako wejście to jest to wina twórcy metody sort, czy twoja bo dostarczyłeś błędny komparator?

Wszystkiego nie da się ogarnąć typami, zwłaszcza w Javie. w Scali i Haskellu jest troche lepiej bo jest HKT, ale to też nie rozwiązuje wszystkich problemów. Zawsze można zrobić błędną implementację interfejsu. W każdym języku

UPDATE - w Javie można jeszcze klasę zrobić finalną żeby nikt nie mógł pi niej dziedziczyć

2

Problemem jest to, że w takim przykładzie masz nic nie znaczące nazwy metody i klas i może być trudno zrozumieć kontrakt, który realizuje klasa biblioteki/frameworku.

Jeśli dostarczasz implementację interfejsu, która jest zgodna z kontraktem, a coś nie działa, tzn. że wybrałeś zły framework. A jak jeszcze nie ma dokumentacji dla kontraktu, to też wybrałeś zły framework ;)

Jeśli robisz taką klasa2, to musisz pamiętać o LSP (w przeciwnym wypadku, to będzie Twoja wina, a nie frameworka):

Preconditions cannot be strengthened in the subtype.
Postconditions cannot be weakened in the subtype.
Invariants must be preserved in the subtype.
1

Być może pora na "drugą" książkę nt zaawansowanej Javy, zdecydowanie oswajają z kodowanie innym niż "szkolne"

zaawansowane pozycje Horstman, Joshua Bloch, nie wiem czy Bruce Eckel ma jakieś odnowione wydanie Thinking in Java (starsze może nie zawierać lambd z Javy 8)

0

https://dzone.com/articles/the-liskov-substitution-principle-with-examples
tu to ilustrują mniej więcej
Ale ci co używają tych php i innych gdzie są zmienne dynamic. które mogą być wszystkim to mają bardziej przerąbane pod tym względem(w zrozumieniu tych wszystkich mechanizmów może w pracy nad tym nie muszą myśleć). Tak mi się wydaje. Dlatego lubię jak jest podany typ. A język jest silnie typowalny.

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