Docsity
Docsity

Przygotuj się do egzaminów
Przygotuj się do egzaminów

Studiuj dzięki licznym zasobom udostępnionym na Docsity


Otrzymaj punkty, aby pobrać
Otrzymaj punkty, aby pobrać

Zdobywaj punkty, pomagając innym studentom lub wykup je w ramach planu Premium


Informacje i wskazówki
Informacje i wskazówki

Zaawansowane programowanie obiektowe, Notatki z Programowanie obiektowe

lang nie wymaga importu (m.in. zawiera klasy String i System). Przykład 3: import java.awt.Button; // importuje nazwę klasy Java ...

Typologia: Notatki

2022/2023

Załadowany 24.02.2023

Osholom
Osholom 🇵🇱

4.5

(35)

192 dokumenty

Podgląd częściowego tekstu

Pobierz Zaawansowane programowanie obiektowe i więcej Notatki w PDF z Programowanie obiektowe tylko na Docsity! Zaawansowane programowanie obiektowe Wykład 1 JAVA Język java  Rok 1990, Bill Joy:  „utworzenie obiektowego środowiska w oparciu o C++”  Język OAK (Object Application Kernel), 1991  Projekt Green, James Gosling, Patrick Naughton, Mike Sheridan Przetwatzanie progtamów użytkownika Edytor MyProgram.java Interpretator Kompilator PC - Windows 95/NT < MyProgram.class Interpretator SUN - Solaris Cechy języka Java  automatyczne odśmiecanie (garbage collection)  nie dopuszcza arytmetyki wskaźnikowej  ścisła kontrola typów (konwersje)  obsługa wyjątków  wbudowane elementy współbieŜności Przykład  Programem w języku Java jest aplikacja (application) lub aplet (applet).  Aplikacja jest programem samodzielnym, zaś aplet jest programem wbudowanym (np. w przeglądarkę WWW).  KaŜda aplikacja musi zawierać dokładnie jeden moduł źródłowy nazywany modułem głównym aplikacji, którego klasa zawiera publiczną funkcję klasy Jak działa interpretator?  wyszuka plik o nazwie Hello.class,  czy klasa Hello zawiera publiczną metodę statyczną main  wykona instrukcje zawarte w bloku main.  W języku Java kaŜda instrukcja kończy się średnikiem, który pełni rolę symbolu terminalnego. Jak działa interpretator?  do metody main jako parametr jest przekazywana (z wiersza rozkazowego) tablica obiektów (łańcuchów) klasy String; metoda main nie zwraca wyniku (typem zwracanym jest void);  Ciało main zawiera jedną instrukcję;  System.out.print("Hello, World!\n"); Jak działa interpretator?  Słowo System jest nazwą klasy w standardowym środowisku języka.  Klasa System zawiera statyczny obiekt składowy typu PrintStream o nazwie out  wywołanie System.out oznacza pisanie do standardowego strumienia wyjściowego. package moje.aplikacje; import javax.swing.*; import java.awt.Container; class PierwszyGUI extends JFrame { public PierwszyGUI () { ... } } class KlasaStartowa { PierwszyGUI ob1; PierwszyGUI ob2 = new PierwszyGUI (); public static void main (String[] args) { ... } } Określenie nazwy pakietu, do którego naleŜą klasy zdefiniowane w tym pliku. MoŜna opuścić. Zewnętrzne pakiety (ew. pojedyncze klasy lub interfejsy), z których korzystamy w naszym programie. MoŜna uwaŜać ten element jako odpowiednik dyrektywy #include w C/C++. Definicje klas (klasy mogą dziedziczyć, jak w tym przykładzie). Metoda main klasy startowej. To od niej rozpoczyna się wykonywanie aplikacji. Musi być to metoda public static ! Inna klasa. Posiada składniki, które mogą być inicjalizowane. Definicja konstruktora. Aplikacja graficzna import javax.swing.*; class GUI extends JFrame { public static void main (String[] args) { GUI gui = new GUI (); gui.setSize (300, 200); gui.show (); } } Klasa z metodą main dziedzicząca z klasy JFrame (opisującej okienko graficzne), która pochodzi z pakietu javax.swing. Korzysta z najprostszych odziedziczonych metod. Struktura programu package ... // deklaracja pakietu (niekonieczna) import ... // deklaracje importu; zwykle, a1e nie zawsze potrzebne import ... /** Komentarz dokumentacyjny zaczyna się ukośnikiem z dwoma gwiazdkami, kończy gwiazdką i ukośnikiem */ // To jest klasa A <- to jest komentarz public class A { . . . } /* To jest komentarz wielowierszowy */ // To jest klasa B class B { ...... } Klasy (przypomnienie)  class nazwy klasy  {  Ciało klasy  }  Przed słowem kluczowym class moŜe wystąpić jeden ze specyfikatorów:  abstract, public, final, lub  dwa z nich:  np. public abstract, public final.  Abstract: klasa abstrakcyjna nie moŜe wystąpić;  final: klasa nie moŜe mieć podklas;  Brak specyfikatora: klasa dostępna tylko dla tego pakietu;  Po nazwie klasy mogą wystąpić frazy: a) ‘extends nazwa_superklasy’ b) ‘implements nazwy_interfejsów’.  a) klasa dziedziczy publicznie (zawsze) od klasy superklasa.  b) w danej klasie zostaną zdefiniowane metody, zadeklarowane w implementowanych interfejsach. Przykład  public class Point { int x, y; } równowaŜne  public class Point { int x, y; public Point() { super(); } } przykład  class Point {int x,y; Point() {x=1; y=2;}}  class CPoint extends Point {public int color = 0xFF00FF;}  public class Super1 {  public static void main(String args[]){  CPoint cp=new CPoint();  System.out.println("cp.color="+cp.color);  System.out.println("cp.x="+cp.x);  }//end main  }//end Super1 class Point ( int x,y; Point(int m, int y) (this.x = x; this.y=y; | | class CPoint extends Point I static final int WHITE = 0, BLACK = 1; int color; CPoint(int x, int y) f this(x,y,WHITE); | CPoint(int x, int y, int color) ( super(x,y); this.color=color; ) l public class Super2 | public static void main(String args[]) | int a= 10, b= 20; CPoint cp = new CPoint(a,b); System.out.println("cp.color= " + cp.color); System.out.println("cp.x= " + cp.x); |//end main ł//end Super? Interfejsy interface Speakable { int QUIET = 0; int LOUD = 1; String getVoice(int voice); } interface Moveable { void startMoving(); void stopMoving(); } class Pies extends Zwierz implements Speakable, Moveable { Pies () {} Pies(String s) { super(s); } String getTyp(){ return "Pies"; } public String getVoice(int voice) { if (voice == LOUD) return "HAU... HAU... HAU... "; else return "hau... hau..."; } public void startMoving() { System.out.println("Pies " + name +"biegnie"); } public void stopMoving() { System.out.println("Pies " + name +"stanął"); } } Interfejsy Pies kuba = new Pies("Kuba"); kuba.startMoving(); System.out.println(kuba.getVoice(Speakable.LOUD)); kuba.stopMoving(); void Wyscig(Moveable[] objects) { for (int i =0; i < objects.length; i++) objects[i].startMoving(); } Wyscig( new Moveable[] { new Pies(), new Samochod(), new Kot(), new Rower() } ); Pakiety Przykład 2: Java.awt.Button b = new Java.awt.Button("0k"); Przykład 4: import java.awt.*; // importuje wszystkie nazwy klas pakietu java.awt class A { Frame f = new Frame("Tytuł");// teraz moŜemy uŜyć teŜ prostej nazwy klasy Button b = new Button("0k");// teraz moŜemy uŜyć teŜ prostej nazwy klasy } Pakiet java.lang nie wymaga importu (m.in. zawiera klasy String i System). Przykład 3: import java.awt.Button; // importuje nazwę klasy Java.awt.Button class A { java.awt.Frame f = new java.awt.Frame("Tytuł"); Button b = new Button("Ok"); } Przykład 1: package moj_pakiet; Słowo kluczowe this SYTUACJA 1 class Para { int a; int b; void add(int a, int b){ this.a + = a ; this.b + = b; } } p.add(p1).add(p2).add( p3); co jest inną formą zapisu: p.add(p1); p.add(p2); p.add(p3); SYTUACJA 2 Para add(Para p) { a = a + p.a; b = b + p. b; return this; } SYTUACJA 3: patrz wywołanie konstruktora z innego konstruktora Składowe statyczne Uwaga: Ze statycznych metod nie wolno odwoływać się do niestatycznych składowych klasy (obiekt moŜe nie istnieć). MoŜliwe są natomiast odwołania do innych statycznych składowych. Przykład: statyczne pole i metoda Para p1 = null,p2 = null; . . . . . . if (Para.count == 0) Para p1 = new Para(1,1); else while (Para.count < 10) { p2 = new Para(2,2); p1.add(p2); } System.out.println(p1.count); Para.showCount(); p1.showCount(); p2.showCount(); class Para{ static int count = 0; Para(int x, int y) { count++; a = x; b = y; } static void showCount() { System.out.println ("Liczba utworzonych par: "+count); } } Słowo kluczowe final Thinking in Java, Bruce Eckel Pole statyczne i finalne  Zajmuje tylko jeden określony fragment pamięci i nie moŜe ulec zmianie  static final int A=5;  static final int a= rand.nextInt(20); Finalne obiekty  Stała jest referencja a nie obiekt, do którego się odwołuje  MoŜna zmienić zawartość obiektu, ale referencja nie moŜe pokazywać na inny obiekt class Value { int i = 1; } public class FinalData { //stale czasu kompilacji: final int i1 = 9; static final int VAL_TWO = 99; public static final int VAL_THREE = 39; // Typowa stała publiczna final int i4 = (int)(Math.random()*20); static final int i5 = (int)(Math.random()*20); Value v1 = new Value(); final Value v2 = new Value(); static final Value v3 = new Value(); final int[] a = { 1, 2, 3, 4, 5, 6 }; public void print(String id) { System.out.println( id + ": " + "i4 = " + i4 + ", i5 = " + i5); }  class Poppet {  private int i;  Poppet (int ii) {i=ii;} }  public class BlankFinal {  final int i = 0; // Zainicjowana zmienna ostateczne  final int j; // Pusta zmienna ostateczna  final Poppet p; // Puste odwołanie ostateczna  BlankFinal() {  j = 1; // Inicjalizacja zmiennej ostatecznej  p = new Poppet();  }  BlankFinal(int x) {  j = x; // Inicjalizacja zmiennej ostatecznej  p = new Poppet();  }  public static void main(String[] args) {  BlankFinal bf = new BlankFinal();  } } ///:~ Finalne argumenty metody  Wewnątrz metody nie moŜna zmieniać wartości;  public class FinalArguments {  void with(final Gizmo g) {  //! g = new Gizmo(); // Niepoprawne -- g jest ostateczna  }  void without(Gizmo g) {  g = new Gizmo(); // OK -- g nie jest ostateczna  g.spin();  } Metody finalne  Blokada metody, zabronienie klasom wydziedziczonym zmian (zapobieganie przesłonięciu)  Wydajność wywołanie w miejscu inline  ominięcie normalnej procedury włączenia kodu  kopiowanie rzeczywistego kodu  Decydujący rozmiar kodu metody  decyzja po stronie kompilatora Javy Interface interfejsy  Klasy abstrakcyjne – udostępniają interfejs, bez definicji  Forma klasy:  Nazwa metody  Lista argumentów  Typy zwracane  Zawierają pola: static final (ale nie puste zmienne finalne)  Metody : public Przykład – „wielokrotne dziedziczenie” w Javie  interface CanFight {  void fight();  }  interface CanSwim {  void swim();  }  interface CanFly {  void fly();  }  class ActionCharacter {  public void fight() {}  }  class Hero extends ActionCharacter  implements CanFight, CanSwim, CanFly {  public void swim() {}  public void fly() {} } public class Adventure { static void t(CanFight x) { x.fight(); } static void u(CanSwim x) { x.swim(); } static void v(CanFly x) { x.fly(); } static void w(ActionCharacter x) { x.fight(); } public static void main(String[] args) { Hero h = new Hero(); t(h); // Traktuje h jako CanFight u(h); // Traktuje h jako CanSwim v(h); // Traktuje h jako CanFly w(h); // Traktuje h jako ActionCharacter }} ///:~ Typy danych Typy proste wartości logiczne: prawda lub fałsz true false1boolean znaki Unicodu-0...655562char -1.xE+308...1.xE3088double liczby rzeczywiste-3.xE+38...3.xE+384float -9223372036854775808 ...9223372036854775807 8long -2147483648...21474836474int -32768...327672short liczby całkowite-128...127lbyte Znaczenieprzedziały wartościLiczba bajtów Nazwa typu Deklaracje Deklaracje typów prostych deklaracja jest zarazem definicją - wydziela w pamięci miejsce na przechowanie zmiennej danego typu. Deklaracja zmiennej typu obiektowego jest faktycznie deklaracją (i definicją) referencji do obiektu, nie wydziela natomiast w pamięci miejsca na przechowanie samego obiektu. String s ; s = "ala ma kota"; int a = l; String s = "ala ma kota"; Operatory i wyraŜenia Nierówności!= Operatory równości -== 6, lewe Stwierdzenie typuinstanceof Operatory relacyjne< <= >= > 5, lewe Przesunięcie bitowe w prawo bez znaku >>> Przesunięcie bitowe w prawo>> Przesunięcie bitowe<< 4, lewe NazwaOperatorPriorytet, Wiązanie Operatory i wyraŜenia Operatory przypisania%= += &= |= <<=13, prawe Operator warunku?:12, prawe Logiczna alternatywa||11, Logiczna koniunkcja&&10, Bitowa alternatywa|9, Bitowe wyłączające ALBO^8. Bitowa koniunkcja&7, NazwaOperatorPriorytet, Wiązanie Operatory x = a > b; //x  boolean!!! x = a > b && c<d; String s1; String s2 = "Napis"; s1 = s2 + " tralala"; s1 = s1 + s2; int k = 1; s1 = k + k + s2; // 2Napis s1 = s2 + k + k; // Napis11 s1 = s2 + (k+k); // Napis2 s1 = k + k; // błąd kompilacji (jeden z argumentów musi być typu String) Instrukcja break int i = 0; int j = 0; outerloop: // etykieta while (i < 100) { i++; while(true) { j++; . . . . . . if (i + j > 10) break outerloop; // przerwanie pętli oznaczonej etykietą outerloop, a nie bieŜącej } } Zasięg zmiennych Uwaga: W Javie instrukcje wyraŜeniowe i sterujące moŜna umieszczać wyłącznie w metodach klasy lub w bloku statycznym Zasięg identyfikatora - fragment programu, w którym moŜe być uŜywany. Zasięg składowych klasy – w kaŜdym miejscu klasy (miejsce deklaracji nieistotne) Zasięg identyfikatorów definiowanych wewnątrz metody jest lokalny. Zasięg parametrów metody jest lokalny W metodzie metoda1() moŜemy odwoływać się do zmiennej a, zmiennej b oraz metody metoda2(), a w metodzie metoda2() moŜemy odwoływać się do zmiennej a, zmiennej c i metody metoda1. class A { int a; void metoda1(){ int b; } void metoda2() { int c; } } Przesłanianie nazw zmiennych NIE W Javie nie wolno przesłaniać zmiennych lokalnych w blokach wewnętrznych: int a; { int a; // BŁĄD kompilacji } TAK W konstruktorach i metodach moŜemy przesłaniać identyfikatory pól klasy: class A { int a; void metoda(){ int a = 0; // przesłonięcie a = a + 10; // zmienna lokalna; this.a++; // pole klasy } Inicjalizacja pól Przy tworzeniu obiektu pola klasy mają zagwarantowaną inicjalizację na wartości ZERO (0, false - dla typu boolean, null - dla typów obiektowych, nie dotyczy to lokalnych zmiennych. PRZYKŁAD JAWNEJ INICJALIZACJI class Para { static String text = "Pary"; static int x = -1; int a = x+1; int b = x+1; Para() { a++; b++; } static String getText() { return text; } void show(){ System.out.println("( " + a + "," + b + ")"); } } Kolejność inicjalizacji pól REGUŁY DOTYCZĄCE KOLEJNOŚCI: •kaŜde odwołanie do klasy inicjalizuje najpierw pola statyczne •tworzenie obiektu (new) inicjalizuje pola niestatyczne, po czym wykonywany jest konstruktor •kolejność inicjalizacji pól - według ich kolejności w definicji klasy (w podziale na statyczne i niestatyczne, najpierw statyczne) NIE (błąd: forward reference) class Para { static int y = x + 1; int a = x+1; int b = x+1; static int x = - 1; } TAK class Para{ static String text = "Pary"; int a = x+1; int b = x+1; Para() { ... } Para(int x){ ... } Para(int x, int y) { ... } static int x = -1; } Typ tablicowy Deklaracja tablicy tworzy referencję. Taka deklaracja nie alokuje pamięci dla samej tablicy. int[] arr; // arr jest referencją MoŜna pisać teŜ int arr[]; // arr jest zmienną typu int[], który jest typem obiektowym Alokowanie pamięci. Rozmiar tablicy moŜe być ustalany dynamicznie podczas działania programu arr = new int[l0]; int[] tab = new int[n]; Tablice - przykłady Component[] tab=new Component[]{new Button("A"), new Button("B"), new Label("A"), new Label("B"),}; for(int i=0;i<tab.length;i++) tab[i].setBackground(Color.blue); Tablice róŜnych obiektów (takie tablice takŜe jako argument funkcji) void chgtab(byte[] t){ for( int i=0; i < t.length; i++) t[i]++; } byte[] b1 = {1, 2, 3 }; chgtab(b1); Tablice jako argumenty metod Tablice wielowymiarowe Przykładowe sposoby deklaracji i inicjalizacji: 1. inicjalizacja w nawiasach klamrowych int[][] macierz2 = new int[n][m]; int[][] macierz1 = {{ l, 2, 3 }, { 4, 5, 6}}; 2. dynamicznie Tablice wielowymiarowe Przykładowe sposoby deklaracji i inicjalizacji: 3. tablica składa się z wektorów o róŜnych rozmiarach public static void main(String[] arg) { int w[] = { 2, 3, 4 }; int n = 3; int[][] m3 = new int[n][]; // rozmiary wierszy będą zm. Dynam. for(int i = 0; i < m3.length; i++){ m3[i] = new int[w[1]]; for (int j = 0; j < m3[i].length; j++) m3[i][j] = i + j; } for (int i = 0; i < m3.length; i++) { System.out.println("Rozmiar i-go wiersza " + m3[i].length); String out = " "; for(int j = 0; j < m3[i].length; j++) out += " " + m3[i][j]; System.out.println(out); } } 80 Tablice public static void main(String[] arg) { int[] w = { 2, 3, 4 }; int n = 3; int[][] m3 = new int[n][]; // row sizes - dynamic for(int i = 0; i < m3.length; i++){ m3[i] = new int[w[i]]; for (int j = 0; j < m3[i].length; j++) m3[i][j] = i + j; } for (int i = 0; i < m3.length; i++) { System.out.println("i-th row size: " + m3[i].length); String out = " "; for(int j = 0; j < m3[i].length; j++) out += " " + m3[i][j]; System.out.println(out); } } 81 double b = 1 / 3; // ? jak w C/C++: dzielenie całkowite, wynik: 0. zastosuj 1.0 / 3.0. Konwersja danych A co teraz? int c = 1.0 / 3.0;//error Java musi być pewna, Ŝe chcesz stracić pewną część informacji int c = (int)(1.0 / 3.0);//OK 82 Typy konwersji (arithmetic) int i; short sh; sh = 5; // OK; 5 is int but is constant and // is small enough (no information loss) i = sh; // expanding, ok sh = (short)i; // OK – with the explicit cast int2int double d = 5.12; i = d; // WRONG! Conversion must be explicit // but: i = (int)d; // OK. The fraction is cut off float2int 85 Powiązanie łańcuchów znaków i liczb String s1 = "Johnny has drunk "; int count1 = 2, count2 = 1; String s2 = " beers."; String s3 = s1 + count1 + s2; String s4 = s1 + (count1 + count2) + s2; String s5 = s1 + count1 + count2 + s2; String s6 = count1 + count2 + s2; 86 Przeładowanie metod • int Fun(int x) • int Fun(float y) • int Fun(int a, float b) Wszystkie w jednej klasie Error!! • int Fun(int x) and • boolean Fun(int y) PrzeciąŜanie metod p.add(jakasPara) ; p.add(3); p.add(1,2); void add(Para p) { a += p.a; b += p.b;} void add(int i) { a += i; b += i; } void add(int i, int k){a += i; b += k; } Obiektowe konwersje rozszerzające KaŜdy obiekt moŜemy przekształcić w obiekt jego (dowolnej) nadklasy. Nazywa się to konwersją rozszerzającą albo upcasting, (up - bo w górę hierarchii dziedziczenia). Obiektowe konwersje rozszerzające dokonywane są automatycznie (nie musimy stosować operatora konwersji) przy: • przypisywaniu zmiennej-referencji odniesienia do obiektu klasy pochodnej, • przekazywaniu argumentów, gdy parametr jest typu nadklasy argumentu, • zwrocie wyniku, gdy wynik podstawiamy na zmienną oznaczającą obiekt nadklasy zwracanego wyniku. Obiektowe konwersje rozszerzające static Para sum(Para pl, Para p2, Para p3) { Para p = new Para(0,0); p.add(pl); p.add(p2); p.add(p3); return p; } Para p1 = new Para(1,2); ParaInh pi1 = new ParaInh(3,4), pi2 = new ParaInh(5,6); Para wynik = sum(pp1, pi1, pi2); Zastosowanie polimorfizmu class Zwierz { String name = "nieznany"; Zwierz() {} Zwierz(String s) {name = s; } String getTyp() {return "Jakiś zwierz";} String getName() {return name;} String getVoice(){return "?";} void speak() { System.out.println( getTyp()+" "+getName()+" mówi " +getVoice()); } } class Pies extends Zwierz { Pies(){} Pies(String s) { super(s); } String getTyp() { return "Pies"; } String getVoice() { return "HAU, HAU!"; } } class Kot extends Zwierz { Kot() {} Kot(String s) { super(s); } String getTyp() { return "Kot"; } String getVoice() { return "Miauuuu..."; } } Metody i klasy abstrakcyjne Metoda abstrakcyjna nie ma implementacji (ciała) i winna być zadeklarowana ze specyfikatorem abstract. Klasa, w której zadeklarowano jakąkolwiek metodę abstrakcyjną jest klasą abstrakcyjną i musi być opatrzona kwalifikatorem abstract. abstract class SomeClass { int n; abstract int getSomething(); void say() { System.out.println("Coś tam"); } } Abstrakcyjność klasy oznacza, iŜ nie moŜna bezpośrednio, np. w wyraŜeniu new tworzyć jej egzemplarzy. Standardowe klasy Javy  java.applet, java.awt, java.beans, java.io, java.lang, java.math, java.net, java.rmi, java.security, java.sql, java.text, java.util, javax.accessibility, javax.swing, org.omg. | Pakiety z java.util.Date data = new java.util.Date(); a import java.util.*;
Docsity logo


Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved