Commit 8670302b by Patryk Czarnik

Przykłady programowania obiektowego

parent 4baff494
package p06_klasy_podstawy.v1;
public class Osoba {
// Zmienna deklarowana na poziomie klasy to (trzy nazwy):
// - pole (field)
// - atrybut (attribute)
// - zmienna instancyjna (instance variable)
// Każdy obiekt tej klasy będzie zawierał własne egzemplarze tych zmiennych.
String imie, nazwisko;
int wiek;
// Metoda to jest czynność, którą potrafi wykonać obiekt.
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
}
}
package p06_klasy_podstawy.v1;
public class PrzykladowyProgram {
public static void main(String[] args) {
// Deklaruję zmienne a i b typu Osoba i wpisuję do nich dwa nowe obiekty klasy Osoba.
Osoba a = new Osoba();
Osoba b = new Osoba();
System.out.println(a);
System.out.println(b);
System.out.println(a.imie + " " + a.nazwisko + " ma " + a.wiek + " lat");
// wyjaśnienie: w nowotworzonych obiektach do pól wpisywane są wartości 0, false lub null
// później zobaczymy kontruktory
System.out.println();
// Mamy bezpośredni dostęp do pól, bo nie są prywatne.
a.imie = "Ala";
a.nazwisko = "Kowalska";
a.wiek = 30;
b.imie = "Bartek";
b.nazwisko = "Malinowski";
b.wiek = 17;
System.out.println(a.imie + " " + a.nazwisko + " ma " + a.wiek + " lat");
System.out.println(b.imie + " " + b.nazwisko + " ma " + b.wiek + " lat");
System.out.println();
// wywołujemy metody na obiektach
a.przedstawSie();
b.przedstawSie();
System.out.println();
Sklep zabka = new Sklep();
zabka.cenaPiwa = 6;
Sklep biedronka = new Sklep();
biedronka.cenaPiwa = 5;
System.out.println("Ala kupuje 3 piwa w Żabce");
zabka.sprzedajPiwo(a, 3);
System.out.println("\nBartek próbuje kupić 1 piwo w Żabce");
zabka.sprzedajPiwo(b, 1);
System.out.println("\nAla kupuje 2 piwa w Biedronce");
biedronka.sprzedajPiwo(a, 2);
System.out.println("\nUtarg Żabki: " + zabka.utarg + " a Biedronki: " + biedronka.utarg);
}
}
package p06_klasy_podstawy.v1;
public class Sklep {
int cenaPiwa;
int utarg;
void sprzedajPiwo(Osoba klient, int sztuk) {
if(klient.wiek >= 18) {
int kwota = cenaPiwa * sztuk;
System.out.println(klient.imie + ", oto twoje " + sztuk + " piwa, płacisz " + kwota);
utarg += kwota;
} else {
System.out.println("Niepełnoletnim nie sprzedajemy");
}
}
}
package p06_klasy_podstawy.v2;
public class Osoba {
// Zmienna deklarowana na poziomie klasy to (trzy nazwy):
// - pole (field)
// - atrybut (attribute)
// - zmienna instancyjna (instance variable)
// Każdy obiekt tej klasy będzie zawierał własne egzemplarze tych zmiennych.
String imie, nazwisko;
int wiek;
Osoba() {
}
Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
// Metoda to jest czynność, którą potrafi wykonać obiekt.
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
}
boolean jestPelnoletnia() {
return wiek >= 18;
}
@Override
public String toString() {
return imie + " " + nazwisko;
}
}
package p06_klasy_podstawy.v2;
public class PrzykladowyProgram {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 30);
Osoba b = new Osoba("Bartek", "Malinowski", 17);
System.out.println(a);
System.out.println(b);
System.out.println();
System.out.println(a.imie + " " + a.nazwisko + " ma " + a.wiek + " lat");
System.out.println(b.imie + " " + b.nazwisko + " ma " + b.wiek + " lat");
System.out.println();
a.przedstawSie();
b.przedstawSie();
}
}
package p06_klasy_podstawy.v2;
public class Sklep {
int cenaPiwa;
int utarg;
Sklep(int cenaPiwa) {
this.cenaPiwa = cenaPiwa;
}
void sprzedajPiwo(Osoba klient, int sztuk) {
System.out.println("Do sklepu przyszedł klient. Kliencie, przedstaw się...");
klient.przedstawSie();
if(klient.jestPelnoletnia()) {
int kwota = cenaPiwa * sztuk;
System.out.println(klient.imie + ", oto twoje " + sztuk + " piwa, płacisz " + kwota);
utarg += kwota;
} else {
System.out.println("Niepełnoletnim nie sprzedajemy");
}
}
}
package p06_klasy_podstawy.v2;
public class Zakupy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 30);
Osoba b = new Osoba("Bartek", "Malinowski", 17);
Sklep zabka = new Sklep(6);
Sklep biedronka = new Sklep(5);
System.out.println("Ala kupuje 3 piwa w Żabce");
zabka.sprzedajPiwo(a, 3);
System.out.println("\nBartek próbuje kupić 1 piwo w Żabce");
zabka.sprzedajPiwo(b, 1);
System.out.println("\nAla kupuje 2 piwa w Biedronce");
biedronka.sprzedajPiwo(a, 2);
System.out.println("\nUtarg Żabki: " + zabka.utarg + " a Biedronki: " + biedronka.utarg);
}
}
package p06_klasy_podstawy.v3;
public class Osoba {
// Zmienna deklarowana na poziomie klasy to (trzy nazwy):
// - pole (field)
// - atrybut (attribute)
// - zmienna instancyjna (instance variable)
// Każdy obiekt tej klasy będzie zawierał własne egzemplarze tych zmiennych.
String imie, nazwisko;
int wiek;
Osoba() {
}
Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
// Metoda to jest czynność, którą potrafi wykonać obiekt.
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
}
boolean jestPelnoletnia() {
return wiek >= 18;
}
@Override
public String toString() {
return imie + " " + nazwisko;
}
}
package p06_klasy_podstawy.v3;
public class PrzykladDziedziczenia {
public static void main(String[] args) {
Osoba osoba = new Osoba("Ala", "Kowalska", 30);
System.out.println(osoba.imie);
osoba.przedstawSie();
System.out.println();
// Z nadklasy nie są dziedziczone konstruktory
// Student student2 = new Student("Jan", "Kowalski", 22);
Student student = new Student("Jan", "Kowalski", 22, 2, "medycyna");
// W obiekcie Student dostępne są pola i metody odziedziczone z klasy Osoba:
System.out.println(student.imie);
student.przedstawSie();
// Ale są też nowe rzeczy, zdefiniowane w klasie Student:
System.out.println(student.kierunek);
student.dodajOcene(5);
student.dodajOcene(4);
student.dodajOcene(4);
System.out.println(student.sredniaOcen());
System.out.println(student.sredniaOcenStream());
}
}
package p06_klasy_podstawy.v3;
public class PrzykladowyProgram {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 30);
Osoba b = new Osoba("Bartek", "Malinowski", 17);
System.out.println(a);
System.out.println(b);
System.out.println();
System.out.println(a.imie + " " + a.nazwisko + " ma " + a.wiek + " lat");
System.out.println(b.imie + " " + b.nazwisko + " ma " + b.wiek + " lat");
System.out.println();
a.przedstawSie();
b.przedstawSie();
}
}
package p06_klasy_podstawy.v3;
public class Sklep {
int cenaPiwa;
int utarg;
Sklep(int cenaPiwa) {
this.cenaPiwa = cenaPiwa;
}
void sprzedajPiwo(Osoba klient, int sztuk) {
System.out.println("Do sklepu przyszedł klient. Kliencie, przedstaw się...");
klient.przedstawSie();
if(klient.jestPelnoletnia()) {
int kwota = cenaPiwa * sztuk;
System.out.println(klient.imie + ", oto twoje " + sztuk + " piwa, płacisz " + kwota);
utarg += kwota;
} else {
System.out.println("Niepełnoletnim nie sprzedajemy");
}
}
}
package p06_klasy_podstawy.v3;
import java.util.ArrayList;
import java.util.List;
public class Student extends Osoba {
int rok;
String kierunek;
List<Integer> oceny = new ArrayList<>();
// W Javie konstruktory nie są dziedziczone z nadklasy,
// ale w podklasie można stworzyć konstruktor, który wywołuje konstruktor nadklasowy za pomocą super().
public Student(String imie, String nazwisko, int wiek, int rok, String kierunek) {
super(imie, nazwisko, wiek);
this.rok = rok;
this.kierunek = kierunek;
}
void dodajOcene(int ocena) {
oceny.add(ocena);
}
double sredniaOcen() {
double suma = 0;
for(int ocena : oceny) {
suma += ocena;
}
return suma / oceny.size();
}
double sredniaOcenStream() {
return oceny.stream().mapToInt(Integer::intValue).average().orElse(Double.NaN); // albo 0
}
void przedstawSie() {
System.out.println("Hejka " + imie);
}
}
package p06_klasy_podstawy.v3;
public class Zakupy {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 30);
Osoba b = new Osoba("Bartek", "Malinowski", 17);
Sklep zabka = new Sklep(6);
Sklep biedronka = new Sklep(5);
System.out.println("Ala kupuje 3 piwa w Żabce");
zabka.sprzedajPiwo(a, 3);
System.out.println("\nBartek próbuje kupić 1 piwo w Żabce");
zabka.sprzedajPiwo(b, 1);
System.out.println("\nAla kupuje 2 piwa w Biedronce");
biedronka.sprzedajPiwo(a, 2);
System.out.println("\nUtarg Żabki: " + zabka.utarg + " a Biedronki: " + biedronka.utarg);
}
}
package p07_polimorfizm;
public class Konto {
int numer;
int saldo;
Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
@Override
public String toString() {
return "Konto nr " + numer + ": " + saldo + " PLN , wł.: " + wlasciciel;
}
void wplata(int kwota) {
saldo += kwota;
}
void wyplata(int kwota) {
saldo -= kwota;
}
}
package p07_polimorfizm;
public class Osoba {
String imie, nazwisko;
int wiek;
Osoba() {
}
Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
}
boolean jestPelnoletnia() {
return wiek >= 18;
}
public String toString() {
return imie + " " + nazwisko + " (" + wiek + " lat)";
}
}
package p07_polimorfizm;
public class Polimorfizm1 {
public static void main(String[] args) {
Osoba osoba = new Osoba("Ala", "Kowalska", 30);
System.out.println(osoba);
// Poprzez zmienną typu Osoba można korzystać tylko ze zmiennych (pól) i metod zdefiniowanych w klasie Osoba.
System.out.println(osoba.imie + " " + osoba.nazwisko);
osoba.przedstawSie();
// Nie działają:
// System.out.println(osoba.kierunek);
// System.out.println(osoba.sredniaOcen());
System.out.println();
Student student = new Student("Adam", "Abacki", 22, "geologia", 4);
System.out.println(student);
// Jeśli klasa Student jest rozszerzeniem klasy Osoba (inaczej mówiąc: dziedziczy z klasy Osoba)
// to na zmiennej typu Student można wykonać te operacje (i dostać się do tych zmiennych),
// które byłyby dostępne zmiennej typu Osoba...
if(student.jestPelnoletnia()) {
System.out.println("Student " + student.imie + " jest pełnoletni");
}
// ... a dodatkowo dostępne są zmienne i metody dodane w klasie Student.
student.dodajOcene(5);
student.dodajOcene(4);
System.out.println("Średnia ocen: " + student.sredniaOcen());
System.out.println();
// Dziedziczenie to nie tylko "skopiowanie definicji z istniejącej klasy i dopisanie czegoś jeszcze".
// W dziedziczeniu chodzi też o to, że w każdej sytuacji obiekt podklasy może być użyty zamiast obiektu nadklasy.
// "zasada podstawiania"
// Skoro student posiada wszystkie te cechy, co inne osoby, to obiektu student można użyć w k ązdym miejscu, gdzie możnaby uzyć osoby.
// Przykłady:
// Student może być wpisany do zmiennej typu Osoba.
Osoba ktos = student;
// Osoba ktos = osoba;
ktos.przedstawSie();
// W zmiennej ktos jest adres wskazujący na obiekt klasy Student.
// Student może być właścicielem konta:
Konto kontoStudenckie = new Konto(1313, 123, student);
kontoStudenckie.wplata(500);
System.out.println(kontoStudenckie);
System.out.println();
// Student może kupić piwo
Sklep.sprzedajPiwo(student);
System.out.println();
Sklep.sprzedajPiwo(ktos);
System.out.println();
// Czy w zmiennej ktos mamy teraz Osobę czy Studenta?
System.out.println(ktos.getClass()); // Student
// Jednak do pól tego obiektu nie można dostać się "oficjalnie":
// System.out.println(ktos.kierunek + " , średnia " + ktos.sredniaOcen());
// Obiekt ze zmiennej typu "nadklasa" można zrzutować na typ "podklasa",
// jeśli widzimy, że w danym momencie jest to możliwe:.
// Najlepiej sprawdzić to za pomocą if(obiekt instanceof Klasa)
if(ktos instanceof Student) {
System.out.println("To jest Student");
Student zrzutowany = (Student)ktos;
System.out.println(zrzutowany.kierunek + " , średnia " + zrzutowany.sredniaOcen());
// albo tak jeśli czytamy tylko jedną rzecz:
System.out.println( ((Student)ktos).rok );
} else {
System.out.println("To nie jest Student");
}
}
}
package p07_polimorfizm;
public class Polimorfizm2 {
public static void main(String[] args) {
Osoba osoba = new Osoba("Ala", "Kowalska", 30);
Student student = new Student("Adam", "Abacki", 20, "prawo", 1);
System.out.println(osoba);
System.out.println(student);
System.out.println();
// 1) Podklasa może nie zmieniać metody z nadklasy - wtedy ta metoda jest "dziedziczona" i działa ta sama implementacja
System.out.println(student.jestPelnoletnia());
// 2) Podklasa może dodać zupełnie nowe metody
student.dodajOcene(3);
student.dodajOcene(4);
student.dodajOcene(5);
student.dodajOcene(5);
System.out.println(student.sredniaOcen());
// System.out.println(osoba.sredniaOcen());
System.out.println();
// 3) podklasa może też nadpisać (OVERRIDE) metodę, która istniała w nadklasie
// wtedy gdy metoda zostanie wywołana na obiekcie podklasy, zadziała jej zmieniona wersja
System.out.print(" osoba.przedstawSie(): ");
osoba.przedstawSie();
System.out.print("student.przedstawSie(): ");
student.przedstawSie();
System.out.println();
// Java użyje wersji metody z podklasy także wtedy, gdy obiekt podklasy (Student)
// będzie wpisany na zmienną typu nadklasa (Osoba):
Osoba x;
x = osoba;
x.przedstawSie();
x = student;
x.przedstawSie();
// bo w języku Java metody instancyjne są zawsze "wirtualne" (terminologia języka C++)
// Zauważmy, że x.przedstawSie() wypisuje informację o kierunku,
// ale sami bezpośrednio tej informacji nie odczytamy ze zmiennej x, bo jest ona typu Osoba
// System.out.println(x.kierunek);
System.out.println();
// Wpisywanie studenta do zmiennej Osoba x jest nienaturalne.
// Ale do podobnej sytuacji może dojść w zupełnie naturalny sposób.
// 1) Kolekcja może zawierać obiekty różnych klas:
Osoba[] osoby = {
new Osoba("Ala", "Kowalska", 30),
new Student("Adam", "Abacki", 20, "prawo", 1),
new StudentInformatyki("Edward", "Ęcki", 22, 3),
new Pracownik("Jan", "Kowalski", 50, "kierowca", 4321),
};
// Wtedy gdy przeglądamy zawartość w pętli element kolekcji widzimy jako obiekt nadklasy (Osoba)
System.out.println("przedstawSie w pętli for:");
for (Osoba o : osoby) {
o.przedstawSie();
}
System.out.println();
System.out.println("=========================");
System.out.println("Idziemy do sklepu...");
// Do sklepu jako Osoba może pójść zwykła Osoba, może też pójść Student...
Sklep.sprzedajPiwo(osoba);
System.out.println();
Sklep.sprzedajPiwo(student);
System.out.println("\n=========================\n");
for(Osoba o : osoby) {
Sklep.sprzedajPiwo(o);
System.out.println();
}
}
}
package p07_polimorfizm;
public class Polimorfizm3 {
public static void main(String[] args) {
// Dzięki temu, że "Student jest Osobą" i "Pracownik jest Osobą",
// można obiekty tych klas umieści w tablicy (kolekcji itp.) osób.
Osoba[] osoby = {
new Osoba("Ala", "Kowalska", 44),
new Osoba("Ola", "Malinowska", 33),
new Student("Adam", "Abacki", 20, "medycyna", 1),
new StudentInformatyki("Karol", "Infobacki", 23, 3),
new Pracownik("Jan", "Kowalski", 40, "kierowca", 3300),
};
// Przeglądają elementy tablicy wiemy na pewno, że są to Osoby,
// ale dodatkowo może się okazać, że niektóre osoby są Student albo Pracownik
// Każda osoba posiada imię, nazwisko i wiek - można te dany odczytać.
// Każda osoba potrafi się przedstawić - można wywołać przedstawSie()
// ale w każdej podklasie ta metoda może mieć inną treść ("overriding").
// Wykona się wersja z właściwej klasy.
for (Osoba osoba : osoby) {
System.out.println("* kolejna osoba to " + osoba.imie + " " + osoba.nazwisko);
System.out.println(" " + osoba);
System.out.print(" ");
// System.out.println(osoba.kierunek); // nie każda osoba jest studentem
osoba.przedstawSie();
System.out.println(" to jest obiekt klasy: " + osoba.getClass().getSimpleName());
// Można jawnie sprawdzić czy zmienna wskazuje na obiekt określonej klasy
// (lub dalszej podklasy - np. StudentInformatyki byłby w tym sensie Studentem)
if(osoba instanceof Student) {
// Jeśli tak jest, to możemy bezpiecznie zrzutować (cast) zmienną na typ Student
Student student = (Student) osoba;
System.out.println(" To jest student kierunku " + student.kierunek
+ ", który ma średnią ocen " + student.sredniaOcen());
}
// natomiast taki if nie byłby prawdziwy dla obiektu klasy StudentInformatyki
if(osoba.getClass() == Student.class) {
System.out.println(" to jest konkretnie klasy Student");
}
System.out.println();
}
}
}
\ No newline at end of file
package p07_polimorfizm;
import java.math.BigDecimal;
class Pracownik extends Osoba {
String zawod;
BigDecimal pensja;
Pracownik() {
}
Pracownik(String imie, String nazwisko, int wiek, String zawod, BigDecimal pensja) {
// wywołanie konstruktora z nadklasy
super(imie, nazwisko, wiek);
this.zawod = zawod;
this.pensja = pensja;
}
Pracownik(String imie, String nazwisko, int wiek, String zawod, double pensja) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, wiek, zawod, BigDecimal.valueOf(pensja).setScale(2));
}
Pracownik(String imie, String nazwisko, int wiek, String zawod, int pensja) {
this(imie, nazwisko, wiek, zawod, BigDecimal.valueOf(pensja).setScale(2));
}
Pracownik(String imie, String nazwisko, int wiek, String zawod, String pensja) {
this(imie, nazwisko, wiek, zawod, new BigDecimal(pensja));
}
// tworzenie wielu konstruktorów w tej samej klasie to jest "przeciążanie konstruktorów" / "overloading"
@Override
public void przedstawSie() {
System.out.println("Dzień dobry, tu "+ imie + ", pracuję jako " + zawod + " i zarabiam " + pensja +" zł.");
}
}
\ No newline at end of file
package p07_polimorfizm;
public class Przyklad3 {
public static void main(String[] args) {
Osoba osoba = new Osoba();
// Obiekt klasy Osoba posiada tylko te pola i metody, które zostały zdefiniowanie w klasie Osoba
osoba.imie = "Ala";
osoba.nazwisko = "Kowalska";
osoba.wiek = 30;
osoba.przedstawSie();
// osoba.kierunek = "informatyka";
// System.out.println(osoba.sredniaOcen());
System.out.println();
// Obiekt klasy Student ("podklasy") posiada pola i metody odziedziczone z klasy Osoba ("nadklasy")
// a dodatkowo elementy zdefiniowane w klasie Student.
Student student = new Student();
student.imie = "Jan";
student.nazwisko = "Kowalski";
student.wiek = 20;
student.kierunek = "geologia";
student.rok = 2;
student.przedstawSie();
System.out.println("średnia ocen: " + student.sredniaOcen());
System.out.println();
// z nadklasy dziedziczone są:
// - pola (wszystkie są w pamięci, ale podklasa nie ma dostępu do pól prywatnych nadklasy)
// - metody (poza prywatnymi)
// - ale nie są dziedziczone konstruktory
//Student s3 = new Student("Adam", "Adamowski", 25);
// Każda klasa od zera definiuje swoje konstruktory.
// Gdy programista nie napisze żadnego, to definiowany jest domyślny. Aby to było możliwe, w nadklasie musi być konstr. bezarguemntowy.
Student s4 = new Student("Adam", "Adamowski", 25, "medycyna", 5);
s4.przedstawSie();
s4.dodajOcene(3);
s4.dodajOcene(3);
s4.dodajOcene(3);
s4.dodajOcene(5);
System.out.println(s4.sredniaOcen());
}
}
package p07_polimorfizm;
public class Sklep {
static void sprzedajPiwo(Osoba klient) {
System.out.println("Do sklepu przychodzi " + klient.imie + ". Przedstaw się...");
klient.przedstawSie();
if(klient.jestPelnoletnia()) {
System.out.println("Ta osoba może kupić piwo");
} else {
System.out.println("Ta osoba nie może kupić piwa, bo ma tylko " + klient.wiek + " lat.");
}
}
}
package p07_polimorfizm;
import java.util.ArrayList;
import java.util.List;
public class Student extends Osoba {
String kierunek;
int rok;
List<Integer> oceny = new ArrayList<>();
public Student() {
}
// W Javie konstruktory nie są dziedziczone, ale narzędzia deweloperskie ułatwiają tworzenie takich konstruktorów w podklasie,
// które przyjmują wszystkie wymagane parametry i przekzują do nadklasy za pomocą super();
public Student(String imie, String nazwisko, int wiek, String kierunek, int rok) {
super(imie, nazwisko, wiek);
this.kierunek = kierunek;
this.rok = rok;
}
// podklasa może
// 1) nie zmieniać metod odziedziczonych z nadklasy
// przykłady: jestPelnoletnia()
// 2) dodać nowe metody, których nie było w nadklasie
void dodajOcene(int ocena) {
oceny.add(ocena);
}
double sredniaOcen() {
double suma = 0;
for(int ocena : oceny) {
suma += ocena;
}
return suma / oceny.size();
}
// 3) nadpisać (override) metody, które były zdefiniowane w nadklasie
// czyli dla istniejących metoda podać inną treść
@Override
void przedstawSie() {
System.out.println("Hej, tu " + imie + " " + nazwisko + ", studiuję kierunek " + kierunek + " na " + rok + " roku");
}
// Od Javy 5 przed definicją metody, która nadpisuje definicję z nadklasy, można umieścić adnotację @Override
// Ważne: nawet bez tej adnotacji nadpisanie jest skuteczne. Adnotacja tylko:
// - zwiększa czytelność kodu ("rzuca się w oczy")
// - powoduje błąd kompilacji, gdyby okazało się, że jednak tutaj nie nadpisujemy metody, tylko definiujemy nową (np. literówka w nazwie, parametry innego typu)
@Override
public String toString() {
return super.toString() + ", student " + rok + " roku kierunku " + kierunek ;
}
}
package p07_polimorfizm;
class StudentInformatyki extends Student {
// Czasami podklasa nie ma nowych pól ani metod,
// a jest wprowadzana po to, aby ustalić pewne szczegóły
// Jest to podklasa / podzbiór w sensie matematycznym (logicznym).
public StudentInformatyki(String imie, String nazwisko, int wiek, int rok) {
// ustalamy, że kierunkiem studiów jest "informatyka" i nie może być inaczej
super(imie, nazwisko, wiek, "informatyka", rok);
}
}
package p08_enkapsulacja;
public class BrakSrodkow extends Exception {
private static final long serialVersionUID = -5235658101493067634L;
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
}
package p08_enkapsulacja;
public class Konto {
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
if(saldo < 0) {
throw new IllegalArgumentException("Saldo nie może być ujemne");
}
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
@Override
public String toString() {
return "Konto nr " + numer + ": " + saldo + " PLN , wł.: " + wlasciciel;
}
// Tylko dla pole wlasciciel pozwalamy na zmianę wartości.
// Nie tworzymy setterów dla pól:
// - numer - ponieważ numer nie będzie się zmieniać (w konkretnym obiekcie)
// dodatkowym podkreśleniem tego faktu i zabezpieczeniem przed własnymi błędami
// jest dopisanie final do pola numer
// - saldo - ponieważ zmiana salda ma być możliwa tylko za pośrednictwem "metod biznesowych" wpłata, wypłata, przelew
// Odpowiednie kontrolując wartości w tych metodach może zapewnić "niezmiennik" (invariant),
// że saldo nigdy nie jest ujemne.
// Zagadka: czy na pewno nie może?... :-)
public int getNumer() {
return numer;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public int getSaldo() {
return saldo;
}
public void wplata(int kwota) {
if(kwota <= 0) {
throw new IllegalArgumentException("Niedodatnia kwota wpłaty");
}
saldo += kwota;
// aby uniknąć integer overflow, można tak:
// saldo = Math.addExact(saldo, kwota);
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota <= 0) {
throw new IllegalArgumentException("Niedodatnia kwota wypłaty");
}
if(kwota > saldo) {
throw new BrakSrodkow("Niewystarczające środki na koncie nr " + numer);
}
saldo -= kwota;
}
public void przelew(Konto kontoDocelowe, int kwota) throws BrakSrodkow {
if(kwota <= 0) {
throw new IllegalArgumentException("Niedodatnia kwota przelewu: " + kwota);
}
if(kwota > saldo) {
throw new BrakSrodkow("Za mało kasy na koncie nr " + numer);
}
this.saldo -= kwota;
kontoDocelowe.saldo += kwota;
// Obiekt ma dostęp do pola prywatnego innego obiektu tej samej klasy!
}
}
package p08_enkapsulacja;
public class Osoba {
private String imie, nazwisko;
private int wiek;
public Osoba() {
}
public Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
public String getImie() {
return imie;
}
public String getNazwisko() {
return nazwisko;
}
public int getWiek() {
return wiek;
}
public void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
}
public boolean jestPelnoletnia() {
return wiek >= 18;
}
public String toString() {
return imie + " " + nazwisko + " (" + wiek + " lat)";
}
}
package p08_enkapsulacja;
import java.math.BigDecimal;
class Pracownik extends Osoba {
private String zawod;
private BigDecimal pensja;
Pracownik() {
}
Pracownik(String imie, String nazwisko, int wiek, String zawod, BigDecimal pensja) {
// wywołanie konstruktora z nadklasy
super(imie, nazwisko, wiek);
this.zawod = zawod;
this.pensja = pensja;
}
Pracownik(String imie, String nazwisko, int wiek, String zawod, double pensja) {
// wywołanie innego konstruktora z tej samej klasy
this(imie, nazwisko, wiek, zawod, BigDecimal.valueOf(pensja).setScale(2));
}
Pracownik(String imie, String nazwisko, int wiek, String zawod, int pensja) {
this(imie, nazwisko, wiek, zawod, BigDecimal.valueOf(pensja).setScale(2));
}
Pracownik(String imie, String nazwisko, int wiek, String zawod, String pensja) {
this(imie, nazwisko, wiek, zawod, new BigDecimal(pensja));
}
// tworzenie wielu konstruktorów w tej samej klasie to jest "przeciążanie konstruktorów" / "overloading"
@Override
public void przedstawSie() {
System.out.println("Dzień dobry, tu "+ getImie() + ", pracuję jako " + zawod + " i zarabiam " + pensja +" zł.");
}
public BigDecimal getPensja() {
return pensja;
}
public String getZawod() {
return zawod;
}
}
\ No newline at end of file
package p08_enkapsulacja;
import java.util.List;
public class ProbaZmianyOcen {
public static void main(String[] args) {
Student student = new Student("Jan", "Kowalski", 25, "astronomia", 4);
System.out.println(student);
student.dodajOcene(2);
student.dodajOcene(4);
student.dodajOcene(4);
// student.dodajOcene(7);
System.out.println("oceny 1: " + student.getOceny());
System.out.println("średnia 1: " + student.sredniaOcen());
System.out.println();
List<Integer> lista = student.getOceny();
System.out.println("dodaję sobie oceny");
lista.add(7); // wyjątek, bo próba modyfikacji "unmodifiableList"
System.out.println("kasuję ocenę");
lista.remove(0);
System.out.println("oceny 2: " + student.getOceny());
System.out.println("średnia 2: " + student.sredniaOcen());
}
}
package p08_enkapsulacja;
import java.util.Scanner;
public class ProgramBankowy {
public static void main(String[] args) {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
Osoba ala = new Osoba("Ala", "Kowalska", 33);
System.out.print("Podaj początkową kwotę: ");
int kwota = sc.nextInt();
sc.nextLine(); // wymuszenie przejścia do nowej linii
Konto konto = new Konto(1, kwota, ala);
System.out.println(konto);
petla:
while(true) {
try {
System.out.println("Co chcesz zrobić? W - wpłata, Y - wypłata, K - koniec");
String wybor = sc.nextLine().toUpperCase();
switch(wybor) {
case "K":
case "Q":
break petla; // przejście do Koniec programu
case "W":
System.out.print("Podaj kwotę wpłaty: ");
kwota = sc.nextInt();
sc.nextLine();
konto.wplata(kwota);
System.out.println("Pieniądze zostały wpłacone");
break;
case "Y":
System.out.print("Podaj kwotę wypłaty: ");
kwota = sc.nextInt();
sc.nextLine();
konto.wyplata(kwota);
// ta linia wykona się tylko jeśli nie było wyjątku:
System.out.println("Pieniądze zostały wypłacone");
break;
default:
System.out.println("Nieznane polecenie");
continue petla; // Przejście do Co chcesz zrobić
}
// Jeśli o różnych sytuacjach błędnych będą informować wyjątki różnych klas,
// to w programie możemy te sytuacje rozróżnić i obsłużyć w róznych catchach
} catch(IllegalArgumentException e) {
System.out.println("Niepoprawny argument: " + e.getMessage());
} catch(BrakSrodkow e) {
System.out.println(e.getMessage());
} catch(Exception e) {
System.out.println("Inny błąd: " + e);
}
System.out.println();
System.out.println(konto);
System.out.println();
}
System.out.println("Koniec programu");
}
}
package p08_enkapsulacja;
public class Sklep {
static void sprzedajPiwo(Osoba klient) {
System.out.println("Do sklepu przychodzi " + klient.getImie() + ". Przedstaw się...");
klient.przedstawSie();
if(klient.jestPelnoletnia()) {
System.out.println("Ta osoba może kupić piwo");
} else {
System.out.println("Ta osoba nie może kupić piwa, bo ma tylko " + klient.getWiek() + " lat.");
}
}
}
package p08_enkapsulacja;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Student extends Osoba {
private String kierunek;
private int rok;
private final List<Integer> oceny = new ArrayList<>();
public Student() {
}
public Student(String imie, String nazwisko, int wiek, String kierunek, int rok) {
super(imie, nazwisko, wiek);
this.kierunek = kierunek;
this.rok = rok;
}
public void dodajOcene(int ocena) {
if(ocena < 2 || ocena > 5) {
throw new IllegalArgumentException("ocena poza zakresem");
}
oceny.add(ocena);
}
public double sredniaOcen() {
double suma = 0;
for(int ocena : oceny) {
suma += ocena;
}
return suma / oceny.size();
}
@Override
public void przedstawSie() {
System.out.println("Hej, tu " + getImie() + " " + getNazwisko() + ", studiuję kierunek " + kierunek + " na " + rok + " roku");
}
@Override
public String toString() {
return super.toString() + ", student " + rok + " roku kierunku " + kierunek ;
}
public String getKierunek() {
return kierunek;
}
public int getRok() {
return rok;
}
public List<Integer> getOceny() {
return Collections.unmodifiableList(oceny);
}
}
package p08_enkapsulacja;
class StudentInformatyki extends Student {
// Czasami podklasa nie ma nowych pól ani metod,
// a jest wprowadzana po to, aby ustalić pewne szczegóły
// Jest to podklasa / podzbiór w sensie matematycznym (logicznym).
public StudentInformatyki(String imie, String nazwisko, int wiek, int rok) {
// ustalamy, że kierunkiem studiów jest "informatyka" i nie może być inaczej
super(imie, nazwisko, wiek, "informatyka", rok);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment