Sens używania interfejsów

Sens używania interfejsów
M4
  • Rejestracja:około 9 lat
  • Ostatnio:prawie 9 lat
  • Postów:11
1

Cześć. Mam problem ze zrozumieniem samej idei interfejsów. Wiem jak one wyglądają, jak stosować i teoretycznie wiem co robią, ale wydają mi się one kompletnym bezsensem. Załóżmy mam klasę "kot" i kolejną "pies". Chcę, żeby w każdej z nich była metoda "biegaj()". No i spoko, zrobie interfejs, każda klasa będzie go implementować, ale jaki jest jego sens? Równie dobrze mogę w klasie kot napisać metodę "biegaj" i tak samo w klasie pies, co de facto z interfejsem też robię, no bo przecież te kasy go tylko implementują a ciało metody biegaj każda klasa będzie miała osobno. Więc bez zastosowania interfejsu też będzie wszystko działać. Czy byłby ktoś w stanie łopatologicznie wytłumaczyć mi co on nam daje, oprócz tego, że pokazje, jakie metody klasa musi mieć w sobie zaimplementowane? Dla mnie to jakiś komplety bezsens i niepotrzebne dodatkowe linie kodu... Byłbym wdzięczny, gdyby jakaś mądra głowa wbiła mi to do mojej, pustej:D

Wibowit
  • Rejestracja:około 20 lat
  • Ostatnio:około 2 godziny
1

Interfejsy są po to, by operować na abstrakcjach. Załóżmy, że jest kilka rodzajów produktów, ale każdy rodzaj implementuje ogólny interfejs Item mający metodę getPrice(). Następnie mamy koszyk, który ma metodę getTotalPrice(), który iteruje po liście produktów i sumuje ceny. W innym miejscu metoda getPrice() mogłaby być wykorzystywana do sortowania i filtrowania produktów. Itp, itd...


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
0

Tez mam problem ze zrozumieniem w 100% sensu interfejsów. Dlaczego każda z tych klas produktów nie może mieć swojej metody getPrice() ? Co daje użycie interfejsu? Jaka jest różnica między użyciem interfejsu a bez niego?

Wibowit
  • Rejestracja:około 20 lat
  • Ostatnio:około 2 godziny
2

Jeśli nie będzie wspólnej nadklasy/ interfejsu to wtedy będziesz miał List<Object>, a potem będziesz musiał sprawdzać typy, rzutować i dopiero wywoływać metody. Przy List<Item> możesz przeiterować po liście, na każdym elemencie wywołać getPrice(), zsumować i zwrócić jako getTotalPrice() w koszyku.


"Programs must be written for people to read, and only incidentally for machines to execute." - Abelson & Sussman, SICP, preface to the first edition
"Ci, co najbardziej pragną planować życie społeczne, gdyby im na to pozwolić, staliby się w najwyższym stopniu niebezpieczni i nietolerancyjni wobec planów życiowych innych ludzi. Często, tchnącego dobrocią i oddanego jakiejś sprawie idealistę, dzieli od fanatyka tylko mały krok."
Demokracja jest fajna, dopóki wygrywa twoja ulubiona partia.
GL
  • Rejestracja:około 9 lat
  • Ostatnio:około 5 lat
  • Postów:4
0

Każda z tych klas implementujących interfejs Item przecież ma swoją metodę getPrice(), to jaką zwróci wartość zależy od tego jaką cenę ma dany produkt. W zasadzie interfejsy wymuszają na Tobie dodanie odpowiednich pól i/lub metod (program Ci się nie skompiluje jeżeli Twoja klasa implementuje interfejs i nie dodałeś metod tego interfejsu do ciała tej klasy) przez co odciąża programistę od zbędnego myślenia i zmniejsza ryzyko wystąpienia błędów.

Gjorni
  • Rejestracja:około 12 lat
  • Ostatnio:około 3 lata
2

Wyobraź sobie, że masz taką sytuację:

Kopiuj
public class Main {
    
    public static void main(String[] args) {
        X1 x1 = new X1();
        ...
        X100 x100 = new X100();

        x1.doSomething();
        ...
        x100.doSomething();
    }
}

W tym wypadku jesteś zmuszony wyprodukować około 100 linii kodu tylko po to, żeby wywołać dla każdego elementu xN metodę doSomething(), nawet, jeżeli każda klasa opisująca każdy z tych obiektów implementuje tą metodę w ten sam sposób.

Teraz spójrz na przykład z interfejsem:

Kopiuj
public interface X {
    void doSomething();
}

// Klasy od X1 do X100 implementują interfejs X.

public class Main {

    public static void main(String[] args) {
        X[] objectsImplementingInterfaceX = new X[99];
        
        objectsImplementingInterfaceX[0] = new X1();
        ...
        objectsImplementingInterfaceX[99] = new X100();
        
        someMethod(objectsImplementingInterfaceX);
    }

    static void someMethod(X[] ob) {
        for (X x : ob) {
            x.doSomething();
        }
    }
}

Imlementacja określonego interfejsu przez wiele różnych klas pozwala Ci zebrać wszystkie referencje do tych obiektów do kupy i wywoływać dla nich masowo metody zdefiniowane przez ten interfejs, np. poprzez iterację typu for-each.

=======przerwa na ciasteczko (hit waniliowe)========

A teraz bardziej życiowy przykład. Wyobraź sobie sytuację, w której w jednym miejscu swojego programu masz coś takiego:

Kopiuj
ArrayList<T> ref = new ArrayList<>();

Dalej w kodzie masz natomiast pierdyliard metod, które przyjmują ref jako argument (oczywiście typu ArrayList, żeby było ciekawiej). Jednak pewnego pięknego dnia wydarza się coś cudownego - doznajesz objawienia i stwierdzasz, że zastosowanie LinkedList zamiast ArrayList będzie dużo bardziej spoko. Otwierasz więc IDE i rozwalasz monitor, ponieważ czeka Cię przyjemność ręcznego refactoringu kilku tysięcy linijek kodu. "Ale zaraz, zaraz..." - mówisz - " Czy aby przypadkiem List nie jest interfejsem, który jest implementowany przez ArrayList i LinkedList?" Ze smutkiem stwierdzasz, że tak jest w istocie, przez co żeby uniknąć kłopotów w przyszłości piszesz:

Kopiuj
List<T> ref = new LinkedList<>();

...a także zmieniasz typ parametrów metod z klasowego na interfejs. Przez co jeżeli w przyszłości najdzie Cię ochota, żeby skorzystać z klasy Vector zamiast LinkedList, to po prostu napiszesz w jednym miejscu swojego programu:

Kopiuj
List<T> ref = new Vector<>();

...i voila.

<EDIT/UPDATE>
Jest jeszcze wiele fajnych zastosowań (w tym oparte na interfejsach funkcyjnych), ale ogarnij najpierw podstawy i ułóż sobie to wszystko w głowie :) Trzymam kciuki.


The quieter you become, the more you are able to hear.
edytowany 1x, ostatnio: Gjorni
3

Istotą jest polimorfizm, np:

Kopiuj
class StoperDlaZwierząt{
  Czas mierzCzas( Biegające b ){
    czas.start();
    b.biegaj();
    czas.stop();
    return czas;
  }
}

i wtedy metoda mierzCzas będzie mogła mierzyć czas każdemu zwierzakowi implementującemu interfejs Biegające, który ma metodę biegaj. Na przykład:
stoper.mierzCzas(pies);
stoper.mierzCzas(kot);
itd

To samo możesz osiągnąć przez dziedziczenie, ale dziedziczenie dodatkowo wprowadza hierarchię między klasami, interfejsy są bardziej "anemiczne". Na przykład jak zrobisz bazową klasę Zwierze z metodą biegaj, to może być głupio zrobić klasę Człowiek dziedziczącą po Zwierze. Jeśli użyjesz interfejsu- Człowiek może implementować taki interfejs. Inne typowe interfejsy to Map, Set, List itd, określają interfejs a implementacje/algorytmy mogą być różne.

Black007
  • Rejestracja:ponad 21 lat
  • Ostatnio:5 dni
0

Interfejs jest kontraktem. Określa dostępne metody. Innymi słowy, jeśli twoja klasa implementuje interfejs, czyli spełnia kontrakt, to używający wie, że Kot, Pies, czy inne zwierze implementuje metody zawarte w interfejsie i nie obchodzi go w jaki sposób ten interfejs jest implementowany.

PS: Właśnie zauważyłem, ze Krzywy Młot dobrze to opisał :)


"Nie popełnia błędów tylko ten, kto nic nie robi"
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
0

Interfejs zmniejsza poziom zależności między klasami, ponieważ zwykle nie udostępnia niepotrzebnych śmieci (np. konstruktorów), dzięki czemu klasy te lepiej znoszą zmiany w wykorzystywanych klasach. Ułatwiają też napisanie wymaganej klasy od nowa, zwłaszcza jeśli klasa implementuje kilka interfejsów a nas obchodzi w danym momencie tylko jeden.

Aventus
  • Rejestracja:około 9 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:UK
  • Postów:2235
4

Ale kombinujecie z tymi wyjaśnieniami - "zapomniał wół jak cielęciem był". Kolego, to że wydaje Ci się to bez sensu na tym etapie nauki jest całkowicie normalne. Móże również zająć trochę czasu zanim w pełni zrozumiesz sens używania interfejsów. Ale mówiąc najprościej- masz klasę Kot i Pies. Napisz teraz metodę która weźmie jeden parametr i na rzecz tego parametru wywoła metodę Biegaj(). Podpowiedź: jako typ parametru użyj interfejs.

Jeśli mogę coś poradzić- pamiętaj że wszystko czego uczysz się na tym etapie to głównie nauka mechaniki. W wielu przypadkach nie będziesz widział sensu używania czegoś bo faktycznie w konkretnym przykładzie takiego sensu nie będzie. Dopiero z czasem kiedy człowiek ma styczność z bardziej skomplikowanym kodem pewne mechanizmy nabierają sensu. Sam dobrze pamiętam jak zaczynalem od podstaw. Na początku wszystko uczyliśmy się (na uczelni) pisać w metodzie Main(), kiedy przyszedł czas na metody i funkcje z początku nie widziałem w tym sensu- przecież mogę cały kod walnąć w Mainie i będzie dobrze. Kiedy w końcu pojąłem (a raczej zacząłem pisać więcej kodu) przyszedł czas na obiekty- i znów nie widziałem sensu, przecież mogę mieć tablice z imionami, wiekami itp. I znów po jakimś czasie zobaczyłem w tym sens. Z czasem to po prostu "zaskoczy", pamiętaj tylko że na tym etapie nauki czym bardziej coś wydaje Ci się bez sensu, tym większy jest tego sens ;) Pisz i jeszcze raz pisz, powodzenia.


Na każdy złożony problem istnieje rozwiązanie które jest proste, szybkie i błędne.
caer
  • Rejestracja:około 11 lat
  • Ostatnio:11 miesięcy
  • Postów:465
0

http://www.javaworld.com/article/3044050/learn-java/discover-the-six-roles-that-interfaces-play-in-the-java-language.html

Interfejs mówi klasie w której tworzymy nasze zmienne, że klasy go implementujące są wymienne. Więc zamiast musieć robić osobną zmienną dla każdego zwierzęcia, możemy utworzyć zmienną typu Zwierzę - analogicznie jak przy dziedziczeniu z klasy abstrakcyjnej.
Interfejsy mogą też całkowicie zastępować dziedziczenie, pozbawiając nas wielu problemów z nim związanych.

grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Interfejs wymusza określone zachowania na klasie. Wszystkie metody interfejsu muszą mieć swoją implementacje w klasie (jeżeli nie korzystamy z default), która po nim dziedziczy.

edytowany 1x, ostatnio: grzesiek51114
grzesiek51114
grzesiek51114
@vpiotr - O_o to jest ciekawa funkcjonalność ale nie przeczy temu, że implementacja jednak musi istnieć, co jest warunkiem koniecznym. Niekoniecznie w klasie, która dziedziczy ale musi istnieć.
vpiotr
Tak, ale nie w klasie. Twoje zdanie jest nieprawdziwe.
grzesiek51114
grzesiek51114
Już jest.
PI
  • Rejestracja:około 13 lat
  • Ostatnio:7 miesięcy
  • Postów:227
0

Sens używania interfejsów można porównać do budowy i użytkowania samochodów. Do sterowania samochodem masz urządzenia takie jak kierownice, skrzynię biegów itp. To jest interfejs samochodu. Ty nie musisz znać implementacji tzn. nie masz zielonego pojęcia jaki jest silnik; czy elektryczny, czy na benzynę, na słońce, na paliwo jądrowe; tak samo nie wiesz jak jest zbudowana skrzynia biegów. Nagle zachodzi potrzeba wymiany silnika albo skrzyni biegów. Kierowca ma te same przyrządy do sterowania pojazdem, może nawet nie zauważy, że coś zostało zmienione.
W programowaniu masz analogiczną sytuacje. Jest interfejs i są implementacje. Wymieniasz implementacje, a interfejs zostaje ten sam. Nie musisz wiedzieć nawet, że zostało coś zmienione. To się fachowo nazywa polimorfizm.

edytowany 1x, ostatnio: pioflor
M4
  • Rejestracja:około 9 lat
  • Ostatnio:prawie 9 lat
  • Postów:11
0

Dziękuję Wam za wszystkie odpowiedzi. Niestety dalej nie mogę zrozumieć tego... Ja wiem, że interfejs jest tym, jak to zostało ładnie nazwane, "kontraktem", ale nie mogę zrozumieć po co to jest i wydaje mi się kompletnym bezsensem. Gjorni - javastart chyba z 5 razy przeczytałem i niestety ta lekcja im kompletnie nie wyszła bo jest całkowicie niezrozumiała (za mało szczegółów pewnie). Najbardziej trafia do mnie post kolegi Krzywy Młot bo jest to konkretny, prościutki przykład i powoli coś zaczynam z tego rozumiec (przynajmniej tak mi się wydaje). Może ktoś by zechciał jeszcze podobne przykłady z opisami podać?:) Rozumiem, że jeśli klasa xyz implementuje interfejs abc, to w metodzie, która wygląda tak: metoda(abc argument) mogę jako argument zastosować obiekt klasy xyz, tak?
Proszę was, nie piszcie, że interfejs mówi jak ma się coś zachowywać i zawiera tylko deklaracje metod, bo ja to wiem i własnie z tym mam problem, że wiem ale nie widze sensu:D Tak samo z samochodem - wymieniam implementacje a interfejs zostaje... ok, ale i tak muszę we wszystkich klasach te implementacje zmienić, więc to dla mnie jest właśnie niezrozumiałe - interfejs jest bo jest i nic nie daje (tak to widzę:D ). Może macie jeszcze jakieś fajne przykłady 'z życia' jak kolega Krzywy Młot? Swoją drogą świetne forum. Nie sądziłem, że od razu taką pomoc otrzymam. Dzięki!

Gjorni
Bo im ta lekcja naprawde nie wyszla :) Oparlem sie na ich przykladzie, bo mialem go w glowie, ale go usprawnilem. Wroc do niego za jakis czas i na spokojne przeczytaj. Nie od razu Rzym zbudowano :) Ponizej kolega dal fajny przyklad z samochodami.
FI
filemonczyk
niektorzy tutaj tlumaczacy sa jak ludzie z uczelni nabijajacy ilosc publikacji naukowych i poradnikow "dla poczatkujacych studentow", otwierasz i czytasz, a nastepnie zastanawaisz sie czy ciagle jezyk polski czy juz nie.
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0
  • Zamiast wielodziedziczenia masz interfejsy;

  • Obie rzeczy (abstract, interface) są oparte o dziedziczenie i polimorfizm;

  • Stosując interfejs wymuszasz w klasie odpowiednie zachowania, do których developer musi się dostosować chcąc w swojej klasie dziedziczyć od tego interfejsu (nie mówimy o default). Kiedy dobrze wszystko zaprojektujesz to możesz stosować luźne referencje przekazując np. jako argument metody interfejs, a developer ze swoją klasą musi się podporządkować i do tego dostosować. Pozwala to też na łatwą zmianę klas, które dziedziczą od interfejsu bez konieczności zmiany argumentu metody. Po prostu klasa ma się tak zachowywać i koniec.

  • Prosty przykład: interfejs Samochod z metodami Jedz, ZatrzymajSie, PrzerzucBieg. Po tym interfejsie może dziedziczyć Fiat czy Porsche ale jako argument metody możesz zastosować interfejs: public void Foo(Samochod samochod). Wtedy możesz skorzystać w ciele tej funkcji z metod Jedz, ZatrzymajSie, PrzerzucBieg, bo wiesz, że na pewno posiadają implementację.

edytowany 2x, ostatnio: grzesiek51114
caer
  • Rejestracja:około 11 lat
  • Ostatnio:11 miesięcy
  • Postów:465
1

Zacznijmy od tego czy wiesz co to jest polimorfizm? Miałeś styczność z programowaniem generycznym w stylu List<String>? Jeśli nie, to ciężko ci będzie zrozumieć praktyczny sens interfejsów, możesz albo się doszkolić z tych tematów albo przyjąć to tymczasowo na wiarę. Owszem, musisz tak czy tak tę implementację napisać ręcznie dla każdej klasy, ALE: klasy które korzystają potem z twojego kodu mają pewność, że takie metody tam są i dzięki temu mogą je wywoływać. Nie możesz od tak sobie zrobić zmiennej typu Object i wołać na niej metody szczekaj(), kompilator musi być pewien że pod tą zmienną jest obiekt klasy która posiada taką metodę.

Jaca777
Po co mu do tego styczność z programowaniem generycznym?
caer
Bo tam jest to najczęściej stosowane
Jaca777
? Interfejsy stosuje się w celu odwrócenia zależności, mogę wyobrazić sobie stworzenie interfejsu z parametrami typów albo użytego do określenia type bounds, ale nie wydaje mi się, aby to było ich główne zastosowanie.
caer
Śmiem twierdzić że dla początkującego to jest jedno z głównych zastosowań
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

@marcin43210 najprosciej będzie jak sam dojdziesz do tego po co są interfejsy. Napisz proszę uniwersalną funkcje min która dla podanych 2 obiektów zwraca ten który jest mniejszy.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
DI
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 6 lat
  • Postów:103
2

Myślę, że najprościej zrozumieć to poprzez wzorzec projektowy "Strategia".

Mamy interfejs:

Kopiuj
public interface Car {
          void nitro();
}

Klasy:

Kopiuj
public class Volvo implements Car {
       public void nitro() {
             System.out.println("Volvo likes Nitro");
      }
}
Kopiuj
public class Fiat implements Car {
       public void nitro() {
             System.out.println("Fiat likes Nitro");
      }
}

I teraz np. klasa kierowcy:

Kopiuj
public class Driver {
  
       private Car car;

       public Driver(Car car) {
            this.car = car;
       }

       public void timeToNitro() {
             car.nitro();
      }
}

Do klasy kierowcy przekazujemy intefejs Car zamiast konkretnej klasy, dzięki czemu kompilator wie, że może wywołać metodę nitro, ponieważ znajduje się w tym interfejsie, a my możemy mieć 100 innych samochodów i każdy może zostać przekazany do konstruktora klasy Driver:

Kopiuj
public statoic void main(String... args) {
      Car volvo = new Volvo();
      Driver driver = new Driver(volvo);
      driver.timeToNitro(); // output: "Volvo likes Nitro"
}
grzesiek51114
grzesiek51114
@marcin43210 patrz - dobry przykład. Możesz wywołać car.nitro(), bo masz pewność, że taka metoda jest zaimplementowana - i do tego służą interfejsy. Ale żeby to zrozumieć MUSISZ rozumieć polimorfizm. Nie ma innej drogi.
caer
  • Rejestracja:około 11 lat
  • Ostatnio:11 miesięcy
  • Postów:465
1
Kopiuj
public interface Zwierze {

    public String wydajOdglos();
}

public class Pies implements Zwierze {

    @Override
    public String wydajOdglos() {
        this.szczekaj();
    }
}

public class Kot implements Zwierze {

    @Override
    public String wydajOdglos() {
        this.miaucz();
    }
}

public class Main {

    public static void main() {
        List<Zwierze> list = new LinkedList<>();
        Scanner sc = new Scanner(System.in);
        String in = sc.nextLine();
        if ("pies".equals(in))
            list.add(new Pies());
        else if ("kot".equals(in))
            list.add(new Kot());
        //powtórz wczytywanie ile razy chcesz
        for (Zwierze zwierze : list)
            System.out.println(zwierze.wydajOdglos());
    }
}
caer
raczcie wybaczyć niezgodność z Javą 8 i lekki pseudokod w paru miejscach
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
1

Może CSharpowo bardziej zadziała na wyobraźnie, bo tam każdy interfejs powinien zaczynać się od litery I:

Kopiuj
namespace Sharp {
    interface INoiceable {
        void MakeNoice();
    }

    class Harley : INoiceable {
        public void MakeNoice() {
            Console.WriteLine("Harley: bur bur bur bur bur");
        }
    }

    class Speeder : INoiceable {
        public void MakeNoice() {
            Console.WriteLine("Spreeder: niiiiijuuuuuuuuuuuu");
        }
    }

    class Program {
        static void Main(string[] args) {

            // Lista obiektów INoicable - luźna referencja;
            var vehicles = new List<INoiceable> { new Harley(), new Speeder() };

            // Wywołanie `MakeNoice()` - masz pewność, że taka metoda posiada
            // swoją implementację i nie martwisz się, że jej wywołanie nie zadziała
            // (pomijając oczywiście błedy w jej ciele.
            foreach (var v in vehicles) v.MakeNoice();
        }
    }
}

Wyraźnie tutaj widzisz, że masz listę interfejsów w mainie - każdy obiekt, który będziesz chciał wsadzić do tej listy musi dziedziczyć od INoiseable i mieć implementację MakeNoice(). O to chodzi.

edytowany 2x, ostatnio: grzesiek51114
caer
zastanawiałem się właśnie jak nazwać ten interfejs żeby było zgodnie z konwencjami :D https://i.ytimg.com/vi/a8c5wmeOL9o/maxresdefault.jpg
ŁF
"Noiceable"?
caer
  • Rejestracja:około 11 lat
  • Ostatnio:11 miesięcy
  • Postów:465
1

Na wypadek gdybyś zastanawiał się czy nie można tu po prostu użyć dziedziczenia: niby można, ale Zwierzę, Samochód czy Motor to byłyby klasy abstrakcyjne, same w sobie nie występują w przyrodzie. Jako że wszystkie ich metody również są abstrakcyjne (nie mamy dla nich żadnej wspólnej implementacji) byłoby to dokładnie to samo co interfejs, z tą różnicą że dziedziczyć można tylko po 1 klasie.

M4
  • Rejestracja:około 9 lat
  • Ostatnio:prawie 9 lat
  • Postów:11
0
Shalom napisał(a):

@marcin43210 najprosciej będzie jak sam dojdziesz do tego po co są interfejsy. Napisz proszę uniwersalną funkcje min która dla podanych 2 obiektów zwraca ten który jest mniejszy.

A mógłbyś mi powiedzieć co wg Ciebie oznacza 'uniwersalną'?
public int min(int a, int b)
{
if(a>b)
return b;
else
return a;
}

Tylko, że to mi nie wygląda na uniwersalną bo działa tylko dla intów i nic więcej... Dobrzy mysle?

caer
no, to teraz niech obsługuje takie obiekty jak Pchła, Statek i Księżyc
M4
to nie mam pojęcia... powinienem stworzyć interfejs z funkcją 'min', każdą z tych klas i tam to poimplementować, tak?
caer
bingo. swoją drogą podobny interfejs już w Javie istnieje i nazywa się Comparable
Shalom
@marcin43210 nie kombinuj tylko spróbuj rozwiazać podstawiony przeze mnie problem.
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
1

@marcin43210 tak, tym sie różni funkcja uniwersalna od tej którą napisałeś, że ja chciałbym porównywać różne rodzaje obiektów, nie tylko inty. Ale popatrz na tą swoją funkcje. Polegasz w niej tylko na tym że istnieje operator > dla obiektów a i b. A gdyby go zamienić na metodę isSmaller()? A gdyby to była metoda któregoś z tych obiektów? if(a.isSmallerThan(b)). Świta ci coś?


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
M4
  • Rejestracja:około 9 lat
  • Ostatnio:prawie 9 lat
  • Postów:11
0
Shalom napisał(a):

@marcin43210 tak, tym sie różni funkcja uniwersalna od tej którą napisałeś, że ja chciałbym porównywać różne rodzaje obiektów, nie tylko inty. Ale popatrz na tą swoją funkcje. Polegasz w niej tylko na tym że istnieje operator > dla obiektów a i b. A gdyby go zamienić na metodę isSmaller()? A gdyby to była metoda któregoś z tych obiektów? if(a.isSmallerThan(b)). Świta ci coś?

Nic... :( Znaczy na pewno interfejs musialbym zrobić, ok... ale co dalej to nie wiem. Załóżmy, że w interfejsie będzie ta funkcja, ale problemem jest co ona ma zwracać? Przecież mogą być różne obiekty, więc jak powinna wyglądać jej deklaracja w interfejsie?

edytowany 2x, ostatnio: marcin43210
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

No to tylko siąść i płakać. Bo jak dalej to nie wiem to juz koniec świata. A może odpalisz jednak IDE i spróbujesz POMYŚLEĆ? Pokombinować? Napiszesz sobie trochę kod? Nie, lepiej od razu napisać że nie wiem jak.

Jak to co ona ma zwracać? A co wg ciebie powinna zwrócić metoda isSmallerThan()? Jak dla mnie boolean wystarczy bo metoda mówi czy obiekt X jest mniejszy od Y.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
M4
  • Rejestracja:około 9 lat
  • Ostatnio:prawie 9 lat
  • Postów:11
0
Shalom napisał(a):

No to tylko siąść i płakać. Bo jak dalej to nie wiem to juz koniec świata. A może odpalisz jednak IDE i spróbujesz POMYŚLEĆ? Pokombinować? Napiszesz sobie trochę kod? Nie, lepiej od razu napisać że nie wiem jak.

Jak to co ona ma zwracać? A co wg ciebie powinna zwrócić metoda isSmallerThan()? Jak dla mnie boolean wystarczy bo metoda mówi czy obiekt X jest mniejszy od Y.

Ok, faktycznie... nie pomyślałem. Zaraz wychodzę, ale jak wrócę to napisze wszystko i pokaże co udało mi się wymodzić. Wydaje mi się, że wiem już o co chodzi, ale zweryfikuje to praktyka.

edytowany 1x, ostatnio: marcin43210
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

o_O funkcja ma zwrócić boolean bo odpowiada na pytanie czy aktualny obiekt jest mniejszy od tego podanego. Oczywiście bez genericów trudno byłoby napisać całkiem sensowną implementacje bo jak porównać gruszkę z samochodem :P niemniej możesz sobie wprowadzic na przykład drugą metodę obok isSmallerThan(), nazwijmy tą drugą metodę getMagicScore() która dla każdego obiektu zwraca jakiegoś inta i porównanie opiera się między innymi o tą wartość (ale niekoniecznie każda klasa traktuje tą wartość tak samo!)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
M4
Póki co chcę zrobić tak, żeby porównywane były 2 takie same obiekty i działało to uniwersalnie. Czyli tworzę interfejs, w nim deklaracja 'isSmallerthan()' i teraz np. klasę 'Kot', w której piszę definicję tej funkcji, następnie jakąś klasę "pies", w której tak samo definicja funkcji, tak?
Shalom
Nie wiem, próbuj, kombinuj, MYŚL.
grzesiek51114
grzesiek51114
  • Rejestracja:ponad 11 lat
  • Ostatnio:ponad 4 lata
  • Postów:2442
0

Podpowiem po CSharpowemu:

Kopiuj
    interface IComparable<T> {
        int Compare(T first, T second);
    }

Niech funkcja zwraca:

  • -1 jeżeli first jest mniejszy od second;
  • 1 jeżeli odwrotnie;
  • 0 jeżeli sę równe.

Zamiast T może być double, int, Kaczka, Porsche etc... ale to już w klasie, która implementuje tej interfejs.

edytowany 3x, ostatnio: grzesiek51114
Shalom
Nie mieszajmy chwilowo w to genericsów :P
grzesiek51114
grzesiek51114
no, to teraz niech obsługuje takie obiekty jak Pchła, Statek i Księżyc - już @caer wmieszał :)
Shalom
Nie prawda, bo w tej chwili każdy z nich może być IComparable i tyle.
grzesiek51114
grzesiek51114
Też racja.
0
marcin43210 napisał(a):
Shalom napisał(a):

No to tylko siąść i płakać. Bo jak dalej to nie wiem to juz koniec świata. A może odpalisz jednak IDE i spróbujesz POMYŚLEĆ? Pokombinować? Napiszesz sobie trochę kod? Nie, lepiej od razu napisać że nie wiem jak.

Jak to co ona ma zwracać? A co wg ciebie powinna zwrócić metoda isSmallerThan()? Jak dla mnie boolean wystarczy bo metoda mówi czy obiekt X jest mniejszy od Y.

Ok, faktycznie... nie pomyślałem. Zaraz wychodzę, ale jak wrócę to napisze wszystko i pokaże co udało mi się wymodzić. Wydaje mi się, że wiem już o co chodzi, ale zweryfikuje to praktyka.

Do nazwy funkcji jak dla mnie boolean by pasował

Shakaz
  • Rejestracja:ponad 10 lat
  • Ostatnio:10 miesięcy
  • Postów:184
3

Why interface is useful
Jak dla mnie najlepsze wytłumaczenie interfejsu.

@marcin43210 Przeczytaj i powiedz, własnymi słowami, jak to rozumiesz.

edytowany 2x, ostatnio: Shakaz
grzesiek51114
grzesiek51114
pozamiatał: 981 plusów. :)
Shakaz
Odpowiedź jest tego warta ;)

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.