Commit 54bb4d18 by Patryk Czarnik

Przykłady techniczne dot. klas

parent c178e38c
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
class Konto { class Konto {
int numer; int numer;
......
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
// Przy definicjach w tym pakiecie nie ma zadeklarowanego poziomu widoczności (public/private). // Przy definicjach w tym pakiecie nie ma zadeklarowanego poziomu widoczności (public/private).
// W tej sytuacji obowiązuje widoczność domyślna=pakietowa. // W tej sytuacji obowiązuje widoczność domyślna=pakietowa.
......
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
public class Polimorfizm1 { public class Polimorfizm1 {
......
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
public class Polimorfizm2 { public class Polimorfizm2 {
public static void main(String[] args) { public static void main(String[] args) {
......
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
public class Polimorfizm3 { public class Polimorfizm3 {
......
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
import java.math.BigDecimal; import java.math.BigDecimal;
......
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
......
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
class StudentInformatyki extends Student { class StudentInformatyki extends Student {
// Czasami podklasa nie ma nowych pól ani metod, a jest wprowadzana po to, aby ustalić pewne szczegóły. // Czasami podklasa nie ma nowych pól ani metod, a jest wprowadzana po to, aby ustalić pewne szczegóły.
......
package pcz.p12_dziedziczenie; package pcz.p12_dziedziczenie.a_podstawy;
public class Urzad { public class Urzad {
......
package pcz.p12_dziedziczenie.konstruktory_z_nadklasy;
class AA {
// klasa posiada konstruktor(y) z parametrami, a nie posiada konstruktora bezparametrowego
AA(String nazwa) {
}
}
/*
// wówczas nie skompiluje się podklasa bez żadnego konstruktora
class BB extends AA {
}
// ponieważ gdy nie napiszemy żadnego własnego konstruktora, automatycznie generowany jest taki:
class CC extends AA {
public CC() {
super();
}
}
// nie można również w podklasach pisać własnych konstruktorów, które nie robią super:
class DD extends AA {
String mojeImie;
DD(String imie) {
mojeImie = imie;
}
// ponieważ gdy nie napiszemy na początrku konstruktora super(...) ani this(...)
// to automatycznie wstawiane jest super() (bez parametrów)
}
class EE extends AA {
EE() {
super("Ala");
// OK
}
}
class FF extends AA {
FF(String arg) {
super(arg);
// OK
}
FF() {
this("Ola"); // wskazanie innego konstruktora z tej samej klasy
}
FF(int x) {
// this lub super muszą być pierwszą instrukcją w konstruktorze
// System.out.println(x); // gdybym odkomentował, to przestanie się kompilować
super(String.valueOf(x));
}
}
public class ProblemZKonstruktorem {
public static void main(String[] args) {
// nie ma konstruktora domyślnego - nie da się w tak prosty sposób utworzyć obiektu
AA a1 = new AA();
}
}
*/
package pcz.p12_dziedziczenie.nadpisywanie;
import java.io.FileNotFoundException;
import java.io.IOException;
class Nadklasa {
// nadklasa, z której potem będziemy dziedziczyć
int m01() {
return 34;
}
Number m02() {
return 23;
}
Nadklasa m02a() {
return this;
}
Integer m03() {
return 27;
}
String m04() {
return "Ala";
}
public String m05() {
return "Ala";
}
private String m06() {
return "Alicja";
}
public String m07(String arg) {
return "napis " + arg;
}
public void m08() throws IOException {
}
public void m09() throws IOException {
}
public void m10() throws FileNotFoundException {
}
public void m11() {
}
public void m12() {
}
@Override
public Nadklasa clone() throws CloneNotSupportedException {
return (Nadklasa)super.clone();
}
}
class Podklasa extends Nadklasa {
// typ wyniku musi być dokładnie taki sam (jeśli mówimy o typach prostych)
// long m01() {
// return 43;
// }
// short m01() {
// return 43;
// }
int m01() {
return 43;
}
// typ wyniku można "zawęzić"/"ukonkretnić" jeśli mówimy o typie klasowym
// jesli w nadklasie metoda zwraca coś bardziej ogólnego, to w podklasie można zwrócić coś bardziej konkretnego
Long m02() {
return 432L;
}
Podklasa m02a() {
return this;
}
// Number m03() {
// return 27;
// }
// nie mozna zmniejszyć poziomu widoczności
// private String m04() {
// return "Ala";
// }
// ale można zwiększyć
protected String m04() {
return "Ala";
}
// zmiejszenie widczności
// String m05() {
// return "Ala";
// }
// protected String m05() {
// return "Ala";
// }
// tutaj nie mamy do czynienia z nadpisywaniem, bo metody prywatne nie są dziedziczone
// @Override
public int m06() throws IOException {
return 9;
}
// to też nie jest nadpisanie, tylko przeciążanie (to jest inna metoda) - może być dowolna jeśli chodzi o wynik, widocznośc i wyjątki
// @Override
int m07(int arg) throws FileNotFoundException {
return 10 * arg;
}
public void m08() {
}
public void m09() throws FileNotFoundException {
//FileNotFoundException jest podklasą IOException
}
// public void m10() throws IOException {
// }
// dotyczy tylko wyjątków checked
public void m10() {
}
public void m11() throws IllegalArgumentException {
throw new IllegalArgumentException("bla bla");
}
// public void m12() throws Exception {
// }
}
package pcz.p12_dziedziczenie.nadpisywanie;
abstract class Zwierze {
Zwierze self() {
return this;
}
}
class Pies extends Zwierze {
Pies self() {
return this;
}
}
class Kot extends Zwierze {
Kot self() {
return this;
}
}
package pcz.p12_dziedziczenie.nadpisywanie_i_przeslanianie;
public class A {
static String zmienna_statyczna = "zmienna statyczna A";
String zmienna_instancyjna = "zmienna instancyjna A";
static String metoda_statyczna() {
return "metoda statyczna A";
}
String metoda_instancyjna() {
return "metoda instancyjna A";
}
}
package pcz.p12_dziedziczenie.nadpisywanie_i_przeslanianie;
public class B extends A {
static String zmienna_statyczna = "zmienna statyczna B";
String zmienna_instancyjna = "zmienna instancyjna B";
static String metoda_statyczna() {
return "metoda statyczna B";
}
String metoda_instancyjna() {
return "metoda instancyjna B";
}
}
package pcz.p12_dziedziczenie.nadpisywanie_i_przeslanianie;
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
A[] razem = { a, b };
System.out.println("A a");
System.out.println(a.zmienna_statyczna);
System.out.println(a.zmienna_instancyjna);
System.out.println(a.metoda_statyczna());
System.out.println(a.metoda_instancyjna());
System.out.println();
System.out.println("B b");
System.out.println(b.zmienna_statyczna);
System.out.println(b.zmienna_instancyjna);
System.out.println(b.metoda_statyczna());
System.out.println(b.metoda_instancyjna());
System.out.println();
for(A e: razem) {
System.out.println("element typu " + e.getClass());
System.out.println(e.zmienna_statyczna);
System.out.println(e.zmienna_instancyjna);
System.out.println(e.metoda_statyczna());
System.out.println(e.metoda_instancyjna());
System.out.println();
}
// Nadpisywanie (overriding) działa tylko dla metod instancyjnych.
// W przypadku zmiennych instancyjnych i statycznych oraz oraz metod statycznych
// mamy do czynienia z "przesłanianiem".
// Poza tym odwołania do rzeczy statycznych poprzez obiekt są tłumaczone w czasie kompilacji na odwołania do klas.
System.out.println(A.metoda_statyczna());
System.out.println(B.metoda_statyczna());
}
}
package pcz.p12_dziedziczenie.nadpisywanie_i_przeslanianie;
// nadpisywanie nie działa dla metod statycnzych.
// zmień metody cenaBiletu na static i zobacz co się stanie
class Osoba {
int cenaBiletu() {
return 6;
}
}
class Student extends Osoba {
int cenaBiletu() {
return 3;
}
}
public class TestOsobaStudent {
public static void main(String[] args) {
Osoba o = new Osoba();
Student s = new Student();
System.out.println("Bilet normalny: " + o.cenaBiletu());
System.out.println("Bilet studencki: " + s.cenaBiletu());
System.out.println();
sprzedajBilet(o);
sprzedajBilet(s);
}
static void sprzedajBilet(Osoba klient) {
System.out.println("Klientowi klasy " + klient.getClass().getSimpleName()
+ " sprzedam bilet za " + klient.cenaBiletu());
}
}
package pcz.p12_dziedziczenie.przeslanianie;
public class A {
static String zmienna_statyczna = "zmienna statyczna A";
String zmienna_instancyjna = "zmienna instancyjna A";
static String metoda_statyczna() {
return "metoda statyczna A";
}
String metoda_instancyjna() {
return "metoda instancyjna A";
}
void wypiszA() {
System.out.println(zmienna_instancyjna);
}
}
package pcz.p12_dziedziczenie.przeslanianie;
public class B extends A {
static String zmienna_statyczna = "zmienna statyczna B";
String zmienna_instancyjna = "zmienna instancyjna B";
static String metoda_statyczna() {
return "metoda statyczna B";
}
String metoda_instancyjna() {
return "metoda instancyjna B";
}
void wypiszB() {
System.out.println(zmienna_instancyjna);
}
}
package pcz.p12_dziedziczenie.przeslanianie;
public class Test {
public static void main(String[] args) {
A a = new A();
B b = new B();
A[] razem = { a, b };
System.out.println("A a");
System.out.println(a.zmienna_statyczna);
System.out.println(a.zmienna_instancyjna);
System.out.println(a.metoda_statyczna());
System.out.println(a.metoda_instancyjna());
System.out.println();
a.wypiszA();
System.out.println();
System.out.println("B b");
System.out.println(b.zmienna_statyczna);
System.out.println(b.zmienna_instancyjna);
System.out.println(b.metoda_statyczna());
System.out.println(b.metoda_instancyjna());
System.out.println();
b.wypiszA();
b.wypiszB();
System.out.println();
for(A e: razem) {
System.out.println("element typu " + e.getClass());
System.out.println(e.zmienna_statyczna);
System.out.println(e.zmienna_instancyjna);
System.out.println(e.metoda_statyczna());
System.out.println(e.metoda_instancyjna());
System.out.println();
}
// Nadpisywanie (overriding) działa tylko dla metod instancyjnych.
// W przypadku zmiennych instancyjnych i statycznych oraz oraz metod statycznych
// mamy do czynienia z "przesłanianiem".
// Poza tym odwołania do rzeczy statycznych poprzez obiekt są tłumaczone w czasie kompilacji na odwołania do klas.
System.out.println(A.metoda_statyczna());
System.out.println(B.metoda_statyczna());
}
}
package pcz.p12_dziedziczenie.przeslanianie;
// nadpisywanie nie działa dla metod statycnzych.
// zmień metody cenaBiletu na static i zobacz co się stanie
class Osoba {
int cenaBiletu() {
return 6;
}
}
class Student extends Osoba {
int cenaBiletu() {
return 3;
}
}
public class TestOsobaStudent {
public static void main(String[] args) {
Osoba o = new Osoba();
Student s = new Student();
System.out.println("Bilet normalny: " + o.cenaBiletu());
System.out.println("Bilet studencki: " + s.cenaBiletu());
System.out.println();
sprzedajBilet(o);
sprzedajBilet(s);
}
static void sprzedajBilet(Osoba klient) {
System.out.println("Klientowi klasy " + klient.getClass().getSimpleName()
+ " sprzedam bilet za " + klient.cenaBiletu());
}
}
package pcz.p12_dziedziczenie.przeslanianie;
public class TestOverridingu {
public static void main(String[] args) {
A obiekt = new B();
System.out.println(obiekt.zmienna_statyczna);
System.out.println(obiekt.zmienna_instancyjna);
System.out.println(obiekt.metoda_statyczna());
System.out.println(obiekt.metoda_instancyjna());
// Overriding działa tylko dla metod instancyjnych. O tym która wersja metody się wykona decyduje klasa obiektu w pamięci w czasie działania programu.
// Dla zmiennych oraz dla metod statycznych o tym co się wypisze/co zadziała decyduje typ zmiennej.
}
}
package pcz.p12_dziedziczenie.superthis;
public class A {
public void print() {
System.out.println("Jestem A");
}
}
package pcz.p12_dziedziczenie.superthis;
public class B extends A {
public void print() {
System.out.println("Jestem B");
}
public void testSuper() {
this.print();
super.print();
}
}
package pcz.p12_dziedziczenie.superthis;
public class C extends B {
public void print() {
System.out.println("Jestem C");
}
}
package pcz.p12_dziedziczenie.superthis;
public class TestSuper {
public static void main(String[] args) {
System.out.println("sprawdzam B");
B b = new B();
b.testSuper();
System.out.println();
System.out.println("sprawdzam C");
C c = new C();
c.testSuper();
}
}
package pcz.p15_inicjalizacja.v1;
public class A {
{
// to jest "blok inicjalizacyjny"
// wykonuje się podczas tworzenia każdego obiektu, przed konstruktorem
System.out.println("init A 1");
}
A() {
System.out.println("A()");
}
{
// jeśli jest wiele bloków, to wykonują się w kolejności w jakiej zostały wpisane, ale przed konstruktorem
System.out.println("init A 2");
}
}
package pcz.p15_inicjalizacja.v1;
public class Test1 {
public static void main(String[] args) {
System.out.println("Początek main");
A a = new A();
System.out.println("Koniec main");
}
}
package pcz.p15_inicjalizacja.v1;
public class Test2 {
public static void main(String[] args) {
System.out.println("Początek main");
A a1 = new A();
A a2 = new A();
new A();
System.out.println("Koniec main");
}
}
package pcz.p15_inicjalizacja.v1;
public class X {
{ System.out.println("foo"); }
}
package pcz.p15_inicjalizacja.v2;
public class A {
static {
// to jest "blok inicjalizacyjny statyczny"
// wykonuje się gdy klasa po raz pierwszy jest potrzebna i jest ładowana do pamięci
System.out.println("static A 1");
}
{
// to jest "blok inicjalizacyjny"
// wykonuje się podczas tworzenia każdego obiektu, przed konstruktorem
System.out.println("init A 1");
}
A() {
System.out.println("A()");
}
{
// jeśli jest wiele bloków, to wykonują się w kolejności w jakiej zostały wpisane, ale przed konstruktorem
System.out.println("init A 2");
}
static {
System.out.println("static A 2");
}
}
package pcz.p15_inicjalizacja.v2;
public class SuperStatic {
static {
System.out.println("super static");
}
}
package pcz.p15_inicjalizacja.v2;
public class Test1 {
public static void main(String[] args) {
System.out.println("Początek main");
A a = new A();
System.out.println("Koniec main");
}
}
package pcz.p15_inicjalizacja.v2;
public class Test2 extends SuperStatic {
public static void main(String[] args) {
System.out.println("Początek main");
A a1 = new A();
A a2 = new A();
new A();
System.out.println("Koniec main");
}
static {
System.out.println("static Test - jeszcze przed mainem");
}
}
package pcz.p15_inicjalizacja.v3;
public class A {
private int x = 5;
public A() {
System.out.println("konstruktor A() " + ++x);
}
static {
System.out.println("static A");
}
{
System.out.println("init A " + ++x);
}
}
package pcz.p15_inicjalizacja.v3;
public class B extends A {
static {
System.out.println("static B");
}
public B() {
// System.out.println("Konstruktor B()");
this(44);
System.out.println("Konstruktor B()");
// wywołanie this() albo super() (jeśli jest jawnie wpisane) musi być pierwszą instrukcją konstruktora
// a jeśli nie ma jawnego wywołania, to niejawnie wywoływane jest super() bez parametrów
}
{
System.out.println("init B 1");
}
public B(int arg) {
super();
// < w tym momencie wykonają się init B
System.out.println("Konstruktor B(" + arg + ")");
}
{
System.out.println("init B 2");
}
}
package pcz.p15_inicjalizacja.v3;
public class Test {
public static void main(String[] args) {
System.out.println("Początek main, wątek " + Thread.currentThread().getId());
// deklaracja zmiennej nie wymusza ładowania klasy
B bbb = null;
System.out.println("mam nulla");
System.out.println();
// A a = new A();
// System.out.println("Obiekt a utworzony\n");
B b = new B();
System.out.println("Obiekt b utworzony\n");
A c = new B(13);
System.out.println("Obiekt c utworzony\n");
System.out.println("Koniec main");
}
static {
System.out.println("static Test, wątek " + Thread.currentThread().getId());
}
}
package pcz.p15_inicjalizacja.v4;
public class A {
A() {
System.out.println("A()");
System.out.println(" w konstruktorze x == " + x); // OK
}
{
System.out.println("init A 1");
// w bloku init nie wolno odczytywać zmiennych instancyjnych, które są zadeklarowane później
//NK System.out.println(" w init 1 x == " + x); // zle, bo zmienna jest dalej
// System.out.println(y);
// ale można zapisywać!!!!
y = 20;
// System.out.println(y);
z = 50;
//NK System.out.println(z);
}
int x = Utils.przypisz(44);
int y = 10;
final int z;
{
System.out.println("init A 2");
System.out.println(" w init 2 x == " + x); // OK, bo zmienna była wcześniej
System.out.println(" w init 2 y == " + y);
System.out.println(" w init 2 z == " + z);
}
A(int i) {
System.out.println("A(int) " + i);
}
}
package pcz.p15_inicjalizacja.v4;
public class Static {
static {
System.out.println("static 1");
//NK System.out.println(" w static 1 x == " + x); // zle, bo zmienna jest dalej
}
{ // blok inicjalizacyjny obiektu może odwołać się do zmiennych statycznych
System.out.println(x);
}
static int x = Utils.przypisz(33);
static {
System.out.println("static 2");
System.out.println(" w static 2 x == " + x); // OK, bo zmienna była wcześniej
}
}
package pcz.p15_inicjalizacja.v4;
public class StaticObejscie {
static {
System.out.println("static 1");
// System.out.println(" w static 1 x == " + x);
System.out.println(" w static 1 x == " + getX()); // tu jest 0
}
final static int x = Utils.przypisz(33);
static {
System.out.println("static 2");
System.out.println(" w static 2 x == " + getX()); // tu jest 33
}
static int getX() {
return x;
}
}
package pcz.p15_inicjalizacja.v4;
public class StaticObejscie2 {
static {
System.out.println("static 1");
x = 55;
System.out.println(" w static 1 x == " + getX()); // tu jest 55
}
static int x = Utils.przypisz(33);
static {
System.out.println("static 2");
System.out.println(" w static 2 x == " + getX()); // a tu 33
}
static int getX() {
return x;
}
}
package pcz.p15_inicjalizacja.v4;
public class TestA {
public static void main(String[] args) {
System.out.println("Tworzę pierwszy obiekt...");
A a = new A();
System.out.println();
System.out.println("Tworzę drugi obiekt...");
new A(15);
}
}
package pcz.p15_inicjalizacja.v4;
public class TestStatic {
public static void main(String[] args) {
System.out.println("początek");
Static zmienna = new Static();
}
}
package pcz.p15_inicjalizacja.v4;
public class TestStaticObejscie {
public static void main(String[] args) {
System.out.println("początek");
StaticObejscie zmienna = new StaticObejscie();
}
}
package pcz.p15_inicjalizacja.v4;
public class TestStaticObejscie2 {
public static void main(String[] args) {
System.out.println("początek");
StaticObejscie2 zmienna = new StaticObejscie2();
}
}
package pcz.p15_inicjalizacja.v4;
public class Utils {
public static int przypisz(int x) {
System.out.println("przypisuję " + x);
return x;
}
}
package pcz.p15_inicjalizacja.zmienne;
public class A {
char c;
int a;
double d;
boolean bool;
String s;
Integer i;
}
package pcz.p15_inicjalizacja.zmienne;
public class TestA {
public static void main(String[] args) {
A obiekt = new A();
System.out.println(obiekt.a);
System.out.println(obiekt.bool);
System.out.println(obiekt.c);
System.out.println((int)obiekt.c);
System.out.println(obiekt.d);
System.out.println(obiekt.s);
System.out.println(obiekt.i);
}
}
package pcz.p16_widocznosc;
public class InnaKlasa {
public void metoda2(Klasa inny) {
//NK System.out.println(inny.prywatne);
System.out.println(inny.domyslne);
System.out.println(inny.chronione);
System.out.println(inny.publiczne);
}
public static void main(String[] args) {
Klasa obiekt = new Klasa();
//NK System.out.println(obiekt.prywatne);
System.out.println(obiekt.domyslne);
System.out.println(obiekt.chronione);
System.out.println(obiekt.publiczne);
}
}
package pcz.p16_widocznosc;
public class Klasa {
private int prywatne = 1;
int domyslne = 2;
protected int chronione = 3;
public int publiczne = 4;
public void metoda() {
System.out.println(this.prywatne);
System.out.println(prywatne);
System.out.println(domyslne);
System.out.println(chronione);
System.out.println(publiczne);
}
public void metoda2(Klasa inny) {
System.out.println(inny.prywatne);
System.out.println(inny.domyslne);
System.out.println(inny.chronione);
System.out.println(inny.publiczne);
inny.prywatne = 101;
}
public static void main(String[] args) {
// Tutaj nie ma dostępu, bo jesteśmy w kontekście statycznym - poziomy widoczności nie mają nic do rzeczy.
//NK System.out.println(prywatne);
//NK System.out.println(publiczne);
Klasa obiekt = new Klasa();
System.out.println(obiekt.prywatne);
System.out.println(obiekt.domyslne);
System.out.println(obiekt.chronione);
System.out.println(obiekt.publiczne);
obiekt.metoda();
Klasa innyObiekt = new Klasa();
innyObiekt.prywatne = 19;
obiekt.metoda2(innyObiekt);
System.out.println(innyObiekt.prywatne);
}
}
package pcz.p16_widocznosc;
public class KlasaZaawansowana {
private int prywatne = 1;
int domyslne = 2;
protected int chronione = 3;
public int publiczne = 4;
public void metoda() {
System.out.println(this.prywatne);
System.out.println(prywatne);
System.out.println(domyslne);
System.out.println(chronione);
System.out.println(publiczne);
//OK Nested1 zagn = this.new Nested1();
Nested1 zagn = new Nested1();
}
public void metoda2(KlasaZaawansowana inny) {
System.out.println(inny.prywatne);
System.out.println(inny.domyslne);
System.out.println(inny.chronione);
System.out.println(inny.publiczne);
inny.prywatne = 101;
}
public static void main(String[] args) {
//NK System.out.println(prywatne);
//NK System.out.println(publiczne);
KlasaZaawansowana obiekt = new KlasaZaawansowana();
System.out.println(obiekt.prywatne);
System.out.println(obiekt.domyslne);
System.out.println(obiekt.chronione);
System.out.println(obiekt.publiczne);
obiekt.metoda();
KlasaZaawansowana innyObiekt = new KlasaZaawansowana();
innyObiekt.prywatne = 19;
obiekt.metoda2(innyObiekt);
System.out.println(innyObiekt.prywatne);
Nested1 zagniezdzony = obiekt.new Nested1();
zagniezdzony.metodaX();
Nested1 zagniezdzony1 = new KlasaZaawansowana().new Nested1();
zagniezdzony1.metodaX();
Nested2 zagniezdzony2 = new Nested2();
zagniezdzony2.metodaX();
}
class Nested1 {
// klasa zagnieżdżona instancyjna
public void metodaX() {
System.out.println(prywatne);
System.out.println(domyslne);
System.out.println(chronione);
System.out.println(publiczne);
}
}
static class Nested2 {
// klasa zagnieżdżona statyczna
public void metodaX() {
// bo nie jestesmy w zadnym obiekcie = jestesmy w kontekscie statycznym
// NK System.out.println(prywatne);
// NK System.out.println(domyslne);
// NK System.out.println(chronione);
// NK System.out.println(publiczne);
}
public void metodaY(KlasaZaawansowana inny) {
System.out.println(inny.prywatne);
System.out.println(inny.domyslne);
System.out.println(inny.chronione);
System.out.println(inny.publiczne);
}
}
}
package pcz.p16_widocznosc.inny_pakiet;
import pcz.p16_widocznosc.Klasa;
public class KlasaWInnymPakiecie {
public void metoda2(Klasa inny) {
//NK System.out.println(inny.prywatne);
//NK System.out.println(inny.domyslne);
//NK System.out.println(inny.chronione);
System.out.println(inny.publiczne);
}
public static void main(String[] args) {
Klasa obiekt = new Klasa();
//NK System.out.println(obiekt.prywatne);
//NK System.out.println(obiekt.domyslne);
//NK System.out.println(obiekt.chronione);
System.out.println(obiekt.publiczne);
}
}
package pcz.p16_widocznosc.inny_pakiet;
import pcz.p16_widocznosc.Klasa;
public class Podklasa extends Klasa {
public void metoda() {
//NK System.out.println(prywatne);
//NK System.out.println(this.prywatne);
//NK System.out.println(domyslne);
System.out.println(chronione);
System.out.println(this.chronione);
System.out.println(publiczne);
//NK ((Klasa)this).chronione = 44;
((Klasa)this).publiczne = 45;
}
public void metoda2(Klasa inny) {
//NK System.out.println(inny.prywatne);
//NK System.out.println(inny.domyslne);
//NK System.out.println(inny.chronione);
System.out.println(inny.publiczne);
// Gdyby Osoba miała pole protected pesel, to:
// Osoba ma dostęp do peselu innej osoby
// Student ma dostęp do peselu innego studenta
// Student nie ma dostępu do peselu osoby
}
public void metoda3(Podklasa inny) {
//NK System.out.println(inny.prywatne);
//NK System.out.println(inny.domyslne);
System.out.println(inny.chronione);
System.out.println(inny.publiczne);
}
public static void main(String[] args) {
Klasa obiekt = new Klasa();
//NK System.out.println(obiekt.prywatne);
//NK System.out.println(obiekt.domyslne);
//NK System.out.println(obiekt.chronione);
System.out.println(obiekt.publiczne);
Podklasa obiekt2 = new Podklasa();
//NK System.out.println(obiekt2.prywatne);
//NK System.out.println(obiekt2.domyslne);
System.out.println(obiekt2.chronione);
System.out.println(obiekt2.publiczne);
Klasa obiekt3 = new Podklasa();
//NK System.out.println(obiekt3.prywatne);
//NK System.out.println(obiekt3.domyslne);
//NK System.out.println(obiekt3.chronione);
System.out.println(obiekt3.publiczne);
}
}
package pcz.p17_przeslanianie.a01_podstawy;
public class Przeciazanie1 {
// w jednej klasie można mieć wiele metod o tej samej nazwie
// pod warunkiem, że te metody różnią się listą typów parametrów
void print() {
System.out.println("print()");
}
void print(String arg) {
System.out.println("print(String) " + arg);
}
void print(int arg) {
System.out.println("print(int) " + arg);
}
void print(int arg1, int arg2) {
System.out.println("print(int, int) " + arg1 + " " + arg2);
}
// nawet tak subtelne różnice typu sa wystarczające
void print(long arg1, int arg2) {
System.out.println("print(long, int) " + arg1 + " " + arg2);
}
void print(int arg1, long arg2) {
System.out.println("print(int, long) " + arg1 + " " + arg2);
}
void print(long arg1, long arg2) {
System.out.println("print(long, long) " + arg1 + " " + arg2);
}
void print(Integer arg1, int arg2) {
System.out.println("print(Integer, int) " + arg1 + " " + arg2);
}
// nie wystarczają natomiast:
// 1) nazwy parametrów
// void print(int x, int y) {
// System.out.println("x y");
// }
// 2) typ wynikowy
// int print(int arg1, int arg2) {
// }
//
// String print(int arg1, int arg2) {
// }
public static void main(String[] args) {
new Przeciazanie1().run();
}
private void run() {
print();
print(13);
print(13, 15);
print(22L, 1);
print("Ala");
}
}
package pcz.p17_przeslanianie.a02_liczby;
public class Liczby1 {
static void m(int arg) {
System.out.println("int " + arg);
}
static void m(double arg) {
System.out.println("double " + arg);
}
static void m(String arg) {
System.out.println("String " + arg);
}
public static void main(String[] args) {
m(5);
byte b = 4;
// widening - parametr typu "węższego" może zostać przekazany do metody oczekującej typu "szerszego"
m(b);
m('A');
long l = 1;
m(l);
m(14L);
m(3.14);
}
}
package pcz.p17_przeslanianie.a02_liczby;
public class Liczby2 {
static void m(int arg) {
System.out.println("int " + arg);
}
static void m(Integer arg) {
System.out.println("Integer " + arg);
}
static void m(Double arg) {
System.out.println("Double " + arg);
}
public static void main(String[] args) {
m(5);
m('A');
int i = 3;
m(i);
Integer ii = 15;
m(ii);
m((Integer)i);
double d = 3.14;
// autoboxing
m(d);
long l = 44L;
// nie działa taka kombinacja: najpierw widening, a potem autoboxing
//NK m(l);
m((double)l);
}
}
package pcz.p17_przeslanianie.a02_liczby;
public class Liczby3 {
static void m(double arg) {
System.out.println("double " + arg);
}
public static void main(String[] args) {
m(5);
m(3.14);
Double dd = 4.44;
// unboxing
m(dd);
Long ll = 4L;
// działa taka kombinacja: najpierw unboxing, a potem widening
m(ll);
}
}
package pcz.p17_przeslanianie.a02_liczby;
public class Liczby4 {
static void m(int x, long y) {
System.out.println("Ala ma kota");
}
static void m(long x, int y) {
System.out.println("Ola ma psa");
}
public static void main(String[] args) {
//NK m(13, 14);
}
}
package pcz.p17_przeslanianie.a02_liczby;
import java.util.ArrayList;
public class ListaLiczb {
public static void main(String[] args) {
ArrayList<Integer> lista = new ArrayList<>();
System.out.println(lista);
lista.add(10);
lista.add(30);
lista.add(40);
System.out.println(lista);
lista.add(1, 20);
System.out.println(lista);
// usuń spod podanego indeksu
Integer coUsunieto = lista.remove(1);
// usuń element 40
boolean czyUsunieto = lista.remove((Integer)40);
// Przykładowo na egzaminie moga napisać:
// a to się nie skompiluje, bo ta wersja remove nie zwraca boolean
int i = 13;
//NK if(lista.remove(i)) {
//
// }
// teraz OK - ta wersja remove zwraca boolean
Integer ii = 33;
if(lista.remove(ii)) {
}
}
}
package pcz.p17_przeslanianie.a03_overloading_overriding;
// Historia: mamy klasy Osoba i Student. Metoda cenaBiletu ma zwrócić cenę biletu w zależności od rodzaju klienta.
// Wydawać by się mogło, że elegancko będzie zrobić przeciążanie. Ale...
public class BiletUlgowy1 {
private static class Osoba {
}
private static class Student extends Osoba {
}
private static class KasaBiletowa {
int cenaBiletu(Osoba klient) {
return 50;
}
int cenaBiletu(Student klient) {
return 25;
}
}
public static void main(String[] args) {
KasaBiletowa kasa = new KasaBiletowa();
Osoba osoba = new Osoba();
Student student = new Student();
System.out.println(kasa.cenaBiletu(osoba)); // 50
System.out.println(kasa.cenaBiletu(student)); // 25
System.out.println();
Osoba[] osoby = {
new Osoba(),
new Student(),
};
for (Osoba o : osoby) {
System.out.println(o.getClass().getSimpleName()
+ " dostaje bilet w cenie "
+ kasa.cenaBiletu(o));
}
// Przeciążanie działa w czasie kompilacji, w oparciu o zadeklarowany typ zmiennej, a nie typ obiektu w pamięci.
// W tym przypadku wszyscy dostaną bilety za 50 zł.
}
}
package pcz.p17_przeslanianie.a03_overloading_overriding;
// Klasy Osoba i Student posiadają metodę mówiącą czy posiada zniżkę, ale podaną jako metoda statyczna.
// To też nie działa, bo dla metod statycznych nie działa nadpisywanie!
public class BiletUlgowy2 {
private static class Osoba {
public static boolean czyMaZnizke() {
return false;
}
}
private static class Student extends Osoba {
public static boolean czyMaZnizke() {
return true;
}
}
private static class KasaBiletowa {
int cenaBiletu(Osoba klient) {
// tu zawsze wywołamy metod z klasy Osoba, tak jakby wołać Osoba.czyMaZnizke()
if(klient.czyMaZnizke()) {
return 25;
}
return 50;
}
}
public static void main(String[] args) {
KasaBiletowa kasa = new KasaBiletowa();
Osoba osoba = new Osoba();
Student student = new Student();
// niby OK
System.out.println(osoba.czyMaZnizke());
System.out.println(student.czyMaZnizke());
System.out.println();
System.out.println(kasa.cenaBiletu(osoba)); // 50
System.out.println(kasa.cenaBiletu(student)); // 50
System.out.println();
Osoba[] osoby = {
new Osoba(),
new Student(),
};
for (Osoba o : osoby) {
System.out.println(o.getClass().getSimpleName()
+ " dostaje bilet w cenie "
+ kasa.cenaBiletu(o));
}
}
}
package pcz.p17_przeslanianie.a03_overloading_overriding;
// Ta wersja poprawna, informacja czy osoba ma zniżkę jest podawana w metodzie instancyjnej, która jest nadpisywana w podklasie.
// Nieintuicyjne (nieżyciowe?... :) ) jest to, że osoba sama deklaruje czy ma zniżkę...
// Nawet patrząc z punktu widzenia dobrych/złych praktyk programistycznych nie podoba mi się to,
// że aby działał klasa KasaBiletowa muskmy dodawać nową metodę do klas Osoba i Student.
// Nadpisywanie (overriding) działa w czasie wykonania (runtime) i bierze pod uwagę faktyczną klase obiektu w pamięciu.
public class BiletUlgowy3 {
private static class Osoba {
public boolean czyMaZnizke() {
return false;
}
}
private static class Student extends Osoba {
@Override
public boolean czyMaZnizke() {
return true;
}
}
private static class KasaBiletowa {
int cenaBiletu(Osoba klient) {
if(klient.czyMaZnizke()) {
return 25;
}
return 50;
}
}
public static void main(String[] args) {
KasaBiletowa kasa = new KasaBiletowa();
Osoba osoba = new Osoba();
Student student = new Student();
// OK
System.out.println(osoba.czyMaZnizke());
System.out.println(student.czyMaZnizke());
System.out.println();
System.out.println(kasa.cenaBiletu(osoba)); // 50
System.out.println(kasa.cenaBiletu(student)); // 25
System.out.println();
Osoba[] osoby = {
new Osoba(),
new Student(),
};
for (Osoba o : osoby) {
System.out.println(o.getClass().getSimpleName()
+ " dostaje bilet w cenie "
+ kasa.cenaBiletu(o));
}
}
}
package pcz.p17_przeslanianie.a03_overloading_overriding;
// W tej wersji jawnie sprawdzamy typ obiektu.
// Działa poprawnie i okazuje się być najbardziej sensownym rozwiązaniem.
public class BiletUlgowy4 {
private static class Osoba {
}
private static class Student extends Osoba {
}
private static class KasaBiletowa {
int cenaBiletu(Osoba klient) {
if(klient instanceof Student) {
return 25;
}
return 50;
}
}
public static void main(String[] args) {
KasaBiletowa kasa = new KasaBiletowa();
Osoba osoba = new Osoba();
Student student = new Student();
System.out.println(kasa.cenaBiletu(osoba)); // 50
System.out.println(kasa.cenaBiletu(student)); // 25
System.out.println();
Osoba[] osoby = {
new Osoba(),
new Student(),
};
for (Osoba o : osoby) {
System.out.println(o.getClass().getSimpleName()
+ " dostaje bilet w cenie "
+ kasa.cenaBiletu(o));
}
}
}
package pcz.p17_przeslanianie.a03_overloading_overriding;
// Tutaj stosuję jeszcze tzw. marker interface, czyli interfejs mówiący, że niektóre klasy mają jakąś cechę
public class BiletUlgowy5 {
private static interface MaZnizke {}
private static class Osoba {
}
private static class Student extends Osoba implements MaZnizke {
}
private static class Pies implements MaZnizke {
}
private static class KasaBiletowa {
int cenaBiletu(Osoba klient) {
if(klient instanceof MaZnizke) {
return 25;
}
return 50;
}
}
public static void main(String[] args) {
KasaBiletowa kasa = new KasaBiletowa();
Osoba osoba = new Osoba();
Student student = new Student();
System.out.println(kasa.cenaBiletu(osoba)); // 50
System.out.println(kasa.cenaBiletu(student)); // 25
System.out.println();
Osoba[] osoby = {
new Osoba(),
new Student(),
};
for (Osoba o : osoby) {
System.out.println(o.getClass().getSimpleName()
+ " dostaje bilet w cenie "
+ kasa.cenaBiletu(o));
}
}
}
package pcz.p17_przeslanianie.a03_overloading_overriding;
public class Nadklasa {
public void print(Number arg) {
System.out.println("Nadklasa Number " + arg);
}
// nie ma metody od Byte
public void print(Integer arg) {
System.out.println("Nadklasa Integer " + arg);
}
public static void main(String[] args) {
Nadklasa obiekt = new Nadklasa();
obiekt.print(5);
Byte bb = 3;
obiekt.print(bb);
}
}
package pcz.p17_przeslanianie.a03_overloading_overriding;
public class Podklasa extends Nadklasa {
public void print(Number arg) {
System.out.println("Podklasa Number " + arg + " obiekt jest klasy " + arg.getClass().getSimpleName());
}
public void print(Byte arg) {
System.out.println("Podklasa Byte " + arg);
}
}
package pcz.p17_przeslanianie.a03_overloading_overriding;
public class TestNadPod {
public static void main(String[] args) {
Integer ii = 7;
Byte bb = 5;
Number n = ii;
Podklasa pod = new Podklasa();
pod.print(ii);
pod.print(bb);
pod.print(n);
System.out.println();
Nadklasa nad = pod;
nad.print(ii);
nad.print(bb);
nad.print(n);
}
}
package pcz.p17_przeslanianie.a07_varargs;
import java.util.Arrays;
public class Varargs1 {
static void test(String... slowa) {
// parametr wewnątrz metody jest widziany jako tablica
System.out.println(slowa.getClass());
System.out.println(slowa.length + " " + Arrays.toString(slowa));
System.out.println();
}
static int sum(int... liczby) {
int suma = 0;
for (int x : liczby) {
suma += x;
}
return suma;
}
//Mając metodę String..., nie można już definiować metody String[] o tej samej nazwie
// static void test(String[] tab) {
// }
/* Parametr z wielokropkiem może być tylko jeden, na samym końcu.
Te wersje się nie kompilują:
void p(String... args, int... ints) {
}
void q(int x, int... ints, int y) {
}
*/
// deklaracje są poprawne, niejednoznaczna będzie próba wywołania
static void test(int a, int... reszta) {
// OK
}
static void test(int a, int b, int... reszta) {
// OK
}
public static void main(String[] args) {
test();
test("Ala");
test("Ala", "Ola", "Ela");
System.out.println();
System.out.println(sum(1,3,5,7));
System.out.println(sum());
System.out.println();
// do takiej metody można też przekazać prawdziwą tablicę
String[] miasta = {"Warszawa", "Kraków", "Łódź"};
test(miasta);
int[] t = new int[100];
Arrays.fill(t, 7);
System.out.println(sum(t));
//NK test(1,2,3);
}
}
package pcz.p17_przeslanianie.a07_varargs;
import java.util.Arrays;
import java.util.List;
public class Varargs2 {
public static void m(String... slowa) {
// slowa jest typu String[]
System.out.println("start");
System.out.println(slowa.length); // NPE jeśli przekazano null-a
for(String slowo : slowa) {
System.out.println("kolejne slowo: " + slowo);
}
System.out.println();
}
// public static void m(String[] slowa) {
// nie może być jednoczesnie metody String... i String[]
// }
public static void main(String[] args) {
m();
m("ala");
m("ola", "ala", "ela");
m(null, "ola", "ala", null);
m(null, null); // tablica String[] zawierająca dwa nulle
//NPE m(null); // bo kompilator "myśli" że null jako tablica i w pętli for-each nastepuje NPE
m((String)null); // a teraz jednak tablica zawierająca nulla
String[] tablica = {"ola", "ala", "ela"};
m(tablica);
m(new String[] {"jeden", "dwa"});
//NK m({"jeden", "dwa"});
List<String> lista1 = Arrays.asList(tablica);
List<String> lista2 = Arrays.asList("ala", "ola", "ela");
}
}
package pcz.p17_przeslanianie.a07_varargs;
import java.util.Arrays;
public class Varargs3 {
public static void m(String... slowa) {
System.out.println("start");
for(String slowo : slowa) {
System.out.println("kolejne slowo: " + slowo);
}
System.out.println("koniec\n");
// slowa[0] = "55";
}
// można zadeklarować metodę, która przyjmuje normalne parametry, a tylko ostatni jest parametrem typu vararg
// w praktyce takie dwie metody jak ta i powyższa prowadziłyby do konfliktu w momencie wywołania
// public static void m(String arg, String... slowa) {
// System.out.println("start");
// for(String slowo : slowa) {
// System.out.println("kolejne slowo: " + slowo);
// }
// System.out.println("koniec\n");
// }
public static void m(Object slowo) {
System.out.println("pojedynczy obiekt "+ slowo);
System.out.println();
}
public static void m(String slowo, String slowo2) {
System.out.println("dwa slowa");
System.out.println();
}
public static int m(int... liczby) {
int suma = 0;
for(int i = 0; i < liczby.length; i++) {
suma += liczby[i];
liczby[i]++;
}
return suma;
}
public static void main(String[] args) {
//NK m(); // niejednoznaczne
m("ala");
m("ala", "ola");
m("ola", "ala", "ela");
m(null, "ola", "ala", null);
String[] tablica = {"ola", "ala", "ela"};
m(tablica);
System.out.println(m(1,3,5,7,9));
int[] ti = {10,20,30};
System.out.println(Arrays.toString(ti));
System.out.println(m(ti));
System.out.println(Arrays.toString(ti));
}
}
package pcz.p19_enkapsulacja.v1_brak_enkapsulacji;
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: " + saldo + ", wł: " + wlasciciel;
}
// Brak kontroli nad tym co się dzieje z saldem.
// Da się ustawić niepoprawne saldo.
// Gdybym zapragnął dodać rejestrowanie historii zmiana, nie byłbym w stanie zapanować nad wszystkimi odwołaniami do zmiennej saldo.
}
package pcz.p19_enkapsulacja.v1_brak_enkapsulacji;
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.");
}
public String toString() {
return imie + " " + nazwisko + " (" + wiek + " lat)";
}
}
package pcz.p19_enkapsulacja.v1_brak_enkapsulacji;
import java.util.stream.DoubleStream;
public class Program {
public static void main(String[] args) {
// Gdy klasy nie stosują zasad enkapsulacji, to programy mogą bezpośrednio używać zmiennych z tych klas:
Student student = new Student("Ada", "Nowak", 22, "biologia", 2);
System.out.println(student.imie);
student.imie = "Adam";
student.dodajOcene(3.5);
student.dodajOcene(4.5);
// Programy mogą zakładać, że zmienna oceny jest typu tablica
// wtedy po ewentualnej zmianie na listę - programy przestaną się kompilować
double[] oceny = student.oceny;
// Nie zawsze ten dostęp jest celowym "psuciem", czasami inny programista korzysta z naszej zmiennej z dobrymi intencjami.
// Ten kod nie robi nic złego, ale kompiluje się tylko przy założeniu, że student.oceny jest tablicą double[]
System.out.println("średnia wyliczona streamem: " + DoubleStream.of(student.oceny).sum() / student.iloscOcen);
// Są też jednak zagrożenia...
// Dostęp do tablicy jest też groźny, bo program może modyfikować zawartość
for (int i = 0; i < oceny.length; i++) {
oceny[i] += 1;
}
Konto konto = new Konto(1, 1000, student);
// można w szczególności wpisać "bez żadnego uzasadnienia" saldo w koncie
konto.saldo = 5000;
konto.saldo += 10000;
// możemy doprowadzić do ujemnego saldo - nie ma żadnej kontroli
konto.saldo -= 40000;
System.out.println(konto);
}
}
package pcz.p19_enkapsulacja.v1_brak_enkapsulacji;
public class Sklep {
public void sprzedajPiwo(Osoba klient) {
if(klient.wiek >= 18) {
System.out.println("Osoba " + klient.imie + " " + klient.nazwisko + " kupuje piwo.");
} else {
System.out.println("Niepełnoletnia " + klient.imie + " nie może kupić piwa");
}
}
}
package pcz.p19_enkapsulacja.v1_brak_enkapsulacji;
import java.util.ArrayList;
import java.util.List;
public class Student extends Osoba {
String kierunek;
int rok;
double[] oceny = new double[10];
// Teraz zmiana typu zmiennej, zmiana "wewnętrznej reprezentacji", spowoduje, że inne klasy w projekcie przestaną się kompilować.
// List<Double> oceny = new ArrayList<>();
int iloscOcen = 0;
Student() {
}
public Student(String imie, String nazwisko, int wiek, String kierunek, int rok) {
super(imie, nazwisko, wiek);
this.kierunek = kierunek;
this.rok = rok;
}
void dodajOcene(double ocena) {
oceny[iloscOcen++] = ocena;
}
double sredniaOcen() {
double suma = 0.0;
for (int i = 0; i < iloscOcen; i++) {
suma += oceny[i];
}
return suma / iloscOcen;
}
void przedstawSie() {
System.out.println("Hej tu " + imie + " " + nazwisko + ", jestem studentem " + rok + " roku kierunku " + kierunek);
}
}
package pcz.p19_enkapsulacja.v3_przed_zmiana;
public class Konto {
private int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
return saldo;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł: " + wlasciciel;
}
// Jedynymi sposobami modyfikacji salda są metody wplata i wyplata.
// Żadna inna klasa w projekcie, choćby było 1000 klas, nie modyfikuje salda z pominięciem tych metod.
// na razie bez zabezpieczeń
public void wplata(int kwota) {
saldo += kwota;
}
public void wyplata(int kwota) {
saldo -= kwota;
}
}
package pcz.p19_enkapsulacja.v3_przed_zmiana;
import java.time.LocalDate;
import java.time.Period;
public class Osoba {
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.imie = imie;
this.nazwisko = nazwisko;
this.setDataUrodzenia(dataUrodzenia);
}
public String getImie() {
return imie;
}
public void setImie(String imie) {
this.imie = imie;
}
public String getNazwisko() {
return nazwisko;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setDataUrodzenia(LocalDate dataUrodzenia) {
this.dataUrodzenia = dataUrodzenia;
}
public int getWiek() {
Period period = Period.between(dataUrodzenia, LocalDate.now());
return period.getYears();
}
public void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + getWiek() + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " (" + getWiek() + " lat)";
}
public boolean jestPelnoletnia() {
return getWiek() >= 18;
}
}
package pcz.p19_enkapsulacja.v3_przed_zmiana;
import java.time.LocalDate;
public class Program {
public static void main(String[] args) {
Student student = new Student("Ada", "Nowak", LocalDate.of(1999, 9, 19), "biologia", 3);
System.out.println(student.getImie());
student.setImie("Adam");
// Teraz program nie ma jak dostać się do tablicy ocen
// double[] oceny = student.oceny;
student.dodajOcene(4.0);
student.dodajOcene(5.0);
student.dodajOcene(4.0);
System.out.println(student.sredniaOcen());
Konto konto = new Konto(1, 1000, student);
// Teraz żadna inna klasa nie będzie mogła "bez uzasadnienia" modyfikować salda;.
// Musi użyć jednej z "operacji biznesowych".
// konto.saldo = 5000;
// konto.saldo -= 40000;
konto.wplata(5000);
System.out.println(konto);
// na razie też możemy doprowadzić do ujemnego salda
konto.wyplata(40000);
System.out.println(konto);
}
}
package pcz.p19_enkapsulacja.v3_przed_zmiana;
import java.time.LocalDate;
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", LocalDate.of(1991, 3, 4));
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":
break petla;
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;
}
} catch(Exception e) {
System.out.println("Inny błąd: " + e);
}
System.out.println();
System.out.println(konto);
System.out.println();
}
}
}
package pcz.p19_enkapsulacja.v3_przed_zmiana;
public class Sklep {
public void sprzedajPiwo(Osoba klient) {
if(klient.jestPelnoletnia()) {
System.out.println("Osoba " + klient.getImie() + " " + klient.getNazwisko() + " kupuje piwo.");
} else {
System.out.println("Niepełnoletnia " + klient.getImie() + " nie może kupić piwa");
}
}
}
package pcz.p19_enkapsulacja.v3_przed_zmiana;
import java.time.LocalDate;
import java.util.Arrays;
public class Student extends Osoba {
private String kierunek;
private int rok;
// Ukrywamy szczegóły implementacji - klient nie musi wiedzieć, w jaki sposób przechowujemy oceny studenta ("to nasza prywatna sprawa")
// Żadna inna klasa nie może odwoływać się bezpośrednio do tej tablicy.
private double[] oceny = new double[10];
private int iloscOcen = 0;
public Student() {
}
public Student(String imie, String nazwisko, LocalDate dataUrodzenia, String kierunek, int rok) {
super(imie, nazwisko, dataUrodzenia);
this.kierunek = kierunek;
this.rok = rok;
}
public String getKierunek() {
return kierunek;
}
public void setKierunek(String kierunek) {
this.kierunek = kierunek;
}
public int getRok() {
return rok;
}
public void setRok(int rok) {
this.rok = rok;
}
public void dodajOcene(double ocena) {
if(iloscOcen == oceny.length) {
oceny = Arrays.copyOf(oceny, oceny.length*2); // mniej więcej coś takiego robi ArrayList oraz StringBuilder
}
oceny[iloscOcen++] = ocena;
}
public double sredniaOcen() {
double suma = 0.0;
for (int i = 0; i < iloscOcen; i++) {
suma += oceny[i];
}
return suma / iloscOcen;
}
public void przedstawSie() {
System.out.println("Hej tu " + getImie() + " " + getNazwisko() + ", jestem studentem " + rok + " roku kierunku " + kierunek);
}
}
package pcz.p19_enkapsulacja.v4_po_zmianie;
public class BrakSrodkow extends Exception {
public BrakSrodkow() {
}
public BrakSrodkow(String message) {
super(message);
}
}
package pcz.p19_enkapsulacja.v4_po_zmianie;
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");
}
if(wlasciciel == null) {
throw new IllegalArgumentException("Właściciel null");
}
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
return saldo;
}
public Osoba getWlasciciel() {
return wlasciciel;
}
public void setWlasciciel(Osoba wlasciciel) {
this.wlasciciel = wlasciciel;
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł: " + wlasciciel;
}
// Jedynymi sposobami modyfikacji salda są metody wplata i wyplata.
// Żadna inna klasa w projekcie, choćby było 1000 klas, nie modyfikuje salda z pominięciem tych metod.
public void wplata(int kwota) {
if(kwota <= 0) {
throw new IllegalArgumentException("Ujemna kwota we wplata");
}
saldo += kwota; // bezpieczniej byłoby saldo = Math.addExact(saldo, kwota)
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota <= 0) {
throw new IllegalArgumentException("Ujemna kwota we wplata");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
}
package pcz.p19_enkapsulacja.v4_po_zmianie;
import java.time.LocalDate;
import java.time.Period;
public class Osoba {
private String imie, nazwisko;
private LocalDate dataUrodzenia;
public Osoba() {
}
public Osoba(String imie, String nazwisko, LocalDate dataUrodzenia) {
this.imie = imie;
this.nazwisko = nazwisko;
this.setDataUrodzenia(dataUrodzenia);
}
public String getImie() {
return imie;
}
public void setImie(String imie) {
this.imie = imie;
}
public String getNazwisko() {
return nazwisko;
}
public void setNazwisko(String nazwisko) {
this.nazwisko = nazwisko;
}
public LocalDate getDataUrodzenia() {
return dataUrodzenia;
}
public void setDataUrodzenia(LocalDate dataUrodzenia) {
this.dataUrodzenia = dataUrodzenia;
}
public int getWiek() {
Period period = Period.between(dataUrodzenia, LocalDate.now());
return period.getYears();
}
public void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + getWiek() + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " (" + getWiek() + " lat)";
}
public boolean jestPelnoletnia() {
return getWiek() >= 18;
}
}
package pcz.p19_enkapsulacja.v4_po_zmianie;
import java.time.LocalDate;
public class Program {
public static void main(String[] args) {
Student student = new Student("Ada", "Nowak", LocalDate.of(1999, 9, 19), "biologia", 3);
System.out.println(student.getImie());
student.setImie("Adam");
// Teraz program nie ma jak dostać się do tablicy ocen
// double[] oceny = student.oceny;
student.dodajOcene(4.0);
student.dodajOcene(5.0);
student.dodajOcene(4.0);
System.out.println(student.sredniaOcen());
Konto konto = new Konto(1, 1000, student);
// Teraz żadna inna klasa nie będzie mogła "bez uzasadnienia" modyfikować salda;.
// Musi użyć jednej z "operacji biznesowych".
// konto.saldo = 5000;
// konto.saldo -= 40000;
konto.wplata(5000);
System.out.println(konto);
try {
konto.wyplata(40000);
System.out.println("Wypłata się powiodła");
} catch (BrakSrodkow e) {
System.out.println("Wypłata nieudana z powodu " + e);
}
System.out.println(konto);
}
}
package pcz.p19_enkapsulacja.v4_po_zmianie;
import java.time.LocalDate;
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", LocalDate.of(1991, 3, 4));
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":
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ć
}
} catch(IllegalArgumentException e) {
System.out.println("Niepoprawny argument: " + e);
} 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 pcz.p19_enkapsulacja.v4_po_zmianie;
public class Sklep {
public void sprzedajPiwo(Osoba klient) {
if(klient.jestPelnoletnia()) {
System.out.println("Osoba " + klient.getImie() + " " + klient.getNazwisko() + " kupuje piwo.");
} else {
System.out.println("Niepełnoletnia " + klient.getImie() + " nie może kupić piwa");
}
}
}
package pcz.p19_enkapsulacja.v4_po_zmianie;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.DoubleStream;
public class Student extends Osoba {
private String kierunek;
private int rok;
// Ukrywamy szczegóły implementacji - klient nie musi wiedzieć, w jaki sposób przechowujemy oceny studenta ("to nasza prywatna sprawa")
// Żadna inna klasa nie może odwoływać się bezpośrednio do tej tablicy.
private List<Double> oceny = new ArrayList<>();
public Student() {
}
public Student(String imie, String nazwisko, LocalDate dataUrodzenia, String kierunek, int rok) {
super(imie, nazwisko, dataUrodzenia);
this.kierunek = kierunek;
this.rok = rok;
}
public String getKierunek() {
return kierunek;
}
public void setKierunek(String kierunek) {
this.kierunek = kierunek;
}
public int getRok() {
return rok;
}
public void setRok(int rok) {
this.rok = rok;
}
public void dodajOcene(double ocena) {
oceny.add(ocena);
}
public double sredniaOcen() {
return oceny.stream().mapToDouble(x->x).average().orElse(0.0);
}
public void przedstawSie() {
System.out.println("Hej tu " + getImie() + " " + getNazwisko() + ", jestem studentem " + rok + " roku kierunku " + kierunek);
}
}
package pcz.p21_wyjatki;
import java.io.IOException;
public class DzialanieWyjatkow {
static int metoda(String arg) throws IOException {
System.out.println("Początek metody, arg = " + arg);
try {
int dlugosc = arg.length();
System.out.println("length() = " + dlugosc);
int wynik = 10 / dlugosc;
System.out.println("Znak numer 2 to " + arg.charAt(2));
switch(arg) {
case "NULL":
NullPointerException wyjatek = new NullPointerException("Moje NPE");
throw wyjatek;
case "ERROR":
long[] t = new long[2000_000_000];
//throw new OutOfMemoryError("Na niby");
break;
case "IOEXC":
throw new IOException("Na niby");
case "RETURN":
System.out.println("Przerywam metodę return");
return 8;
case "EXIT":
System.out.println("Przerywam program EXIT");
System.exit(0);
}
System.out.println("Koniec metody, zwracam " + wynik);
return wynik;
} finally {
System.out.println("FINALLY w metodzie");
}
}
public static void main(String[] args) throws IOException {
System.out.println("Początek main");
try {
int x = -1;
x = metoda("ala");
//x = metoda(null);
//x = metoda("");
//x = metoda("As");
//x = metoda("NULL");
//x = metoda("ERROR");
//x = metoda("RETURN");
//x = metoda("EXIT");
System.out.println("Metoda się wykonała, wynik to " + x);
if(x > 2) {
System.out.println("Przerywam maina");
return;
}
System.out.println("Przed catchami");
} catch(NullPointerException e) {
System.out.println("Wyłapałem wyjątek NPE " + e.getMessage());
} catch(Exception e) {
System.out.println("Wyłapałem inny wyjątek " + e.getClass().getSimpleName() + " " + e.getMessage());
// } catch (Error e) {
// System.out.println("Wyłapałem ERROR " + e.getClass().getSimpleName() + " " + e.getMessage());
// } catch (Throwable e) {
// System.out.println("Wyłapałem coś " + e.getClass().getSimpleName() + " " + e.getMessage());
} finally {
System.out.println("FINALLY w main");
}
System.out.println("Koniec main");
}
}
package pcz.p21_wyjatki;
import java.io.FileInputStream;
import java.io.IOException;
public class KiedyTrzebaLapac {
public static void main(String[] args) {
String s = "123";
// tutaj może dojść do błędu NumberFormatException
// nie ma błędu kompilacji - ten wyjątek należy do kategorii "unchecked"
int x = Integer.parseInt(s);
System.out.println(x);
// operacje dotyczące plików mogą kończyć się wyjątkiem IOException
// tym razem musimy te wyjątki jawnie obsłużyć - za pomocą try-catch albo throws
// bo IOException jest wyjątkiem z kategorii "checked"
try {
FileInputStream in = new FileInputStream("plik.txt");
int bajt;
while((bajt = in.read()) != -1) {
System.out.println("kolejny bajt: " + bajt);
}
in.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
package pcz.p21_wyjatki;
class BrakSrodkow extends Exception {
}
class Konto {
public void wyplata(int kasa) throws BrakSrodkow {
// usunięcie throws spowoduje błąd kompilacji w uzytkowniku
}
}
class Uzytkownik {
public static void main(String[] args) {
Konto k = new Konto();
try {
k.wyplata(400);
System.out.println("jest kasa");
} catch(BrakSrodkow e) {
System.out.println("nie ma kasy");
}
}
}
package pcz.p21_wyjatki;
public class ProsteDzialanieWyjatkow {
static void metoda(String arg) {
try {
System.out.println("Początek metody: " + arg);
int x = arg.length();
System.out.println("Długość napisu: " + x);
if(x == 1) {
return; // przerwanie metody
}
int y = 10 / x;
System.out.println("Wynik dzielenia: " + y);
} finally {
System.out.println("FINALLY w metodzie");
}
}
public static void main(String[] args) {
try {
//metoda("Ala ma kota");
metoda(null);
// metoda("");
// metoda("A");
System.out.println("Przed catch");
} catch(NullPointerException e) {
System.out.println("Był wyjątek NPE");
} finally {
System.out.println("FINALLY w main");
}
System.out.println("Koniec programu");
}
}
package pcz.p21_wyjatki;
public class ProsteDzialanieWyjatkow_BezCatch {
static void metoda(String arg) {
System.out.println("Początek metody: " + arg);
int x = arg.length();
System.out.println("Długość napisu: " + x);
if(x == 1) {
return; // przerwanie metody
}
int y = 10 / x;
System.out.println("Wynik dzielenia: " + y);
}
public static void main(String[] args) {
metoda("Ala ma kota");
// metoda(null);
// metoda("");
// metoda("A");
System.out.println("Przed catch");
System.out.println("Koniec programu");
}
}
package pcz.p21_wyjatki;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class ZasadyWyjatkow1 {
public static void main(String[] args) {
// try {
// System.out.println("Ala ma kota");
// File f = new File("plik.txt");
// // tu na pewno nie ma IOException
//
// } catch (IOException e) {
// // nie kompiluje się - ale to dotyczy tylko wyjątków "checked"
// System.out.println("wyjątek którego nie ma prawa być");
// }
try {
} catch(NullPointerException e) {
// RuntimeExceptiony można zawsze próbować łapać
System.out.println("NPE którego nie było");
}
try {
} catch(Exception e) {
// exception i Throwable można łapać zawsze, bo one obejmują w sobie RuntimeException i Error
}
try {
Scanner sc = new Scanner(new File("ala.txt"));
// konstruktor Scanner() deklaruje FileNotFoundException
// można łapać IOException, bo to jest nadklasa
sc.close();
} catch(IOException e) {
System.out.println("IOEx");
}
// przykład "try-with-resources"
try(Scanner sc = new Scanner(new File("ala.txt"))) {
String linia = sc.nextLine();
System.out.println(linia);
// nie trzeba pisać close, a Java i tak zamknie plik
} catch(IOException e) {
System.out.println("IOEx");
}
}
}
package pcz.p21_wyjatki;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class ZasadyWyjatkow2 {
public static void main(String[] args) {
// try {
// System.out.println();
// } catch(Exception e) {
// System.out.println("E");
// } catch(RuntimeException e) {
// // "martwy catch", bo Exception już ten przypadek obejmowało
// System.out.println("RE");
// }
}
}
package pcz.p21_wyjatki;
public class ZasadyWyjatkow3 {
public static void main(String[] args) {
try {
System.out.println();
} catch(ArithmeticException | NullPointerException | NumberFormatException e) {
// zmienna e jest typu, który jest najbliższą wspólną nadklasą wszystkich klas wymienionych w catch
RuntimeException e2 = e;
System.out.println("multicatch złapał " + e.getMessage());
}
// pewniak na egzaminie: multi-catch, w którym coś się nie zgadza
// try {
// System.out.println();
// } catch(NumberFormatException | IllegalArgumentException e) {
// // nie kompiluje sie bo NumberFormatException jest podklasą IllegalArgumentException
// System.out.println("multicatch złapał " + e.getMessage());
// }
//
// try {
// System.out.println();
// } catch(Exception | NullPointerException e) {
// // nie można wymieniać tych klas, które są spokrewnione "w linii prostej"
// System.out.println("multicatch złapał " + e.getMessage());
// }
}
}
package pcz.p21_wyjatki;
public class ZasadyWyjatkow4 {
// temat "rethrow" - ponownego wyrzucania złapanego wyjątku
static void test1() {
try {
throw new RuntimeException();
} catch(RuntimeException e) {
System.out.println(e);
throw e;
} catch(Exception e) {
// ten catch nie wyłapie wyjątku wyrzuconego we wcześniejszym catchu
System.out.println(e);
}
}
static void test2() {
try {
throw new RuntimeException();
} catch(Exception e) {
System.out.println(e);
throw e;
// Kompilator wie, że wyrzucany jest RuntimeException
// i nie każe go deklarować / obsługiwać
}
}
static void test3() {
try {
java.sql.Connection c = java.sql.DriverManager
.getConnection("jdbc:postgresql://localhost//baza");
} catch(java.sql.SQLException e) {
throw new RuntimeException(e);
// wyrzucanie opakowanego wyjątku - jako RuntimeException nie wymaga deklaracji
}
}
static void test4() {
try {
try {
System.out.println("A");
throw new RuntimeException("X");
//NK System.out.println("B"); // martwy kod
} catch(Exception e) {
System.out.println("C " + e);
throw e;
} catch(Throwable t) {
System.out.println("D " + t);
throw t;
} finally {
System.out.println("E");
}
} catch(Exception e) {
System.out.println("F " + e);
throw e;
} finally {
System.out.println("G");
}
}
static void test5() {
// throw new Exception(); // trzeba by deklarować
// throw new RuntimeException(); // nie trzeba deklarować
try {
throw new RuntimeException();
// throw new Exception(); // gdytby było to, to trzeba dekalrować throws Exception
} catch(Exception e) {
System.out.println("wyłapałem " + e + " i rzucam dalej");
throw e;
// mimo że zmienna e jest typu Exception, nie muszę deklarować tego wyrzucenia w metodzie,
// bo kompilator widzi, że e to może być najwyżej RuntimeException
}
}
public static void main(String[] args) {
test4();
}
}
package pcz.p21_wyjatki.zasoby;
public class UzycieZasobu0 {
public static void main(String[] args) {
System.out.println("początek maina");
try(Zasob z = new Zasob()) {
System.out.println("po try");
z.dzialaj();
System.out.println("koniec try");
}
System.out.println("koniec main");
}
}
package pcz.p21_wyjatki.zasoby;
public class UzycieZasobu1 {
public static void main(String[] args) {
System.out.println("początek maina");
try(Zasob z = new Zasob()) {
System.out.println("po try");
z.dzialaj();
System.out.println("koniec try");
} finally {
System.out.println("finally");
}
System.out.println("koniec main");
}
}
package pcz.p21_wyjatki.zasoby;
public class UzycieZasobu2 {
public static void main(String[] args) {
System.out.println("początek maina");
try(Zasob z = new Zasob()) {
System.out.println("po try");
z.przerwij();
System.out.println("koniec try");
} finally {
System.out.println("finally");
}
System.out.println("koniec main");
}
}
package pcz.p21_wyjatki.zasoby;
public class UzycieZasobu3 {
public static void main(String[] args) {
System.out.println("początek maina");
try(Zasob z = new Zasob()) {
System.out.println("po try");
z.przerwij();
System.out.println("koniec try");
// close wykona się przed catchem
} catch(RuntimeException e) {
System.out.println("catch");
} finally {
System.out.println("finally");
}
System.out.println("koniec main");
}
}
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