Commit b301c04e by Patryk Czarnik

Nadpisanie metod toString, equals, hashCode

parent 63d505c9
package p11_klasy.podstawy;
import java.util.Objects;
public class Osoba {
// Zmienna deklarowana na poziomie klasy to jest:
// pole (field), atrybut (attribute), zmienna instancyjna (instance variable)
......@@ -40,4 +42,36 @@ public class Osoba {
return wiek >= 18;
}
@Override
public String toString() {
return imie + " " + nazwisko + " (" + wiek + " lat)";
}
// Błędna realizacja equals - jako parametr zadeklarowana Osoba
// public boolean equals(Osoba other) {
// return this.imie.equals(other.imie)
// && this.nazwisko.equals(other.nazwisko)
// && this.wiek == other.wiek;
// }
// Prawdziwa metoda equals jako swój parametr musi przyjmować Object
// Tutaj wygenerujemy standardowe implementacje equals i hashCode oferowane przez edytor
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Osoba other = (Osoba) obj;
return Objects.equals(imie, other.imie) && Objects.equals(nazwisko, other.nazwisko) && wiek == other.wiek;
}
@Override
public int hashCode() {
return Objects.hash(imie, nazwisko, wiek);
}
}
package p11_klasy.podstawy;
import java.util.HashSet;
import java.util.Set;
public class Porownywanie {
public static void main(String[] args) {
......@@ -44,7 +47,15 @@ public class Porownywanie {
System.out.println("b: " + b.hashCode());
System.out.println("c: " + c.hashCode());
System.out.println("r: " + r.hashCode());
System.out.println();
Set<Osoba> set = new HashSet<>();
set.add(a);
set.add(b);
set.add(c);
set.add(r);
System.out.println("Rozmiar zbioru: " + set.size());
System.out.println(set);
}
}
......@@ -4,7 +4,7 @@ public class Wypisywanie {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 30);
Osoba b = new Osoba("Ola", "Malinowska", 30);
Osoba b = new Osoba("Ola", "Malinowska", 40);
// co się dzieje, gdy wypisujemy obiekt?
System.out.println(a);
......
package p11_klasy.podstawy_v2;
import java.util.HashSet;
import java.util.Set;
public class Porownywanie {
public static void main(String[] args) {
......@@ -44,7 +47,15 @@ public class Porownywanie {
System.out.println("b: " + b.hashCode());
System.out.println("c: " + c.hashCode());
System.out.println("r: " + r.hashCode());
System.out.println();
Set<Osoba> set = new HashSet<>();
set.add(a);
set.add(b);
set.add(c);
set.add(r);
System.out.println("Rozmiar zbioru: " + set.size());
System.out.println(set);
}
}
package p11_klasy.podstawy_v3;
import java.util.Objects;
public class Osoba {
// Zmienna deklarowana na poziomie klasy to jest:
// pole (field), atrybut (attribute), zmienna instancyjna (instance variable)
// Każdy obiekt tej klasy zawiera pola (które nie są statyczne).
String imie, nazwisko;
int wiek;
// Klasa może posiadać wiele konstruktorów, które różnią się liczbą lub typem parametrów
Osoba() {
}
Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
{ // blok inicjalizacyjny - fragment kodu, który wykona się podczas tworzenia każdego obiektu
// jeszcze przed konstruktorem
System.out.println("powstaje obiekt Osoba");
}
static {
// blok inicjalizacyjny statyczny - wykonuje się raz, gdy klasa jest ładowana do maszyny wirtualnej
System.out.println("static Osoba");
}
// Metoda to czynność, którą "potrafi wykonać obiekt".
// nie piszemy już "static"
// Wewnątrz metody można odwoływać się do pól należących do obiektu.
// Te odwołania można poprzedzać this ("ten obiekt, w którym jesteśmy), ale w Javie nie trzeba tego robić.
void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
}
boolean pelnoletnia() {
return wiek >= 18;
}
@Override
public String toString() {
return imie + " " + nazwisko + " (" + wiek + " lat)";
}
// Błędna realizacja equals - jako parametr zadeklarowana Osoba
// public boolean equals(Osoba other) {
// return this.imie.equals(other.imie)
// && this.nazwisko.equals(other.nazwisko)
// && this.wiek == other.wiek;
// }
// Prawdziwa metoda equals jako swój parametr musi przyjmować Object
// Tutaj wygenerujemy standardowe implementacje equals i hashCode oferowane przez edytor
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Osoba other = (Osoba) obj;
return Objects.equals(imie, other.imie) && Objects.equals(nazwisko, other.nazwisko) && wiek == other.wiek;
}
@Override
public int hashCode() {
return Objects.hash(imie, nazwisko, wiek);
}
}
package p11_klasy.podstawy_v3;
import java.util.HashSet;
import java.util.Set;
public class Porownywanie {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 30);
Osoba b = new Osoba("Ola", "Malinowska", 30);
Osoba c = new Osoba("Ala", "Kowalska", 30);
Osoba r = a;
System.out.println("\nWszystkie obiekty:");
System.out.println("a: " + a);
System.out.println("b: " + b);
System.out.println("c: " + c);
System.out.println("r: " + r);
// operator == sprawdza "czy to jest ten sam obiekt"
// porównywane są adresy, a nie zawartość obiektów
System.out.println("\nPorównanie ==:");
System.out.println("a == a: " + (a == a));
System.out.println("a == b: " + (a == b));
System.out.println("a == c: " + (a == c));
System.out.println("a == r: " + (a == r));
// Metoda equals ma służyć do logicznego porównywania obiektów.
// Bardzo często działa tak, że sprawdza, czy zawartość obiektów jest równa (np. tak jest dla Stringów)
// Ale dla własnej klasy TO AUTOR KLASY MUSI ZDEFINIOWAĆ metodę equals,
// aby działała w taki sposób. Domyślnie equals działa tak samo jak ==
System.out.println("\nPorównanie eq:");
System.out.println("a eq a: " + a.equals(a));
System.out.println("a eq b: " + a.equals(b));
System.out.println("a eq c: " + a.equals(c));
System.out.println("a eq r: " + a.equals(r));
// Metoda hashCode zwraca liczbę int na podstawie obiektu.
// Domyślnie jest to liczba uzyskiwana na podstawie adresu; taka, aby była unikalna w skali maszyny wirtualnej
// Autor klasy może zmienić definicję hashCode i POWINIEN TO ZROBIĆ jeśli definiuje equals
// Jeśli obiekty są równe w sensie equals, to hasz kody muszą być równe
// Jeśli obiekty są różne (equals daje false), to haszkody z dużym prawdopodobieństwem powinny być różne.
// Zazwyczaj własny hashCode jest jakąś formą sumy kontrolnej wyliczaj na podstawie wartości pól.
System.out.println("\nHasz kody:");
System.out.println("a: " + a.hashCode());
System.out.println("b: " + b.hashCode());
System.out.println("c: " + c.hashCode());
System.out.println("r: " + r.hashCode());
System.out.println();
Set<Osoba> set = new HashSet<>();
set.add(a);
set.add(b);
set.add(c);
set.add(r);
System.out.println("Rozmiar zbioru: " + set.size());
System.out.println(set);
}
}
package p11_klasy.podstawy_v3;
public class Przyklad0 {
public static void main(String[] args) {
// Dzięki temu, że istnieje klasa Osoba, możemy zadeklarować zmienną typu Osoba.
Osoba o;
// ale uwaga - w Javie sama deklaracja zmiennej nie tworzy obiektu
// System.out.println(o); - błąd kompilacji - niezainicjowana zmienna
// można też utworzyć nowy obiekt klasy Osoba i wpisać go do zmiennej
o = new Osoba();
System.out.println(o);
// Najczęściej w jednej linii deklaruje się zmienną i wpisuje nowy obiekt:
Osoba p = new Osoba();
System.out.println(p);
// Każdy obiekt w języku Java (nawet zupełnie pustej klasy)
// posiada pewne metody, które można uruchomić.
// toString - zwraca tekstową postać obiektu
String s = o.toString();
System.out.println(s);
// getClass - zwraca "obiekt klasy" z informacjami nt klasy, do której należy obiekt
System.out.println(o.getClass());
Class<?> klasa = o.getClass();
System.out.println("pakiet: " + klasa.getPackageName() + ", klasa " + klasa.getSimpleName());
// equals i hashCode związane z porównywaniem obiektów
System.out.println("hasz o : " + o.hashCode());
System.out.println("hasz p : " + p.hashCode());
if(o.equals(p)) {
System.out.println("obiekty równe");
} else {
System.out.println("obiekty nierówne");
}
// metody wait (z kilku wersjach) i notify - służą do synchronizacji wątków w aplikacjach wielowątkowych
// toString, equals, hashCode często są nadpisywane przez autorów klas.
}
}
package p11_klasy.podstawy_v3;
public class Przyklad1 {
public static void main(String[] args) {
Osoba a = new Osoba();
Osoba b = new Osoba();
System.out.println("Początkowe wartości pól:");
System.out.println(a.imie + " " + a.nazwisko + " " + a.wiek);
a.imie = "Ala";
a.nazwisko = "Kowalska";
a.wiek = 30;
b.imie = "Basia";
b.nazwisko = "Malinowska";
b.wiek = 40;
// Każdy obiekt posiada własne wartości pól.
System.out.println("Ustawione wartości pól:");
System.out.println("a: " + a.imie + " " + a.nazwisko + " " + a.wiek);
System.out.println("b: " + b.imie + " " + b.nazwisko + " " + b.wiek);
System.out.println();
// wywołanie metody na obiekcie
a.przedstawSie();
b.przedstawSie();
System.out.println();
a.wiek++;
a.przedstawSie();
b.przedstawSie();
if(a.pelnoletnia()) {
System.out.println(a.imie + " jest pełnoletnia");
} else {
System.out.println("ALARM");
}
// Obiektów w Javie nie usuwa się w sposób jawny - robi to "garbage collector" gdy zauważa,
// że do obiektu nie ma już dostępu (nie ma możliwości użycia)
// Dzieje się to asynchronicznie, czyli nie wiemy kiedy dokładnie.
}
}
package p11_klasy.podstawy_v3;
public class Przyklad2_Konstruktory {
public static void main(String[] args) {
System.out.println("Początek main");
// Tworzenie obiektów na zasadzie:
// - konstruktor domyślny, które niezainicjowane pola (null, 0)
// - a następnie wpisujemy wszystkie wartości
// ma dwie wady:
// 1) rozwlekłość zapisu
// 2) przez jakiś czas obiekt nie jest poprawnie zainicjowany, nie jest gotowy do pracy
// programista może "zapomnieć" wpisać dane do pól i działać z takim upośledzonym obiektem
Osoba a = new Osoba();
a.imie = "Ala";
a.przedstawSie(); // Ala null 0 lat
a.nazwisko = "Kowalska";
a.wiek = 30;
a.przedstawSie();
System.out.println();
// Gdy w klasie zdefiniujemy odpowiedni konstruktor, będziemy mogli tworzyć obiektu od razu wypełnione danymi
Osoba b = new Osoba("Ola", "Malinowska", 20);
b.przedstawSie();
}
static {
System.out.println("blok statyczny w programie");
}
}
package p11_klasy.podstawy_v3;
public class Wypisywanie {
public static void main(String[] args) {
Osoba a = new Osoba("Ala", "Kowalska", 30);
Osoba b = new Osoba("Ola", "Malinowska", 40);
// co się dzieje, gdy wypisujemy obiekt?
System.out.println(a);
System.out.println(b);
System.out.println();
// Java zamienia obiekt na postać tekstową za pomocą metody toString:
String s = a.toString();
System.out.println(s);
// to samo dzieje się, gdy dodajemy obiekt do string lub gdy używamy metody String.valueOf:
// String.valueOf(cokolwiek) jest uniwersalnym sposobem, aby stworzyć st
s = String.valueOf(a);
System.out.println(s);
System.out.println("Witamy osobę: " + a);
}
}
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