Dziedzictwo
Zastanów się nad samochodem i autobusem. Są to dwa różne pojazdy. Ale nadal mają wspólne cechy, takie jak układ kierowniczy, hamulce, biegi, silnik itp.
Tak więc dzięki koncepcji dziedziczenia można to przedstawić następująco ...
public class Vehicle {
private Driver driver;
private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
//You can define as many properties as you want here ...
}
Teraz rower ...
public class Bicycle extends Vehicle {
//You define properties which are unique to bicycles here ...
private Pedal pedal;
}
I samochód ...
public class Car extends Vehicle {
private Engine engine;
private Door[] doors;
}
To wszystko dotyczy dziedziczenia . Używamy ich do klasyfikowania obiektów w prostsze formy podstawowe i ich dzieci, jak widzieliśmy powyżej.
Klasy abstrakcyjne
Klasy abstrakcyjne są niekompletnymi obiektami. Aby to zrozumieć, jeszcze raz rozważmy analogię pojazdu.
Pojazd można prowadzić. Dobrze? Ale różne pojazdy są prowadzone na różne sposoby ... Na przykład nie można prowadzić samochodu tak, jak jeździ się rowerem.
Jak więc przedstawić funkcję jazdy pojazdu? Trudniej jest sprawdzić, jaki to pojazd, i prowadzić go własną funkcją; przy dodawaniu nowego typu pojazdu musiałbyś ciągle zmieniać klasę kierowcy.
Nadchodzi rola abstrakcyjnych klas i metod. Możesz zdefiniować metodę napędu jako abstrakcyjną, aby powiedzieć, że każde dziedziczące dziecko musi zaimplementować tę funkcję.
Jeśli więc zmodyfikujesz klasę pojazdu ...
//......Code of Vehicle Class
abstract public void drive();
//.....Code continues
Rower i samochód muszą również określać sposób prowadzenia pojazdu. W przeciwnym razie kod nie zostanie skompilowany i zostanie zgłoszony błąd.
W skrócie ... klasa abstrakcyjna jest częściowo niekompletną klasą z pewnymi niekompletnymi funkcjami, które dziedziczące dzieci muszą określić własne.
Interfejsy
Interfejsy są całkowicie niekompletne. Nie mają żadnych właściwości. Wskazują tylko, że dziedziczące dzieci są w stanie coś zrobić ...
Załóżmy, że masz przy sobie różne rodzaje telefonów komórkowych. Każdy z nich ma inne sposoby wykonywania różnych funkcji; Np .: zadzwoń do osoby. Producent telefonu określa, jak to zrobić. Tutaj telefony komórkowe mogą wybrać numer - to znaczy, że można go wybrać. Przedstawmy to jako interfejs.
public interface Dialable {
public void dial(Number n);
}
Tutaj twórca Dialable określa sposób wybierania numeru. Musisz tylko dać mu numer do wybrania.
// Makers define how exactly dialable work inside.
Dialable PHONE1 = new Dialable() {
public void dial(Number n) {
//Do the phone1's own way to dial a number
}
}
Dialable PHONE2 = new Dialable() {
public void dial(Number n) {
//Do the phone2's own way to dial a number
}
}
//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
Dialable myDialable = SomeLibrary.PHONE1;
SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....
Używając interfejsów zamiast klas abstrakcyjnych, autor funkcji korzystającej z Dialable nie musi martwić się o swoje właściwości. Np .: Czy ma ekran dotykowy lub klawiaturę, Czy jest to telefon stacjonarny czy komórkowy? Musisz tylko wiedzieć, czy można go wybrać; dziedziczy (lub implementuje) interfejs Dialable.
A co ważniejsze , jeśli któregoś dnia zmienisz Dialable na inny
......
public static void main(String[] args) {
Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....
Możesz być pewien, że kod nadal działa idealnie, ponieważ funkcja, która używa dialable, nie zależy (i nie może) od innych szczegółów niż te określone w interfejsie Dialable. Obie implementują interfejs Dialable i to jedyna rzecz, na której zależy jej funkcja.
Interfejsy są powszechnie używane przez programistów w celu zapewnienia interoperacyjności (używaj zamiennie) między obiektami, o ile mają one wspólną funkcję (podobnie jak możesz zmienić telefon stacjonarny lub komórkowy, o ile wystarczy wybrać numer). Krótko mówiąc, interfejsy są znacznie prostszą wersją klas abstrakcyjnych, bez żadnych właściwości.
Pamiętaj też, że możesz implementować (dziedziczyć) tyle interfejsów, ile chcesz, ale możesz rozszerzać (dziedziczyć) tylko jedną klasę nadrzędną.
Więcej informacji
Klasy abstrakcyjne a interfejsy