Dziedziczenie klas abstrakcyjnych
Klasy abstrakcyjne mogą dziedziczyć od innych klas nie-abstrakcyjnych oraz od klas abstrakcyjnych tak, jak zwykłe klasy. Nie ma ograniczenia liczby poziomów dziedziczenia w drzewie hierarchii dziedziczenia klas abstrakcyjnych.
W klasie abstrakcyjnej dziedziczącej od innej klasy abstrakcyjnej nie muszą występować metody abstrakcyjne zadeklarowane w klasie nadrzędnej (klasie przodka), jeśli na danym poziomie abstrakcji nie są one implementowane. Te metody abstrakcyjne będą musiały być zaimplementowane w klasie potomnej, nie-abstrakcyjnej, która będzie znajdować się na końcu łańcucha dziedziczących od siebie klas abstrakcyjnych.
Przykład dziedziczenia klas abstrakcyjnych - bardziej zaawansowany:
Kolor BŁĘKITNY - klasy realnych obiektów (nie-abstrakcyjne);
Kolor ZIELONY - klasy abstrakcyjne;
Kolor FIOLETOWY - interfejsy
Aby wyświetlić diagram w pełnej rozdzielczości w osobnej karcie, kliknij tutaj: _img/Vehicles_UML_model_abstract_class_inheritance_01.png

Odpowiadający temu modelowi kod w języku Java:
// Pojazd kołowy - realna klasa, implementująca wszystkie metody wspólne dla każdego pojazdu na kołach.
public class WheeledVehicle
{
public String name;
public int currentSpeed; // bieżąca prędkość
// Tocz się na kołach
public void rollOnWheels( int speed ) {
// tutaj implementacja procesu toczenia z określoną prędkością
}
// Zahamuj
public void brake() {
// tutaj implementacja procesu hamowania do zatrzymania
}
}
// Skręcający pojazd kołowy - w tej klasie wys†ępuje metoda turn() realizująca zakręcanie pojazdu. Ale w różnych pojazdach proces
// zakręcania przebiega różnie i dlatego ta metoda i klasa musi być abstrakcyjna. Inaczej skręca pojazd ze skrętnymi przednimi
// kołami, inaczej pojazd ze skrętnymi tylnymi, a jeszcze inaczej pojazd z przebugem między przednią a tylną osią.
public abstract class TurningWheeledVahicle extends WheeledVehicle
{
public int movingDirection; // Kierunek poruszania się pojazdu
public abstract void turn( int angle ) ;
}
// Silnikowy pojazd kołowy - w naszym schemacie dziedziczy od skręcającego pojazdu kołowego
public abstract class WheeledMotorVehicle extends TurningWheeledVahicle
{
public int engineElectricalSystemVoltage; // napięcie w układzie elektrycznym silnika
public int engineRotationSpeed; // bieżąca prędkość obrotowa silnika
// Ustaw określone obroty silnika - ten proces przebiega zupełnie inaczej w silnikach spalinowych,
// a inaczej w silinikach elektrycznych. Dlatego ta metoda jest abstrakcyjna.
public abstract void setEngineRotationSpeed( int targetEngineRotationSpeed ) ;
public void turnEngineOff() {
// Tutaj implementacja procesu wyłączenia silnika - odcięcie prądu w układzie elektrycznym silnika
}
}
// Kołowy pojazd elektyczny - w tej klasie znajduje się tylko jedna metoda nie-abstrakcyjna z implementacją. Jest to metoda
// wspólna dla wszystkich pojazdów elektrycznych i kołowych. Jednakże nie ma tutaj implementacji abstrakcyjnych metod
// zadeklarowanych w klasach nadrzędnych i dlatego ta klasa również musi być abstrakcyjna.
public abstract class WheeledElectricVehicle extends WheeledMotorVehicle
{
public void setEngineRotationSpeed( int targetEngineRotationSpeed ) {
// Tutaj implementacja procesu ustawiania określonych obrotów silnika elektrycznego
// Zwiększamy lub zmniejszamy napięcie, aż silnik osiągnie zadane obroty.
}
}
// Interfejs definiujący metody zakręcania używane w pojazdach ze skrętnymi przednimi kołami.
public interface FrontWheelsTurningVehicle
{
public void turn( int angle ) ;
public void turnFrontWheels( int targetAngle ) ;
}
// Klasa dziedzicząca od wszystkich nadrzędnych klas abstrakcyjnych i nie-abstrakcyjnych a ponadto implementująca interfejs
// FrontWheelsTurningVehicle. Tutaj implementowane są wszystkie metody zadeklarowane i nie zaimplementowane w nadrzędnych
// klasach abstrakcyjnych oraz w implementowanym interfejsie.
public class ElectricCar extends WheeledElectricVehicle implements FrontWheelsTurningVehicle
{
public String registrationNumber; // Nr rejestracyjny samochodu
public int frontWheelsTurnAngle;
public void turn(int angle) {
// Tutaj implementacja procesu zakręcania o określony kąt. Dla realizacji tego procesu
// zostanie użyta w odpowiedni sposób metoda turnFrontWheels()
}
public void turnFrontWheels(int targetAngle) {
// Tutaj implementacja procesu stopniowego skręcania przednich kół
}
}