• Nie Znaleziono Wyników

Języki i techniki programowania Ćwiczenia 3 Dziedziczenie

N/A
N/A
Protected

Academic year: 2021

Share "Języki i techniki programowania Ćwiczenia 3 Dziedziczenie"

Copied!
7
0
0

Pełen tekst

(1)

Języki i techniki programowania

Ćwiczenia 3

Dziedziczenie

(2)

Autor: Marcin Orchel Klasa abstrakcyjna

Klasa abstrakcyjna to taka, że nie możemy tworzyć obiektów tej klasy, możemy jednak dziedziczyć po tej klasie.

Jeśli klasa ma co najmniej jedna metodę abstrakcyjną, a więc nie zdefiniowaną w tej klasie, to klasa jest abstrakcyjna.

W Javie dodaje się wtedy słowo kluczowe abstract przed nazwą klasy.

W C++ nie jest konieczne dodawanie tego słowa.

W C++ aby danej metody nie definiować należy na końcu deklaracji metody dodać = 0;.

Metodami niedefiniowanymi mogą być tylko i wyłącznie metody wirtualne. Co to są za metody będzie przedstawione w późniejszej częsci. Metoda wirtualna, niedefiniowana w klasie nazywa się metodą czysto wirtualną (pure virtual).

Dziedziczenie

W Javie po jednej klasie może dziedziczyć tylko jedna klasa – jednokrotne dziedziczenie. Klasa może implementować wiele interfejsów, interfejsy mogą być dziedziczone między sobą wielokrotnie.

Przykład:

interace interface1 {

}

interace interface2 {

}

interace interface3 extends interface1, interface2 {

}

class class1 implements interface1, interface2 { }

Dziedziczenie z trzema poziomami

Klasa Car -> Fiat -> Punto W przypadku uruchomienia

Punto punto;

punto.startEngine();

Jeśli metoda startEngine jest zdefiniowana w klasie Punto to ona zostanie uruchomiona.

Jeśli nie jest zdefiniowana w klasie Punto, a jest zdefiniowana w klasie Car i Fiat, to zostanie uruchomiona metoda startEngine() z klasy Fiat.

W przypadku uruchomienia:

(3)

void f(Car & car) {

car.startEngine();

}

Punto punto;

f(punto);

zostanie uruchomiona metoda startEngine() z klasy Car.

Jeśli metoda startEngine będzie wirtualna w klasie Car to zostanie wywołana metoda startEngine() z klasy Punto. Jeśli nie jest zdefiniowana w klasie Punto to z klasy Fiat.

Metody wirtualne

W Javie wszystkie metody są wirtualne.

Metoda wirtualna to taka metoda, że mając daną zmienną typu bazowego, pod którą znajduje się obiekt typu pochodnego, wywołanie metody wirtualnej na tej zmiennej spowoduje wywołanie metody z klasy pochodnej, a nie klasy bazowej.

W C++ aby metoda była wirtualna musi mieć słowo kluczowe virtual przed nazwą.

Przykład:

Vehicle {

public: virtual startEngine() {

} };

Tram : public Vehicle {

public: startEngine() {

} };

moveVehicles(Vehicle & vehicle) {

vehicle.startEngine();

}

void main() {

Tram tram = new Tram() moveVehicles(tram);

}

(4)

Wywołanie moveVehicles(tram) spowoduje uruchomienie metody startEngine() z klasy Tram, a nie z klasy Vehicle.

Wielokrotne dziedziczenie

W Javie jest możliwe tylko jednokrotne dziedziczenie pomiędzy klasami.

W C++ jest możliwe wielokrotne dziedziczenie.

Przykład

Mamy różne rodzaje pojazdów i różne rodzaje silników.

Chcemy mieć możliwość definiowania zachowania dla poszczególnych rodzajów pojazdów z poszczególnymi rodzajami silników.

Struktura klas:

Car -> Fiat

Car -> CarWithGasoline

Fiat, CarWithGasoline -> FiatWithGasoline Klasy tworzą tzw. strukturę diamentową.

Metoda startEngine() jest zdefiniowana dla klasy Car, Fiat oraz CarWithGasoline.

foo(Car & car) {

}

FiatWithGasoline fiatWithGasoline;

foo(fiatWithGasoline);

Powyższe wywołanie funkcji foo jest nieprawidłowe, ponieważ klasa Car jest przekazywana dwoma drogami poprzez klasę Fiat oraz CarWithGasoline.

FiatWithGasoline fiatWithGasoline;

(1) fiatWithGasoline.startEngine();

Przy tym uruchomieniu pojawi się błąd kompilacji, ponieważ nie można stwierdzić, która metoda ma się uruchomić czy z klasy Fiat, czy z klasy CarWithGasoline.

Gdy nie ma zdefiniowanej metody startEngine() zarówno dla klasy Fiat jak i CarWithGasoline, to również będzie błąd kompilatora, ponieważ metoda startEngine() z klasy Car jest

przekazywana dwoma drogami i nie wiadomo, którą wybrać.

Podobne problemy do powyższych dotyczą również parametrów klas.

Można zapobiec przekazywaniu metod dwoma drogami dziedziczenia używając wirtualnego dziedziczenia specyfikowanego następująco:

Fiat : public virtual Car.

(5)

Jeśli metoda startEngine() nie jest zdefiniowana ani dla klasy Fiat, ani dla klasy CarWithEngine, oraz klasy Fiat i CarWithEngine wirtualnie dziedziczą po klasie Car,

uruchomienie (1) jest prawidłowe, ponieważ wszystkie metody klasy Car przekazywane są

tylko jedną drogą.

(6)

Zadania

Zadanie podstawowe

- stworzyć klasę Figure, po której dziedziczy klasa Triangle - stworzyć klasę Circle dziedziczącą po klasie Figure.

W klasie Figure zadeklarować metodę computePerimeter, zdefiniować tą metodę dla klasy Triangle oraz dla klasy Circle.

Utworzyć klasę Figures, która w konstruktorze dostaje tablicę figur.

W klasie Figures zdefiniować metodę znajdującą figurę o największym obwodzie.

Napisać test poprawności programu.

Zadanie dodatkowe 1

- stworzyć dodatkową figurę Rhombus dziedziczącą po Figure, - stworzyć dodatkową figurę Square dziedziczącą po Rhombus

Znaleźć figurę o największym obwodzie dla przykładowych figur zapisanych w obiekcie klasy Figures.

Napisać test poprawności programu.

Zadanie dodatkowe 2

Dla wszystkich figur zdefiniować metody liczące pole,

zdefiniować w klasie Figures metodę znajdującą największe pole.

Zdefiniować klasy:

- FigureWithCircleInside

Klasa te posiada konstruktor z parametrami koła znajdującego się wewnątrz figury.

Klasa ta posiada metodę liczącą pole koła.

- RhombusWithCircleInside

Klasa ta posiada konstruktor z parametrami rombu oraz koła wpisanego do rombu.

Klasa ta posiada metodę liczącą pole figury. Pole figury z kołem wewnątrz jest równe polu figury bez pola koła.

Klasa ta posiada metodę sprawdzającą czy dane koło da się wpisać w dany romb.

Zdefiniować dodatkowo następujące dziedziczenia:

Figure -> FigureWithCircleInside

Rhombus, FigureWithCircleInside -> RhombusWithCircleInside

W RhombusWithCircleInside napisać metodę sprawdzającą czy można wpisać dane koło w

dany romb.

(7)

Stworzyć obiekt typu Figures z przykładowymi figurami zdefiniowanymi powyżej.

Znaleźć figurę o największym polu.

Napisać test poprawności programu.

Cytaty

Powiązane dokumenty

Miejsce Nr Załoga Kl Samochód Czas Kara Wynik Strata do lidera..

Ocenę dobrą (4) otrzymuje uczeń, który uzyskał 71% - 88% sumy wszystkich punktów Ocenę bardzo dobrą (5) otrzymuje uczeń, który uzyskał 89% - 99% sumy wszystkich punktów;..

Ile czasu potrzeba, żeby zagrzać 1,7 litra wody z temperatury pokojowej (20℃), czajnikiem elektrycznym o mocy

Niech punkt I będzie środkiem okręgu wpisanego w trójkąt ABC, zaś D, E, F niech będą punktami przecięcia dwusiecznych kątów A, B, C trójkąta ABC odpowiednio z bokami BC, AC

W miarę możliwości zaleca się taką organizację pracy szkoły i jej koordynację, która umożliwi zachowanie dystansu między osobami przebywającymi na terenie szkoły i

Formy czasowników czasu teraźniejszego, przeszłego i przyszłego ; „ą”, „ę” w różnych pozycjach w wyrazie. - Wypisz odpowiednią formę osoby czasowników : czytać, wołać, brać,

Krowy i gęsi mają łącznie sto głów i nóg, i jest ich łącznie trzy razy więcej niż koni.. Ile koni pasie się

Jeśli jednak nie jest prawdą, że logika jest jedna, to może istnieć logika prawnicza jako odmienny rodzaj logiki.. Zatem albo logika jest jedna, albo nie jest prawdą, że nie