Programowanie w Java-w1

Transkrypt

Programowanie w Java-w1
Programowanie w Java
K.Barteczko: Ćwiczenia z Java. Wykłady i ćwiczenia, MIKOM,
Warszawa 2000.
B. Eckel: Thinking in Java. Wydanie trzecie. Edycja polska. Helion,
2003
http://kmeif.pwr.wroc.pl/Dydaktyka-->Java
Javolandia
Java
JVM
language
Java
utilities
API
Java
IDE
JVM
• Maszyna wirtualna (specyfikacja opublikowana
przez Sun)
• Interpretacja kodu pośredniego (Java bytecode),
który (z reguły) powstaje po kompilacji kodu
źródłowego Javy
• JVM jest dostępna praktycznie na wszystkie
platformy programowo sprzętowe (Windows,
Unix, Linux, Solaris, MacOS ...
JVM
"compile once, run anywhere" – Java
"write once, compile anywhere" Przenośny kod bajtowy umieszczany jest w plikach typu
.class (kaŜda klasa w oddzielnym pliku)
Przy dystrybucji duŜych programów kod bajtowy umieszcza
się a archiwach .jar
JVM wykonuje kod bajtowy interpretując go bądź stosując
technikę JIT (obecnie standard) np. Java HotSpot
JIT= kompilacja “w locie” i optymalizacja kodu
bezpośrednio przed wykonaniem
Java API
• JVM jest niezaleŜna od systemu
operacyjnego stąd nie ma OS API, w zamian
• JVM dostarczana jest łącznie ze zbiorem
bibliotek klas, które tworzą Java API
• JVM + Java API = JRE
Wersje Javy
• 1.0
• 1.1
•
•
•
•
•
•
1.2
1.3
1.4
1.5
1.6
1.7
• „Java 1” ?
• Java 2
Windows, Linux, SunOS,
Mac
Edycje (profile)
aplikacja, applet, midlet, servlet, scriptlet
•
•
•
•
J2SE http://java.sun.com/j2se/
J2EE http://java.sun.com/j2ee/index.jsp
J2ME http://java.sun.com/j2me/index.jsp
...
Java IDE
• Eclipse IDE for Java (http://www.eclipse.org)
• NetBeans IDE http://netbeans.org/
• JBuilder http://www.embarcadero.com/products/jbuilder
• IBM® Rational Application Developer for
WebSphere Software
http://www-01.ibm.com/software/awdtools/developer/application/
• BlueJ http://www.bluej.org/
• And much more
Java utilities
• javac
• jar
• javadoc
• javah
• keytool
• ...
Java language
• Wzorowany na C (uproszczenia) eliminacja
elementów sprzyjających popełnianiu
błędów (wskaźniki, destrukcja obiektów,
kontrolowanie zakresu tablic ...)
• Konsekwentnie obiektowy (bez zmiennych
i funkcji globalnych) wyjątek typy proste:
int, double, float, ...
Charakterystyka języka Smalltalk
•
•
•
•
•
Everything is an object. (wyjątek typy proste)
A program is a bunch of objects telling each
other what to do by sending messages.
Each object has its own memory made up of
other objects. (kompozycja)
Every object has a type. (instance of class)
All objects of a particular type can receive the
same messages.
• Boch: „An object has state, behavior
and identity”
OOP
• Podstawowe zadanie w programowaniu
obiektowym polega na tworzeniu nowych typów
danych (klas).
• Klasy opisują zbiory obiektów o identycznych
charakterystykach i zachowaniu.
• Programowanie obiektowe wywodzi się z
symulacji (Simula-67) i to „naśladownictwo”
rzeczywistości wyraŜa się w próbie
projektowania modeli programowych
elementów, które występują w danej dziedzinie
z zachowaniem odpowiedniej dokładności
odwzorowania.
Interfejs obiektu
• UŜyteczność obiektów sprowadza się do
tego, Ŝe są one w stanie wykonać pewną
liczbę określonych poleceń.
• Repertuar tych poleceń jest określony
przez definicję typu (klasy) i jest
nazywany interfejsem (interface)
Wykonaj polecenie twoja sprawa jak
Light lt = new Light(); // tworzymy obiekt typy/klasy Light
lt.on(); //polecenie do obiektu przekazujemy „składając”
//referencję (lt) z nazwą polecenia (on) za pomocą
kropki (.)
Tworzenie i wykorzystywanie usług
• Celem programowania jest wytworzenie
(albo lepiej odszukanie w dostępnych
bibliotekach) takiego zbioru obiektów,
które dostarczają usług
satysfakcjonujących wymagania
uŜytkownika (rozwiązują dany problem)
• Traktuj obiekty jak źródła usług
Zadania programistyczne
• Kreator klas
• Konsument klas
• Rozpoznanie i skupienie się na
• Projektant aplikacji
korzystający z usług
oferowanych przez dostępne
biblioteki klas,
• wymagane gromadzenie i
rozeznanie w usługach
oferowanych przez (często
bardzo liczne) zbiory
dostępnych klas
dziedzinie problemu,
dostarczenie implementacji
ustalonego interfejsu i jej
„ukrycie” aby uŜytkownik
(konsument klas) miał dostęp
jedynie do niezbędnych
elementów, implementację
moŜna będzie bezpiecznie
zmodyfikować a ponadto słabo
rozeznany w dziedzinie
„konsument” nic nie zepsuje
Specyfikatory dostępu
• private – dostęp tylko dla projektanta klasy,
rodzaj muru ceglanego oddzielającego twórcę
klasy od programisty-konsumenta
• public – dostęp dla kaŜdego
• protected – dostęp dla klasy pochodnej
• defualt – dostęp pakietowy - klasy z tego samego
pakietu (biblioteki) mają domyślny dostęp do składowych
klasy nieoznaczonych odpowiednim słowem kluczowym
Kompozycja-ponowne wykorzystanie
implementacji
• Relacja typu „ma” „zawiera” („has-a”),
często niedoceniana w podręcznikach,
które skupiają się na dziedziczeniu,
poniŜej notacja UML-owa (teŜ jak BlueJ)
Mikrokontroler
Licznik
Dziedziczenie
• MoŜliwe jest rozbudowanie i
wprowadzenie modyfikacji do istniejących
typów (klasa bazowa,nadklasa ... klasa
pochodna, podklasa...)
A singly rooted hierarchy
• Klasa Object wierzchołkiem dziedziczenia
wszystkich obiektów w Javie, wspólny
interfejs określony przez Object
• Np. String toString() kaŜdy obiekt „umie”
się przedstawić dostarczając znakowej
informacji o sobie. (tworząc nowe klasy
dostarczajmy rozsądnej implementacji tej
metody)
Typy Danych
• Proste - pojedyncza wartość określonego rozmiaru i
formatu (typ całkowity int 32 bity (uzupełnienie do 2),
char 16 bitów Unicode)
• Referencyjne
(Tablice, klasy i interfejsy)
W Javie niedopuszczalne jest bezpośrednie
wykorzystywanie i wykonywanie operacji na referencjach
(adresach) (jak np. w języku C), lecz wykorzystuje się nazwy
zmiennych (obiektów).
Manipulowanie obiektem
• Tylko pośrednio przez referencję
•
•
•
•
•
-analogia do
urządzenia i pilota sterującego (telewizor, okap
kuchenny) włączasz, zmieniasz kanał/szybkość wywiewu
za pomocą pilota)
String s = new String("asdf"); // s to pilot s.length()
String s; s.length() ; // ??? Sam pilot na niewiele się przyda ...
String s = "asdf"; s.length(); // teraz ok. ale to wyjątek !!!
Licznik licz = ??? „16,true, true” no!
Licznik licz = new Licznik(16, true, true); //utworzenie
obiektu typu Licznik i związanie z referencją licz
Typ
prosty
boolean
Size
Min
Max
—
—
—
Wrapper
type
Boolean
char
16-bit
Unicode 0
Unicode 216- 1
Character
byte
8-bit
-128
+127
Byte
short
16-bit
-215
+215—1
Short
int
32-bit
-231
+231—1
Integer
long
64-bit
-263
+263—1
Long
float
32-bit
IEEE754
IEEE754
Float
double
64-bit
IEEE754
IEEE754
Double
void
—
—
—
Void
Literały
wartość (liczbowa, tekstowa, itp.) wpisana bezpośrednio w kod programu
Literal
Data Type
178
Literal
Data Type
int
26.77e3
double
8864L
long
'c'
char
37.266
double
true
boolean
37.266f
float
false
boolean
Zasięg (scope)
O zasięgu w Javie (podobnie jak w C) decydują nawiasy {}
{
int x = 12;
// Only x available
{
int q = 96;
// Both x & q available
}
// Only x available // q “out of scope”
}
Zmienna zdefiniowana wewnątrz bloku ograniczonego nawiasami {}
jest dostępna tylko do końca tego bloku
{ int x = 12;
{ int x = 96; // Illegal }
}
Zasięg obiektów
{
String s = new String("a string");
} // End of scope
Referencja s do obiektu typu String znika wraz z
końcem zasięgu, ale obiekt jest dalej
przechowywany w pamięci! I pozostanie w niej tak
długo jak potrzeba.
>>W Javie nie ma potrzeby troszczenia się o
usuwanie zbędnych obiektów!<<
Odśmiecacz
• W języku Java nie ma koncepcji destruktora. W zamian
wprowadzono tzw. „odśmiecacz” (garbage collector),
który zajmuje się odzyskiwaniem pamięci po
niepotrzebnych obiektach (ale tylko tych zaalokowanych
przez operator new).
• Bezpośrednio przed usunięciem obiektu z pamięci
odśmiecacz wywołuje metodę finalize() na rzecz obiektu
co pozwala na wykonanie czynności porządkujących.
• Trzeba jednak pamiętać, Ŝe odśmiecacz działa
asynchronicznie (moŜna wymusić jego wykonanie
System.gc()) i moŜe w ogóle nie zadziałać w trakcie
działania programu (cała pamięć zostania en masse
zwrócona po jego zakończeniu).
Gospodarka pamięcią
• W Javie wszystkie obiekty alokowane są na
stercie (heap) co jest mniej efektywne niŜ
korzystanie ze stosu. Z tego powodu w
implementacjach maszyny wirtualnej Java
stosowane są specjalne algorytmy alokacji
(rodzaj pasa transmisyjnego) co daje
efektywność zbliŜoną do stosu. Przy
wyczerpywaniu się zasobów sterty do gry
wkracza odśmiecacz, który realokuje obiekty
„cofa i włącza taśmociąg ponownie”.
Tworzenie nowych typów
• class ATypeName { /* Class body goes here */ }
• „type ATypeName { /* Type body goes here */ }”
• ATypeName a = new ATypeName(); // possible?
class DataOnly {
int i;
float f;
boolean b;
}
DataOnly d = new DataOnly();
d.i = 47;
Metody, argumenty, zwracane
wartości
• returnType methodName( /* Argument list */
) { /* Method body */ }
Nazwa metody i lista argumentów
jednoznacznie identyfikuje metodę.
Metody są częścią klasy (tylko
wewnątrz klasy)
Wywoływanie metod:
objectName.methodName(arg1, arg2, arg3);
Overloading -PrzeciąŜanie
• int m(int a, float b) {...}
• int m(float a, char b) {...}
• int m(double c) {...}
• Ok.
• int m(int a, float b) {...}
• float m(int a, float b) {...}
• ??? Why not?
• float x=m(10, 3.2F);
• m(10, 3.2F); // ??? side
//effect
Konstruktor domyślny
• Jeśli zdefiniujemy klasę nie umieszczając
w niej konstruktora wówczas kompilator
automatycznie umieści w niej konstruktor
bezargumentowy zwany takŜe
konstruktorem domyślnym (default
constructor).
• Jeśli jednak zdefiniujemy chociaŜ jeden
konstruktor kompilator nie dodaje
konstruktora domyślnego!
Konstruktor domyślny
• class Hat {
Hat(int i) {}
Hat(double d) {}
}
Teraz
• new Hat(); // ???
jest niepoprawne poniewaŜ kompilator nie
znajdzie odpowiedniego konstruktora!
Słowo kluczowe this
• class Banana { void f(int i) { /* ... */ } }
• Banana a = new Banana(), b = new Banana();
• a.f(1); b.f(2);
• W rzeczywistości to wywołanie ma postać:
Banana.f(a,1); Banana.f(b,2);
• To znaczy pierwszym „ukrytym” parametrem
metody jest referencja do obiektu!
this c.d.
• Jeśli wewnątrz metody potrzebujemy referencji
do tego obiektu a nie mamy przecieŜ
identyfikatora bo jest ukryty to wykorzystujemy
słowo kluczowe this, które jest właśnie
synonimem referencji do bieŜącego (tego)
obiektu.
• Jeśli wewnątrz metody chcemy wywołać inną
metodę obiektu to moŜna to zapisać:
• this.innaMetoda(); ale nie jest to konieczne!
Kompilator realizuje to automatycznie.
this w konstruktorze
• Gdy definiujemy szereg konstruktorów w
klasie ( typowe), bardzo często
wywołujemy jeden z drugiego aby uniknąć
powielania kodu (lenistwo!). Wewnątrz
konstruktora zapis
• this(arg, arg, ...)
jest odwołaniem do innego konstruktora,
którego parametry odpowiadają liście
argumentów. Takie wywołanie musi
wystąpić na początku i tylko raz!
Przysłonięcie
• Drugim typowym zastosowaniem słowa
kluczowego this jest sytuacja, w której parametr
metody i pole składowe klasy są identyczne.
Następuje wówczas przysłonięcie pola
składowego przez ten parametr, this pozwala na
odniesienie do przysłoniętego pola składowego.
int stan;
//...
void setStan(int stan) {
this.stan = stan; } //is it really good style?
• Czy moŜna wywołać konstruktor z innej metody
(nie konstruktora)? NIE!
Metody statyczne
• Niejawne przekazanie referencji do obiektu jako
pierwszego parametru metody reprezentowanego
przez słowo kluczowe this nie ma miejsca w
przypadku metod statycznych! (które są
związane z klasą). Z wnętrza metod statycznych
nie moŜna wywoływać metod niestatycznych,
chociaŜ odwrotna operacja jest moŜliwa. Metody
statyczne moŜna wywoływać bez konieczności
uprzedniego kreowania obiektów! Jest to zresztą
zasadniczy sens istnienia metod statycznych.
Przykłady:
• Math.sin(); System.out.println();
Metody statyczne
• Statyczne metody są odpowiednikami funkcji globalnych
języka C, które w języku Java nie występują! MoŜna
napotkać argumentację, Ŝe metody statyczne nie są
obiektowo zorientowane, za ich stosowaniem
przemawiają względy praktyczne, stąd w całym API Javy
istnieją setki klas z metodami statycznymi (niektóre tzw.
utility class posiadają wyłącznie metody statyczne).
Znacznie wygodniej obliczyć cosinus kąta alfa za
pomocą:
double co = Math.cos (alfa) ;
niŜ
Math m = new Math(); double co = m.cos (alfa) ;
Konflikty nazw
• W wielomodułowych programach opracowywanych przez
zespoły programistów łatwo moŜe dochodzić do
konfliktów nazw (identyczne nazwy klas). Identyczne
nazwy mogą takŜe znaleźć się w wykorzystywanych
bibliotekach. Twórcy języka Java zaproponowali
konwencję tworzenia nazw bibliotek odwołującą się do
DNS-owej przestrzeni nazw co zapewnia jednoznaczność
gdyŜ uzyskujemy hierarchiczną wielopoziomową
przestrzeń nazw.
• pl.wroc.pwr.kmeif.mylibrary (odwrócona kolejność!)
• Ale pojawia się problem odszukania (lokalizacji)
właściwej klasy
Importowanie klas/pakietów
• Klasa jest zdefiniowana w tym samym pliku – nie ma problemu, (nie
ma potrzeby uŜywania „forward”)
• Jeśli potrzebna klasa znajduje się w innej bibliotece wskazujemy jej
lokalizację za pomocą deklaracji importu:
import java.util.ArrayList; // poza klasą!!!
Możemy także zaimportować całą bibliotekę (wszystkie klasy z tej
biblioteki):
import java.util.*; // częściej w praktyce stosowane
Uwaga: standardowe biblioteki Javy (java API) nie mają prefiksu domeny
(com.sun...)
Nie trzeba importować biblioteki (pakietu) java.lang! (Object, System
klasy opakowujące, String, Thread ...)
http://www.kmeif.pwr.wroc.pl/Dydaktyka-->Java
„HelloWorld” Program
• // HelloDate.java
import java.util.*;
public class HelloDate {
public static void main(String[] args) {
System.out.println("Hello, it's: ");
System.out.println(new Date());
}
}
Komentarze
/* This is a comment
* that continues
* across lines */
// This is a one-line comment
Komentarze dokumentacyjne związane z
narzędziem javadoc
/** A class comment */
Kompilacja
• javac HelloDate.java
Klasa HelloDate (zawierająca metodę main)
musi być zapisana w pliku o odpowiedniej
nazwie (HelloDate.java)
Inicjalizacja
• Zmienne lokalne metod muszą być
zainicjalizowane inaczej kompilator
zasygnalizuje błąd!
• void f() {
•
int i;
•
i++; // Error -- i not initialized
• }
• ChociaŜ kompilator mógłby domyślnie
inicjalizować je, przyjęto załoŜenie, Ŝe brak
takiej inicjalizacji jest częściej symptomem
błędu niŜ zamierzonym efektem.
Inicjalizacja składowych klasy
• W przeciwieństwie do zmiennych lokalnych
jawne inicjalizowanie zmiennych
składowych klasy nie jest konieczne,
jednak nie pozostawia się ich wartości
przypadkowi i inicjalizuje domyślnie
(wartości zerowe i false dla typów
prostych i null dla typów obiektowych).
• Uwaga: „null” jest słowem kluczowym
języka Java
Domyślne inicjalizacje
Primitive type Default
boolean
false
char
‘\u0000’ (null)
byte
(byte)0
short
(short)0
int
long
float
double
0
0L
0.0f
0.0d
Jednoczesna inicjalizacja wartości z
deklaracją zmiennej
class InitialValues {
boolean b = true;
char c = 'x';
byte b = 47;
short s = 0xff;
int i = 999;
long l = 1L;
float f = 3.14f;
double d = 3.14159;
Depth d = new Depth();
Depth d ; d= new Depth(); // ale nie tak!
int i = f(); // ale tak jest ok, metodę moŜna wywołać
Inicjalizacja za pomocą konstruktora
•
•
•
•
•
•
•
class Counter {
int state = 255;
public Counter(){
state = 1;
}
// . . .
Trzeba pamiętać, Ŝe najpierw inicjalizowane są
wartości zmiennych w kolejności ich
występowania dopiero później wywoływany jest
konstruktor (najpierw 255 potem 1).
Sekcja static
• class Spoon {
• static int i;
• static { //składnia podobna do metody
•
i = 47;
• }
• Blok statyczny wykonywany jest tylko raz w
momencie kreowania (pierwszego) obiektu lub
przy pierwszym dostępie do składowej statycznej
tej klasy nawet jeśli nigdy nie będzie kreowany
Ŝaden obiekt.

Podobne dokumenty