Programowanie obiektowe - Wyklad 01

Transkrypt

Programowanie obiektowe - Wyklad 01
Programowanie obiektowe
Wykład 01
Maciej Wołoszyn
mailto:[email protected]∗
27 lutego 2008
Spis treści
1
Java
1.1
1.2
1.3
2
Najważniejsze cechy j˛ezyka . . . . . . . . . . . . . . . . . . . . . . . . . .
Składnia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Przykładowy program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2
2
3
2
Typy danych
3
3
Operatory
5
4
Klasy
8
4.1
4.2
4.3
Składowe static . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dost˛ep do składników . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Dost˛ep do klas i nazwy plików źródłowych . . . . . . . . . . . . . . . . . .
11
12
12
5
Klasy biblioteczne
12
6
Tablice
14
6.1
6.2
15
16
7
Tablice wielowymiarowe . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Klasa Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Styl – konwencje, nazewnictwo itp.
16
∗ Prosz˛
e o przesyłanie na ten adres informacji o znalezionych bł˛edach,
literówkach oraz propozycji zmian i uzupełnień. Dokument przygotowano za pomoca˛ systemu LATEX. Wszelkie prawa zastrzeżone.
1
Programowanie obiektowe. Wykład 01
2
1 Java
• j˛ezyk programowania zaprojektowany przez firm˛e Sun ( → http://java.sun.com )
1.1 Najważniejsze cechy jezyka
˛
• niezależny od architektury
– programy napisane w j˛ezyku Java można uruchamiać w wielu systemach operacyjnych komputerów, a także na różnych innych urzadzeniach
˛
(np. telefony)
– kod źródłowy kompiluje si˛e do postaci pośredniej (tzw. bytecode, uniwersalny dla
wszystkich obsługiwanych systemów operacyjnych)
– do uruchomienia potrzebna jest wirtualna maszyna Javy (JVM, zależne od systemu operacyjnego środowisko uruchomieniowe; np. zawarte w pakiecie JSE
firmy Sun)
– w efekcie także:
∗ mniejsza wydajność w porównaniu do j˛ezyków typu C czy C++ – ale stale poprawiana za pomoca˛ mechanizmów takich jak just-in-time compilation (JIT)
∗ wi˛eksze zużycie zasobów komputera
• zastosowanie metodologii obiektowej – zaimplementowana od podstaw;
pierwotnym zamiarem twórców Javy było zastapienie
˛
C++
• wbudowana obsługa m.in. sieci komputerowych, graficznego interfejsu użytkownika,
wielowatkowości
˛
⇒ wraz z Java˛ dostarczana jest bardzo obszerna biblioteka klas
1.2 Składnia
• oparta na C i C++ : podobny sposób zapisu programu, definiowana zmiennych, funkcji,
bloków instrukcji;
identyczne instrukcje sterujace
˛ takie jak np.:
–
–
–
–
if
for
while
switch
Programowanie obiektowe. Wykład 01
3
1.3 Przykładowy program
Plik MojProgram.java:
// plik MUSI sie nazywac MojProgram.java !
public class MojProgram
{
public static void main(String[] args)
{
System.out.println("[MojProgram!]");
}
}
• odpowiednikiem wyst˛epujacej
˛ w C i C++ funkcji
main(int argc, char* argv[])
jest zawarta w publicznie dost˛epnej klasie metoda
public static void main(String[] args)
• od main rozpoczyna si˛e wykonywanie aplikacji
(innym rodzajem tworzonych w Javie programów sa˛ np. aplety – programy działajace
˛
zwykle na stronie WWW, w oknie przegladarki
˛
internetowej)
1. kompilacja do postaci bytecode’u:
$ javac MojProgram.java
⇒ wytworzenie pliku MojProgram.class
(lub komunikaty o bł˛edach kompilacji!)
2. uruchomienie programu nast˛epuje za pomoca˛ JVM:
$ java MojProgram
→ [MojProgram!]
2 Typy danych
• proste (primitive types)
int – 32-bitowa liczba całkowita (zakres −231 ÷ 231 − 1)
byte – 8-bitowa liczba całkowita (−128 ÷ 127)
short – 16-bitowa liczba całkowita (−32768 ÷ 32767)
long – 64-bitowa liczba całkowita (zakres −263 ÷ 263 − 1)
float – 32-bitowa liczba zmiennoprzecinkowa (precyzja ok. 7 cyfr)
double – 64-bitowa liczba zmiennoprzecinkowa (precyzja ok. 15 cyfr)
char – 16-bitowy znak kodowany jako Unicode (inaczej niż w C++! – łatwo operować
na znakach narodowych itp.)
Programowanie obiektowe. Wykład 01
4
boolean – typ logiczny (odpowiednik bool z C++), może przechowywać wartości
true lub false
– . . . oraz typ void
Uwaga: Java wymaga dokładnego przestrzegania zgodności typów, stad
˛ np. do przechowywania wartości rzeczywistych zwykle najwygodniej używać tylko typu double
Przykład: nie jest możliwe bezpośrednie (bez rzutowania) podstawienie wartości typu
double do zmiennej float:
// float fX = 1.2; /* ZLE! */
double dX = 1.2; /* OK */
• zakresy ważności nazw sa˛ ograniczone podobnie jak w C i C++ nawiasami klamrowymi
{ }
• nie jest dozwolone przesłanianie nazw, np.
{
char w = ’a’;
{
// char w = ’b’; /* ZLE */
}
}
• obiekty (instancje klas)
– wszystkie dziedzicza˛ po wspólnej, bazowej klasie Object (np.
wszystkie maja˛ metod˛e toString())
– sa˛ dost˛epne tylko poprzez referencje – nigdy bezpośrednio!
– składaja˛ si˛e z:
∗ pól (danych składowych)
∗ metod (funkcji składowych)
– tworzone sa˛ za pomoca˛ operatora new
Przykład:
(klasa String pełni w Javie podobna˛ rol˛e jak std::string w C++)
String s = new String("abc");
System.out.println("napis=[" + s + "]");
→
napis=[abc]
• Instrukcja:
dzi˛eki temu
Programowanie obiektowe. Wykład 01
5
String s;
tworzy tylko referencj˛e – nie odnosi si˛e ona jeszcze do żadnego obiektu (nie została
zainicjalizowana);
bł˛edna byłaby wi˛ec wtedy instrukcja:
System.out.println("napis=["+s+"]");
(efekt → bład
˛ kompilacji: variable s might not have been initialized)
• String (klasa obsługujaca
˛ napisy) jest przykładem jednej z bardzo wielu klas dost˛epnych w bibliotece Javy
• dla typów prostych, które same nie sa˛ obiektami, dost˛epne sa˛ klasy obudowujace
˛ (wrappers), np.
double x = -0.5;
Double obj = new Double(x);
System.out.println("obj="+obj);
→
obj=-0.5
• dla klas obudowujacych
˛
(opakowujacych)
˛
jest używany mechanizm automatycznego
opakowywania i rozpakowywania
double x = 3.0;
Double obj = x / 2.0;
double y = obj / 2.0;
System.out.println("y="+y);
→
y=0.75
• swoich odpowiedników wśród typów prostych nie maja˛ klasy służace
˛ do operacji arytmetycznych z duża˛ dokładnościa:
˛
BigInteger – liczby całkowitej dowolnego rozmiaru
BigDecimal – liczby ułamkowe z dowolna˛ precyzja˛
pozwalaja˛ one na operacje dost˛epne dla innych typów reprezentujacych
˛
liczby, z tym że
zamiast operatorów należy użyć odpowiednich metod
3 Operatory
• Java zapewnia standardowy zestaw operatorów dla typów prostych (np. arytmetyczne +
- / *, operator przypisania = itd.)
Programowanie obiektowe. Wykład 01
6
• dla obiektów maja˛ zastosowanie tylko operatory = == !=
• operatorów nie można przeładowywać
• dodatkowo klasa String pozwala na używanie operatorów + oraz +=
String s = new String("abc");
String t = new String("def");
System.out.println(s+t);
→
abcdef
• jeżeli wyrażenie rozpoczyna si˛e od obiektu typu String, to nast˛epujace
˛ po operatorze
+ wyrazy także musza˛ być typu String – w razie potrzeby kompilator b˛edzie si˛e starał
znaleźć reprezentacj˛e obiektu lub typu protego w postaci napisu
double x=-1.2;
String u = "x="+x;
System.out.println(u);
→
x=-1.2
• operator przypisania zastosowany dla obiektów kopiuje referencje!
• również operatory porównania == i != w przypadku obiektów porównuja˛ same referencje („adresy”), a nie to, na co one wskazuja˛ (zawartość obiektów)!
Przykład:
class Znak {
char z;
}
Znak a = new Znak();
Znak b = new Znak();
a.z = ’A’; b.z = ’B’;
System.out.println("a="+a.z+" b="+b.z);
b = a;
System.out.println("a="+a.z+" b="+b.z);
a.z = ’C’;
System.out.println("a="+a.z+" b="+b.z);
→ a=A b=B
a=A b=A
a=C b=C
Programowanie obiektowe. Wykład 01
7
Znak a = new Znak();
Znak b = new Znak();
a.z = ’q’;
b.z = ’q’;
System.out.println(a==b);
b=a;
System.out.println(a==b);
→
false
true
• do porównywania obiektów tworzonych z klas bibliotecznych można posłużyć si˛e metoda˛ equals(), która zwykle porównuje zawartość obiektów
String s = new String("abc");
String t = new String("abc");
System.out.println(s==t);
System.out.println(s.equals(t));
→
false
true
• operator rzutowania:
(typDocelowy)
może być używany pomi˛edzy dowolnymi typami prostymi z wyjatkiem
˛
boolean, przy
czym jawne rzutowanie jest wymagane tylko gdy istnieje groźba utraty informacji;
w przypadku obiektów rzutowanie jest możliwe tylko wewnatrz
˛ jednej „rodziny” (tzn.
powiazanych
˛
relacja˛ dziedziczenia)
int n = 1;
double z = n; //OK
//n = z; /* ZLE */
n = (int)(z+1.9);
System.out.println("z="+z+" n="+n);
→
z=1.0 n=2
• brak jest operatora w rodzaju sizeof – w Javie jest on zb˛edny:
poszczególne typy maja˛ dobrze zdefiniowane rozmiary (wi˛ec nie ma potrzeby sprawdzania np. liczby bajtów zajmowanych przez zmienna˛ typu int).
Programowanie obiektowe. Wykład 01
8
4 Klasy
• definicja:
class Nazwa
{
. . . pola, metody . . .
}
• pola moga˛ być zarówno typów prostych, jak i referencjami do obiektów
Przykład:
class CA {
int i;
String s;
}
• referencje musza˛ zostać zainicjalizowane przed użyciem, np. z wykorzystaniem operatora new w konstruktorze
• odniesienie si˛e do składników klasy nast˛epuje poprzez operator .
public static void main(String[] args) {
CA ca = new CA();
ca.i = 5;
ca.s = "to jest CA";
System.out.println(
ca.s + ", ca.i = " + ca.i);
}
→
to jest CA, ca.i = 5
• każde pole typu prostego jest domyślnie inicjalizowane wartościa:
˛
– 0 w przypadku typów liczbowych
– false dla typu boolean
– znakiem o kodzie ’\u0000’ jeśli typem jest char
Uwaga: Inicjalizacja taka dotyczy tylko pól (danych składowych) klas!
• niezainicjalizowane referencje maja˛ wartość null
• pola moga˛ być inicjalizowane równocześnie z deklaracja,˛ np.
class CA {
int x = 5;
}
Programowanie obiektowe. Wykład 01
9
lub za pomoca˛ tzw. bloku inicjalizacyjnego:
class CA {
int x;
{
x = 5;
}
}
• funkcje można w Javie definiować tylko jako metody wewnatrz
˛ klas
class CB {
void print(String s) {
System.out.println(s);
}
}
class Program {
public static void main(String[] args) {
String w = "ABC";
CB o = new CB();
o.print(w);
}
}
→ ABC
• argumenty sa˛ przesyłane do metod poprzez wartość – ale dla obiektów ta˛ wartościa˛ jest
referencja!
class CA {
int x = 5;
}
class CB {
void print(CA c){
System.out.println("x=" + c.x);
c.x = 0;
}
}
class Program {
public static void main(String[] args) {
CA a = new CA();
CB b = new CB();
b.print(a);
Programowanie obiektowe. Wykład 01
System.out.println("teraz x=" + a.x);
}
}
→
x=5
teraz x=0
? jaki skutek miałoby użycie poniższej metody zdefiniowanej w klasie CB?
void swap(CA a, CA b) {
CA t = a;
a = b;
b = t;
}
Odpowiedź: żaden!
CA w = new CA();
CA v = new CA();
w.x=-1; v.x=2;
System.out.println(w.x + " " +v.x);
b.swap(v,w);
System.out.println(w.x + " " +v.x);
→
-1 2
-1 2
dla porównania:
jeśli do klasy CA dodałoby si˛e metod˛e setX
class CA {
int x = 5;
void setX(CA c) {
x = c.x;
}
}
to w klasie CB zdefiniować można nast˛epujac
˛ a˛ metod˛e swap2:
void swap2(CA a, CA b) {
CA t = new CA();
t.setX(a);
a.setX(b);
b.setX(t);
}
10
Programowanie obiektowe. Wykład 01
11
w.x=-1; v.x=2;
System.out.println(w.x + " " +v.x);
b.swap2(v,w);
System.out.println(w.x + " " +v.x);
→
-1 2
2 -1
? Dlaczego tym razem zamiana si˛e powiodła?
4.1 Składowe static
• metody static moga˛ być uruchamiane nawet gdy nie istnieja˛ żadne obiekty danej
klasy; definiuje si˛e je wewnatrz
˛ klasy
class CC {
static void print(double x){
System.out.println("x="+x);
}
}
wywołanie nast˛epuje poprzez użycie konstrukcji
nazwaKlasy.nazwaMetody()
Przykład:
CC.print(2.3);
→
x=2.3
Uwaga: metody static (np. main) nie moga˛ si˛e bezpośrednio odnosić do składowych,
które nie sa˛ statyczne!
• pola static również nie sa˛ zwiazane
˛
z konkretna˛ instancja˛ klasy;
deklaruje si˛e je wewnatrz
˛ klasy i moga˛ być inicjalizowane równocześnie z deklaracja˛
class CD {
static int n=0;
}
CD.n = -3;
CC.print(CD.n);
Programowanie obiektowe. Wykład 01
12
→ x=-3.0
• przykładem statycznego pola jest składnik out klasy System ⇒ dlatego mogliśmy wywoływać dla niego metod˛e println, mimo że nie tworzyliśmy żadnego obiektu klasy
System
System.out.println( "System.out= "
+ System.out );
→ System.out= java.io.PrintStream@675b7986
4.2 Dostep
˛ do składników
• określany znanymi z C++ słowami kluczowymi:
– public
– protected
– private
• należy je umieszczać każdorazowo przed polem lub metoda,˛ których maja˛ dotyczyć
• w Javie nie ma natomiast możliwości deklarowania klas lub metod zaprzyjaźnionych
• brak słów kluczowych private, protected i public skutkuje jeszcze innym, domyślnym sposobem ograniczenia dost˛epu: składnik taki b˛edzie dost˛epny jedynie dla klas
z tego samego pakietu (zwykle klas w tym samym pliku i innych plikach z tego samego
katalogu), dla innych b˛edzie si˛e zachowywał tak, jakby był typu private ⇒ jest to tzw.
dost˛ep pakietowy (package access)
• protected umożliwia dost˛ep do składników nie tylko klasom potomnym, ale także
innym klasom z tego samego pakietu
4.3 Dostep
˛ do klas i nazwy plików źródłowych
• klasy moga˛ być deklarowane jako public (ogólnie dost˛epne) lub bez żadnego modyfikatora (dost˛epne w tym samym pakiecie)
• klas˛e publiczna˛ należy umieszczać w pliku o nazwie zgodnej z nazwa˛ klasy;
w tym samym pliku moga˛ si˛e znajdować również definicje innych (niepublicznych) klas
5 Klasy biblioteczne
• przed użyciem klas dodatkowych (tzn. spoza pakietu java.lang) dost˛epnych z bibliotek Javy (lub własnych pakietów) należy je dołaczyć
˛
korzystajac
˛ z polecenia:
import nazwaPakietu.NazwaKlasy ;
– lub odnosić si˛e do nich w kodzie poprzez pełna˛ nazw˛e, np.
java.util.Vector
Programowanie obiektowe. Wykład 01
13
import java.util.Date;
class Program
{
public static void main(String[] args){
Date d = new Date();
System.out.println("Dzisiaj= "+d);
}
}
→
Dzisiaj= Wed Feb 27 10:58:16 CEST 2008
• oprócz importowania pojedynczych klas można również dodać cały pakiet, np. w poprzednim przykładzie lini˛e
import java.util.Date;
można zastapić
˛ instrukcja˛
import java.util.*;
• domyślnie dost˛epne sa˛ wszystkie klasy z pakietu java.lang
należa˛ do nich m.in.:
– String
– Math – klasa zawierajaca
˛ podstawowe funkcje matematyczne takie jak np.:
sin(double x)
sqrt(double x)
oraz stałe:
E – liczba e
PI – liczba π
double x = Math.PI;
double y;
y = Math.cos(x/2);
System.out.println("cos(PI/2)="+y);
→
cos(PI/2)=6.123233995736766E-17
• pełna˛ dokumentacj˛e bibliotek Javy można pobrać do zainstalowania lub przegladać
˛
online na stronach http://java.sun.com/javase/reference/api.jsp
(np. dla wersji J2SE 5.0 pod adresem http://java.sun.com/j2se/1.5.0/docs/
api/
a dla Java SE 6 http://java.sun.com/javase/6/docs/api/ )
Programowanie obiektowe. Wykład 01
14
6 Tablice
• sa˛ obiektami definiowanymi za pomoca˛ operatora []
typ[] nazwaObiektu;
(definiuje si˛e w ten sposób jak zwykle referencj˛e do obiektu! – nie została zarezerwowane jeszcze żadna pami˛eć)
• tworzone sa˛ operatorem new
int[] t1 = new int[5];
lub jednocześnie z inicjalizacja˛
int[] t2 = {1,2,3};
String[] tab = {
new String("abc"),
new String("def")
};
? Co byłoby efektem wykonania instrukcji t1=t2; ?
• każda tablica posiada pole o nazwie length zawierajace
˛ informacj˛e o jej rozmiarze
(poszczególne elementy maja˛ numery od 0 do length-1)
for(int i=0;i<tab.length;i++)
System.out.print(tab[i]+"|");
for(int i=0;i<t1.length;i++)
System.out.print(t1[i]+"#");
for(int i=0;i<t2.length;i++)
System.out.print(t2[i]+":");
→
abc|def|0#0#0#0#0#1:2:3:
• wyjście poza tablic˛e skutkuje natychmiastowym wystapieniem
˛
sytuacji wyjatkowej
˛
java.lang.ArrayIndexOutOfBoundsException
• rozmiar tablicy może być obliczany w trakcie wykonywania programu
int N = 4;
/* ... */
double[] z = new double[N*10];
• utworzenie tablicy dla obiektów tworzy w rzeczywistości tylko tablic˛e referencji – same
obiekty też dopiero wymagaja˛ utworzenia za pomoca˛ new!
Programowanie obiektowe. Wykład 01
15
class Znak { char z=’x’; }
Znak[] ts = new Znak[3];
//System.out.println(ts[1].z); /* ZLE */
for(int i=0;i<ts.length;i++)
ts[i] = new Znak();
System.out.println(ts[1].z);
→x
⇒ próba dost˛epu do nieutworzonego elementu tablicy kończy si˛e wystapieniem
˛
wyjatku
˛
java.lang.NullPointerException
6.1 Tablice wielowymiarowe
• obiektem zawartym w każdym elemencie jednowymiarowej tablicy może być kolejna
tablica – łatwo można tworzyć wielowymiarowe tablice, także o różnych rozmiarach
poszczególnych „podtablic” (np. tablica dwuwymiarowa o wierszach różnej długości)
int[][] t = { {1,2,3}, {4,5} };
for(int i = 0; i < t.length; i++)
for(int j = 0; j < t[i].length; j++)
System.out.println("t[" + i + "]["
+ j + "] = " + t[i][j]);
→
t[0][0]
t[0][1]
t[0][2]
t[1][0]
t[1][1]
=
=
=
=
=
1
2
3
4
5
String[][] ts = new String[2][2];
for(int i = 0; i < ts.length; i++)
for(int j = 0; j < ts[i].length; j++) {
ts[i][j] = new String("ts"+i+j);
System.out.println("ts[" + i + "]["
+ j + "] = " + ts[i][j]);
}
→
ts[0][0]
ts[0][1]
ts[1][0]
ts[1][1]
=
=
=
=
ts00
ts01
ts10
ts11
Programowanie obiektowe. Wykład 01
16
6.2 Klasa Arrays
• pakiet java.util.*
• zbiór statycznych metod do typowych operacji na tablicach (np. wyszukiwanie, sortowanie, porównywanie)
int[] t = {4,2,1,3};
Arrays.sort(t);
System.out.println(Arrays.toString(t));
→ [1, 2, 3, 4]
7 Styl – konwencje, nazewnictwo itp.
• najcz˛eściej przyjmowana praktyka to nazywanie klas z dużej litery, a jeśli nazwa składa
si˛e z kilku słów to łaczenie
˛
ich w jeden napis, z zaznaczeniem pierwszych znaków
dużymi literami, np.:
MojaBardzoPotrzebnaKlasa
• nazwy metod tworzy si˛e zwykle podobnie, z tym że zaczynajac
˛ od małej litery:
pewnaPozytecznaMetoda()
• nazwy zmiennych tworzone sa˛ na tej samej zasadzie co nazwy metod; zalecane jest
unikanie nazw rozpoczynajacych
˛
si˛e od znaku podkreślenia
• stałe maja˛ nazwy pisane samymi dużymi literami, np.
Math.PI
jeśli składaja˛ si˛e z kilku słów, to rozdziela si˛e je znakiem podkreślenia, np.
WAZNA_STALA_MATEMATYCZNA
Wi˛ecej zaleceń można znaleźć w dokumencie Code Conventions for the Java Programming
Language http://java.sun.com/docs/codeconv/

Podobne dokumenty