WSNHiD, Programowanie 2 Lab. 2 Język Java struktura programu, dziedziczenie, abstrakcja, polimorfizm, interfejsy Pojęcie klasy Program napisany w języku Java składa się ze zbioru klas. Każda klasa zawiera pola przechowujące dane oraz metody wykonujące operacje na tych danych. Klasy zapisywane są w plikach noszących taką samą nazwę jak klasa. Operacje niezbędne do wstępnego zainicjalizowania klasy umieszcza się w konstruktorze. Oto przykład klasy: public class Shape { protected String color; public String getcolor() { return color; public Shape (String color) { this.color = color; Podstawowe pojęcia: słowa kluczowe class oraz this, modyfikatory widoczności (public, protected, private, default). Aby utworzyć instancję klasy należy skorzystać ze słowa kluczowego new. Przykładowo w metodzie main() obiektu Board można utworzyć obiekt klasy Shape w następujący sposób: public class Board { Shape shape = new Shape("Red"); System.out.println(shape.getColor() + " shape is on the board."); Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 1
Dziedziczenie Domyślnie każda klasa w języku Java dziedziczy po klasie Object. Dlatego też wszystkie klasy posiadają metody takie jak: clone() equals() finalize() getclass() hashcode() notify() notifyall() tostring() wait() Są to metody zaimplementowane w klasie Object. Samemu również można dziedziczyć po dowolnej klasie, która nie posiada modyfikatora final przed słowem kluczowym class. Przykładowo można utworzyć klasę Square, która będzie dziedziczyła po klasie Shape. Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 2
Implementacja klasy może wyglądać w poniższy sposób: public class Square extends Shape { private double side; public Square(String color, double side) { super(color); this.side = side; public double area() { return side * side; A oto przykładowe wykorzystanie klasy Square: public class Board { Shape shape = new Shape("Red"); Square square1 = new Square("Blue", 3); Square square2 = new Square("Yellow", 4); System.out.println(shape.getColor() + " shape is on the board."); System.out.println(square1.getColor() + square1.area()); System.out.println(square2.getColor() + square2.area()); Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 3
Na podobnej zasadzie można utworzyć inne klasy dziedziczące po klasie Shape. public class Circle extends Shape { private double radius; public Circle(String color, double radius) { super(color); this.radius = radius; public double area() { return Math.PI * radius * radius; Utworzenie klasy Circle może wyglądać następująco: public class Board { Shape shape = new Shape("Red"); Square square1 = new Square("Blue", 3); Square square2 = new Square("Yellow", 4); Circle circle1 = new Circle("Green", 2.5); Circle circle2 = new Circle("Black", 7); System.out.println(shape.getColor() + " shape is on the board."); System.out.println(square1.getColor() + square1.area()); System.out.println(square2.getColor() + square2.area()); System.out.println(circle1.getColor() + " circle is on the board. Its area is " + circle1.area()); System.out.println(circle2.getColor() + " circle is on the board. Its area is " + circle2.area()); Ćwiczenie 1 Proszę napisać klasę Rectangle (prostokąt), która będzie dziedziczyła po klasie Shape. Klasa powinna posiadać metodę area() obliczającą pole powierzchni utworzonego prostokąta. Proszę utworzyć instancję utworzonej klasy oraz wywołać metodę area(). Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 4
Abstrakcja i polimorfizm Proszę zwrócić uwagę, że wszystkie utworzone klasy (Square, Circle oraz Rectangle) są bardzo podobne. Wszystkie klasy dostarczają metodę area() służącą do obliczenia pola powierzchni. Pożądana byłaby możliwość posługiwania się utworzonymi klasami na nieco wyższym poziomie. Zmodyfikujmy klasę Shape tak, aby posiadała abstrakcyjną metodę area(). public abstract class Shape { protected String color; public String getcolor() { return color; public Shape (String color) { this.color = color; public abstract double area(); Proszę zwrócić uwagę na fakt, iż klasa Shape stała się klasą abstrakcyjną i nie ma już możliwości utworzenia instancji tej klasy za pomocą słowa kluczowego new. Dzięki takiej modyfikacji możemy zmodyfikować klasę Board upraszczając ją. Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 5
public class Board { Shape square1 = new Square("Blue", 3); Shape square2 = new Square("Yellow", 4); Shape circle1 = new Circle("Green", 2.5); Shape circle2 = new Circle("Black", 7); Shape rectangle = new Rectangle("Pink", 3, 2); System.out.println(square1.getColor() + square1.area()); System.out.println(square2.getColor() + square2.area()); System.out.println(circle1.getColor() + " circle is on the board. Its area is " + circle1.area()); System.out.println(circle2.getColor() + " circle is on the board. Its area is " + circle2.area()); System.out.println(rectangle.getColor() + " rectangle is on the board. Its area is " + rectangle.area()); Idąc dalej tym tropem można wprowadzić listę obiektów dziedziczących po klasie Shape. import java.util.arraylist; import java.util.list; public class Board { List list = new ArrayList(); list.add(new Square("Blue", 3)); list.add(new Square("Yellow", 4)); list.add(new Circle("Green", 2.5)); list.add(new Circle("Black", 7)); list.add(new Rectangle("Pink", 3, 2)); for (int i = 0; i < list.size(); i++) { Shape shape = (Shape)list.get(i); System.out.println(shape.getColor() + " " + shape.getclass().getname() + " is on the board. Its area is " + shape.area()); Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 6
Można również skorzystać z nowych możliwości języka Java i zapisać to jeszcze krócej. import java.util.arraylist; import java.util.list; public class Board { List<Shape> list = new ArrayList<Shape>(); list.add(new Square("Blue", 3)); list.add(new Square("Yellow", 4)); list.add(new Circle("Green", 2.5)); list.add(new Circle("Black", 7)); list.add(new Rectangle("Pink", 3, 2)); for (Shape shape : list) { System.out.println(shape.getColor() + " " + shape.getclass().getname() + " is on the board. Its area is " + shape.area()); Przysłanianie metod Klasa, która dziedziczy po innej klasie może przysłaniać niektóre jej metody. Oznacza to, że może dostarczać własnej implementacji. Spójrzmy przykładowo na klasę Trojkat, która dziedziczy po klasie Shape. public class Trojkat extends Shape { private double a; private double h; public Trojkat(String color, double a, double h) { super(color); this.a = a; this.h = h; public double area() { return a * h / 2; Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 7
Załóżmy, że chcemy, aby kolor trójkąta był podawany w języku polskim. W tym celu możemy przysłonić metodę getcolor() klasy shape. public class Trojkat extends Shape { private double a; private double h; public Trojkat(String color, double a, double h) { super(color); this.a = a; this.h = h; public double area() { return a * h / 2; public String getcolor () { if (color.equals("red")) { return "Czerwony"; else if (color.equals("blue")) { return "Niebieski"; else if (color.equals("green")) { return "Zielony"; return "<Nieznane tlumaczenie (ang. " + color + ")>"; Dodajmy odpowiednie linie kodu w klasie Board: list.add(new Trojkat("Blue", 4, 2)); list.add(new Trojkat("Pink", 6, 2));... i spójrzmy na wynik. Interfejsy Na klasy można patrzyć poprzez funkcjonalność, której dostarczają. Ponieważ utworzona wcześniej klasa Shape dostarcza nam dwóch informacji tzn.: informacje o kolorze kształtu za pomocą metody getcolor() informacje o polu powierzchni kształtu za pomocą metody area() Łatwo wyobrazić sobie interfejs, który mógłby zostać tu wprowadzony. public interface IColor { String getcolor(); Klasa Shape implementująca interfejs IColor będzie wyglądała następująco: Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 8
public abstract class Shape implements IColor { protected String color; public String getcolor() { return color; public Shape (String color) { this.color = color; public abstract double area(); Interfejs ten można wykorzystać również dla zupełnie innych obiektów. Np. wprowadzony już wcześniej obiekt Board może posiadać kolor. Tak oto dla białej tablicy (white board) możemy przygotować następujący fragment kodu: import java.util.arraylist; import java.util.list; public class Board implements IColor { public String getcolor() { return "White"; List<Shape> list = new ArrayList<Shape>(); list.add(new Square("Blue", 3)); list.add(new Square("Yellow", 4)); list.add(new Circle("Green", 2.5)); list.add(new Circle("Black", 7)); list.add(new Rectangle("Pink", 3, 2)); for (Shape shape : list) { System.out.println(shape.getColor() + " " + shape.getclass().getname() + " is on the board. Its area is " + shape.area()); Ćwiczenie 2: Proszę napisać klasę Person (osoba), która będzie reprezentowała pojedynczą osobę. Klasa powinna zawierać metody zwracające imię osoby oraz jej nazwisko. Dane te powinny być inicjalizowane w konstruktorze podczas tworzenia obiektu. Klasa powinna implementować następujący interfejs: public interface IPerson { String getfirstname(); String getlastname(); Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 9
Ćwiczenie 3: Proszę napisać klasę Employer (pracodawca), która będzie reprezentowała pracodawcę. Klasa ta powinna dziedziczyć po klasie Person a dodatkowo zawierać metodę zwracającą nazwę firmy. Klasa powinna implementować interfejs: public interface IEmployer { String getcompany(); Ćwiczenie 3: Proszę utworzyć klasę Market a w niej metodę main(). W metodzie tej proszę utworzyć instancję klasy Employer i wypisać na konsoli rezultat wywołania metody tostring() na obiekcie klasy Employer. Proszę sprawdzić co zostanie wypisane na konsoli w wyniku uruchomienia programu. Ćwiczenie 4: Proszę przysłonić metodę tostring() klasy Object w klasie Employer. Metoda ta powinna zwracać imię, nazwisko oraz firmę w następujący sposób: First Name: <tu imię osoby> Last Name: <tu nazwisko osoby> Company: <tu firma> Ćwiczenie 5: Proszę utworzyć listę pracodawców (czyli obiektów klasy Employer) w metodzie main() klasy Market, a następnie wypisać na konsoli informację o wszystkich pracodawcach wywołując dla każdego obiektu znajdującego się na liście metodę tostring(). Ćwiczenie 6: Proszę utworzyć klasę Employee (pracownik) implementujący interfejs IEmployee. Przyjmijmy, że każdy pracownik jest przypisany dokładnie do jednego pracodawcy. Metoda getemployer() powinna zwracać pracodawcę tego pracownika a calcsalary() wysokość jego wynagrodzenia. public interface IEmployee { Employer getemployer(); double calcsalary(); --- Koniec --- Programowanie 2, Java struktura programu..., 2007 Bartosz Bogacki 10