Cześć! Na poprzednich lekcjach zapoznaliśmy się już pokrótce z koncepcją dziedziczenia. Dzisiaj ponownie poruszymy ten temat, ale znowu niezbyt głęboko. Nadal będziemy mieć bardziej szczegółową lekcję na ten temat w przyszłości. Dzisiaj rzucimy okiem na kilka praktycznych przykładów i zapoznamy się z interesującym operatorem w Javie.
Dziedziczenie to mechanizm programowania (również w Javie), który pozwala zadeklarować nową klasę na podstawie istniejącej. Klasa pochodna uzyskuje następnie dostęp do pól i metod klasy nadrzędnej. Dlaczego mielibyśmy tego potrzebować? Cóż, wyobraź sobie, że musisz utworzyć kilka klas samochodów w programie: Ciężarówka, Wyścigówka, Sedan, Pickup itp. Jeszcze przed napisaniem jakiegokolwiek kodu wiesz na pewno, że wszystkie te klasy mają ze sobą wiele wspólnego: wszystkie samochody mają model nazwa, rok produkcji, wielkość silnika, maksymalna prędkość itp. (nie wspominając o tym, że wszystkie mają wspólne koła i inne części). W tej sytuacji możesz:
Dziedzictwo
Czym zatem jest dziedziczenie?
- Utwórz te pola w każdej klasie (dodając je do każdej nowej klasy samochodu podczas jej tworzenia)
- Przenieś pola wspólne dla wszystkich samochodów do
Car
klasy nadrzędnej, a następnie użyj słowa kluczowego extends , aby wyprowadzić z klasy wszystkie klasy dla określonych typów samochodówCar
.
public class Car {
private String model;
private int maxSpeed;
private int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
}
public class Truck extends Car {
public Truck(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
public class Sedan extends Car {
public Sedan(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
Minimalnie unikamy niepotrzebnego powielania kodu (do czego zawsze powinniśmy dążyć pisząc programy). Ponadto mamy prostą i zrozumiałą strukturę klas, w której wszystkie pola wspólne dla wszystkich samochodów są skonsolidowane w jednej klasie. Jeśli ciężarówki mają jakieś specjalne pola, których nie mają inne samochody, można je zadeklarować w Truck
klasie. To samo dotyczy metod. Wszystkie samochody mają pewne wspólne zachowanie, które można opisać za pomocą metod, np. uruchamianie samochodu, przyspieszanie/hamowanie itp. Te wspólne metody można skonsolidować w klasie nadrzędnej, a każdy określony typ Car
samochodu może definiować swoje unikalne działania w swoich klasach pochodnych .
public class Car {
public void gas() {
// Accelerate
}
public void brake() {
// Brake
}
}
public class F1Car extends Car {
public void pitStop() {
// Only race cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
Do klasy dodaliśmy metody wspólne dla wszystkich samochodów Car
. Ale spójrz na F1Car
klasę, która reprezentuje samochody wyścigowe „Formuły 1”. Pit stopy (postoje w celu pilnej konserwacji samochodu) są wykonywane tylko podczas wyścigów, więc dodaliśmy tę specyficzną funkcjonalność do odpowiedniej klasy pochodnej. 
operator instancji
W Javie istnieje specjalny operator, instanceof , służący do sprawdzania, czy obiekt został utworzony na podstawie określonej klasy. Zwraca true lub false w zależności od wyniku sprawdzenia. Zobaczmy, jak to działa, korzystając z klas w naszym przykładzie samochodu:
public class Truck extends Car {
public static void main(String[] args) {
Truck truck = new Truck();
System.out.println(truck instanceof Car);
}
}
Dane wyjściowe: true Operator instanceof
zwraca wartość true , ponieważ mamy Truck
obiekt, a wszystkie ciężarówki to samochody. Klasa Truck
pochodzi od Car
klasy. Wszystkie ciężarówki są tworzone w oparciu o wspólny element nadrzędny, Car
klasę. Przyjrzyj się dokładnie, w jaki sposób instanceof
operator jest używany. Piszesz to bez kropki, ponieważ jest to operator, a nie metoda („instancja obiektu klasy”). Spróbujmy w inny sposób:
public static void main(String[] args) {
Car car = new Car();
System.out.println(car instanceof Truck);
}
Wyjście: false Klasa Car
(i obiekty samochodów) nie wywodzi się z Truck
klasy. Wszystkie ciężarówki to samochody, ale nie wszystkie samochody to ciężarówki. Car
obiekty nie są oparte na Truck
klasie. Jeszcze jeden przykład:
public static void main(String[] args) {
Car car = new Car();
Truck truck = new Truck();
System.out.println(car instanceof Object && truck instanceof Object);
}
Wyjście: Prawda Tutaj również logika jest prosta: wszystkie klasy w Javie, w tym klasy tworzone przez Ciebie, wywodzą się z klasy Object
(nawet jeśli nie piszesz „rozszerza obiekt” — to już implikowane). Jak i kiedy może się to przydać? Operator instanceof
jest najczęściej używany podczas zastępowania equals()
metody. Oto przykład equals
implementacji metody w String
klasie:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Przed porównaniem a String
z przekazanym obiektem metoda sprawdza, czy obiekt jest nawet ciągiem znaków? Dopiero wtedy zaczyna porównywać właściwości dwóch obiektów. Gdyby ten test nie istniał, każdy obiekt z polami wartości i długości mógłby zostać przekazany do metody i porównany z łańcuchem, co oczywiście byłoby błędne.
GO TO FULL VERSION