Programowanie 2 - Ćwiczenia 4


Poprzednie Następne
Temat: Mechanizmy programowania obiektowego.

Dziedziczenie - w przykładach

Polimorfizm

Polimorfizm (z gr. wielopostaciowość) - mechanizmy pozwalające programiście używać wartości, zmiennych i podprogramów na kilka różnych sposobów. Inaczej mówiąc jest to możliwość wyabstrahowania wyrażeń od konkretnych typów.

Co nam daje - przykład


Załóżmy, iż chcelibyśmy napisać klasę Kwadrat umożliwiającą wykonywanie operacji "opiszSie" oraz "czyPunktWKole".
Możliwym sposobem wykonania tego zadania jest: napisanie nowej klasy z wszystkimi potrzebnymi wartościami.

Jak napisalibyśmy teraz program umożliwiający użytkownikowi dodanie dowolnej ilości figur, o różnym typie a następnie zsumowaniu ich pól?

Struktura wyglądałaby zapewne w zarysie:
public static void main(String[] args) {
// odczytaj wybor osoby: (1- kolo, 2-kwadrat)
int wybor = ...<jakis kod>... ;
do {
if (wybor == 1 ) {
// odczytaj parametry kola i utworz obiekt
// dodaj kolo do jakiejs listy Kol;
} else if (wybor == 2) {
// odczytaj parametry kwadratu i utworz obiekt
// dodaj kolo do jakiejs listy Kwadratow;
}
} while (wybor != 0);

double pole=0;

for (int i=0; i<ile_kol; i++){
pole = pole + kolo[i].obliczPole();
}

for (int i=0; i<ile_kwadratow; i++){
pole = pole + kwadrat[i].obliczPole();
}


System.out.println("Pole wynosi: " + pole);
}

Jeżeli w programie dodamy kilka roznych figur to będziemy musieli dokładać dodatkowe petle zliczające pola danych figur.

Jak temu zaradzić?

Utwórzmy następujące klasy:

Klasa Figura:
public abstract class Figura {
public abstract double obliczPole();
public abstract double obliczObwod();
public abstract void opiszSie();

}


Klasa Kwadrat dziedzicząca z klasy Figura

public class Kwadrat extends Figura {

int x, y;
public Kwadrat() {
// wczytanie danych z klawiatury i zapisanie w polach klasy
}

public double obliczObwod() {
// ...
return 0;
}

public double obliczPole() {
// ...
return 0;
}

public void opiszSie() {
// ...
}
}


Wykorzystanie dziedziczenia:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;

public class SumowaniePol {

public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader klawiatura = new BufferedReader(new InputStreamReader(System.in));
ArrayList<Figura> lista_figur = new ArrayList<Figura>();
int wybor;

do {
wybor = Integer.parseInt(klawiatura.readLine());
switch (wybor) {
case 1:
lista_figur.add(new Kolo());
break;
case 2:
lista_figur.add(new Kwadrat());
}
} while (wybor != 0);

double pole = 0;

Iterator<Figura> i = lista_figur.iterator();

while (i.hasNext()) {
pole = pole + i.next().obliczPole();
}
}
}

Aby program działał trzeba jeszcze dodatkowo dodać bezparametrowy konstruktor w klasie Kolo.
Zadanie 4.1
Uruchom powyższy przykład (trzeba wprowadzić klika zmian).
Zadanie 4.2
Dodaj klasę Trojkat i zmień powyższy przykład by możliwe było obliczanie również pól trójkątów.


Widoczność pól i metod - hermetyzacja

Hermetyzacja - definicja

Hermetyzacja (z ang. encapsulation, kapsułkowanie, ukrywanie informacji, czasami także enkapsulacja) – jedno z założeń paradygmatu programowania obiektowego. Polega ono na ukrywaniu pewnych danych składowych lub metod obiektów danej klasy tak, aby były one (i ich modyfikacja) dostępne tylko metodom wewnętrznym danej klasy lub funkcjom z nią zaprzyjaźnionym.

Z pełną hermetyzacją mamy do czynienia wtedy, gdy dostęp do wszystkich pól w klasie jest możliwy tylko i wyłącznie poprzez metody, lub inaczej mówiąc gdy wszystkie pola w klasie znajdują się w sekcji prywatnej (lub chronionej).


Przykłady

Sprawdź czy możesz dokonać zmiany wartości pól z klasy Kolo np.:

public static void main(String[] args) {
// utworzenie obiektu o nazwie kolo1
Kolo kolo1 = new Kolo(10.0, 20.0, 5.0);
kolo1.x = 23;
kolo1.promien = 55;
...
}

Co się stanie, gdy zmieniona zostanie definicja pól na następującą: ?

// Klasa o nazwie Kolo. Bedzie reprezentowac figure geometryczna pozwalajaca 
// na wykonaniu podstawowych operacji takich jak obliczenie pola i obwodu
public class Kolo {

// pola (wlasciwosci)
private double x;
private double y;
private double promien;

...

Ćwiczenie

Pozmieniaj przykłady z zadań tak by wszystkie pola były prywatne.  Co się stanie gdy zmienione zostaną widoczności metod na prywatne (private) lub chronione (protected) ?.