WPROWADZENIE DO JAVY
Jak działają programy w Javie
W Javie program jest zestawem klas. Oprócz deklaracji pakietu i importu nie ma żadnego kodu poza obrębem
klasy, chociaż można oczywiście umieszczać komentarze poza klasami. Program może być zapisany w jednym lub
wielu plikach źródłowych z rozszerzeniem *.java. Możliwe jest też umieszczanie klasy w klasie.
Zasada: nazwa pliku musi być taka sama jak nazwa klasy, która się w nim znajduje.
Ale jeżeli w pliku *.java znajduje się więcej niż jedna klasa?
- wówczas jedna z klas musi być publiczna i właśnie jej nazwę będzie nosił plik !
Wszystkie wybrane pliki źródłowe są kompilowane za pomocą kompilatora Javy– powstają z nich pliki o
rozszerzeniu *.class. Jeżeli w jednym pliku były dwie klasy, to powstaną dwa pliki o rozszerzeniu *.class – po
jednym dla każdej klasy.
Przykład
Po przeczytaniu
JAVA_tworzenie_projektu.pdf
utwórz projekt SalonSamochodowy i nazwij klasę
MojaPierwszaKlasa. Konwencja jest taka, że nazwy klas piszemy zawsze dużą literą. Niezależnie od nazwy
pakietu, pierwsza litera tej nazwy jest zawsze mała.
Po utworzeniu projektu od razu wykasuj szare komentarze. Kod programu wygląda następująco:
package salonsamochodowy;
public class MojaPierwszaKlasa {
public MojaPierwszaKlasa() {
}
public static void main(String[] args) {
}
}
Nasza przykładowa klasa będzie przechowywać informacje o samochodach, potrzebujemy więc pomocniczej klasy
Samochod, która będzie reprezentować dane na temat jednego samochodu. Między deklaracją pakietu, a klasą
MojaPierwszaKlasa wklej kod nowej klasy:
class Samochod{
String marka;
int przebieg;
double pojemnoscSilnika;
public Samochod(String m,int p,double ps){
marka = m;
przebieg = p;
pojemnoscSilnika = ps;
}
public String toString(){
String informacja = "Marka: "+marka;
informacja = informacja + ", przebieg: "+przebieg;
informacja = informacja + ", pojemnosc: "+pojemnoscSilnika;
return informacja;
}
}
mgr Agnieszka Patyk, Wydział FTiMS, Politechnika Gdańska, 2007
Nazwa pakietu – jeżeli dodamy
jakieś inne pliki źródłowe, to
każdy będzie miał tę linijkę
(żeby klasy widziały się na
wzajem i wiedziały, że są w tym
samym projekcie)
W NetBeansie główna klasa
projektu od razu robi się public
Konstruktor – na razie jest pusty
Funkcja main – też początkowo pusta.
Uwaga!
Funkcja main znajduje się
wewnątrz klasy – w języku C/C++ nie
należała do żadnej klasy.
Przed słowem class nie ma słowa public, bo mamy już klasę publiczną.
String to typ napisowy – zauważ, że nie musimy nigdzie
podawać ile znaków chcemy przechowywać w napisie.
Możemy po prostu przypisać wartość napisu do zmiennej, w
języku C/C++ trzeba było używać funkcji strcpy.
Dzięki tej metodzie możemy wyświetlić informacje
o obiekcie, np. korzystając z System.out.println()
– w języku C/C++ musieliśmy przedefiniować
operator <<, pisaliśmy np.:
ostream& operator << ... a potem:
cout<<zmienna;
Proszę nie zmieniać nazwy metody toString –
program się sam nie domyśli, że podczas
drukowania ma skorzystać z innej metody.
Tutaj doklejamy liczbę do napisu za pomocą plusa i nie musimy
do tego używać żadnej funkcji (a w C/C++ musieliśmy).
W funkcji main wklej dwie linijki:
Samochod mojeAuto = new Samochod("Mercedes",12050,0.1);
System.out.println(mojeAuto);
Skompiluj i uruchom program. Na dole okna powinno być wypisane:
Marka: Mercedes, przebieg: 12050, pojemnosc: 0.1
Ćwiczenia:
1.
Sprawdź, czy metoda toString jest naprawdę potrzebna – zakomentuj tę metodę (całą! a więc nie tylko
środek, ale także nagłówek i wszystkie klamerki). Skompiluj i uruchom program. Na dole ekranu powinno być
wypisane coś w rodzaju:
salonsamochodowy.Samochod@11a698a
– są to informacje o klasie, której obiekt
miały być wypisany oraz adres w pamięci. Odkomentuj z powrotem metodę toString.
2.
Dodaj w klasie Samochod nowe pole napisowe kolor – przerób też konstruktor klasy tak, by można było
dodać informacje o kolorze. W funkcji main uzupełnij dane do tworzenia samochodu.
3.
Stwórz w funkcji main drugi obiekt typu Samochod, nadaj mu jakieś inne wartości i wydrukuj go. Gdy już
będą się drukować informacje o obu samochodach, zamień funkcję System.out.println na funkcję
System.out.print – jaka jest różnica w działaniu ?
4.
Eksperyment – zamiast class Samochod wpisz public class Samochod. Poczekaj chwilę i sprawdź, co
NetBeans podkreśli na czerwono. Przeczytaj błąd, który się pokaże. Potem skasuj słowo public.
Słowo
this
Zmień konstruktor klasy Samochod tak, by wyglądał następująco:
public Samochod(String marka,int przebieg,double pojemnoscSilnika){
this.marka = marka;
this.przebieg = przebieg;
this.pojemnoscSilnika = pojemnoscSilnika;
}
Teraz przesyłane parametry nazywają się tak samo jak pola klasy. śeby nie było nieporozumienia, która zmienna
jest polem klasy, a która przyszła do konstruktora z zewnątrz, pola klasy poprzedzone zostały słowem this.
Oznacza to, że chodzi o pole tego (bieżącego) obiektu.
Warto nadawać zmiennym w konstruktorze te same nazwy, co polom klasy, żeby wiedzieć co gdzie przypisać.
Dziedziczenie
Gdzieś między klasą Samochod a klasą MojaPierwszaKlasa wklej kod nowej klasy, która będzie dziedziczyła
po klasie Samochod:
class Ciezarowy extends Samochod{
int ladownosc;
public Ciezarowy(String marka,String kolor, int przebieg,double pojemnoscSilnika,int ladownosc){
super(marka,kolor,przebieg,pojemnoscSilnika);
this.ladownosc = ladownosc;
}
public String toString(){
String informacja = "Ciezarowy - Marka: "+marka;
informacja = informacja + ", kolor: "+kolor;
informacja = informacja + ", przebieg: "+przebieg;
informacja = informacja + ", pojemnosc: "+pojemnoscSilnika;
informacja = informacja + ", ladownosc: "+ladownosc;
return informacja;
}
}
extends oznacza, że dziedziczymy po innej klasie.
Nowe pole.
super przekazuje do konstruktora klasy
nadrzędnej (a więc: Samochod) te pola,
które przyjmuje konstruktor klasy
nadrzędnej (a więc wszystko poza
ładownością). Jeżeli korzystamy z super,
to musi on być wywołany jako pierwsza
linijka w konstruktorze.
mgr Agnieszka Patyk, Wydział FTiMS, Politechnika Gdańska, 2007
Ćwiczenia:
1.
Zrób eksperyment: w konstruktorze klasy Ciezarowy zamień kolejność linijek – najpierw przypisz ładowność,
a dopiero potem wywołaj super – jaki błąd się pokazuje ? Po eksperymencie przywróć poprzednią kolejność
linijek.
2.
Dodaj jakąś własną klasę dziedziczącą po Samochod i przetestuj jej obiekt w funkcji main.
3.
Dodaj w klasie Samochod metodę:
public void cofnijLicznik(){
przebieg = przebieg - 100;
}
W funkcji main wpisz (po utworzeniu obiektów lecz przed ich wydrukowaniem) linijki:
mojeAuto.cofnijLicznik();
c1.cofnijLicznik();
Uruchom program i sprawdź, czy informacja o przebiegu samochodów drukuje się prawidłowo.
4.
Teraz dopisz w funkcji main linijki, które wypiszą same marki samochodów:
System.out.println(mojeAuto.przebieg);
System.out.println(c1.przebieg);
Linijki te przydadzą się w następnym temacie.
private, public i protected
Podobnie jak w języku C++:
- specyfikator private oznacza, że zmienna lub metoda jest dostępna tylko w danej klasie
- specyfikator protected oznacza, że jest dostępna z danej klasy i wszystkich klas dziedziczących oraz ze
wszystkich klas w danym pakiecie.
- specyfikator public oznacza, że jest dostępna zewsząd, w tym z innych pakietów.
- jeżeli nie ma specyfikatora – a w naszym przykładzie nie ma ich przed polami klasy, są akurat tylko przed
metodami toString – to oznacza, że zmienna jest zaprzyjaźniona – jest dostępna ze wszystkich klas danego
pakietu.
Eksperyment:
1.
W klasie Samochod dodaj słowo private przed każdym polem – a więc góra klasy powinna wyglądać tak:
class Samochod{
private String marka;
private String kolor;
private int przebieg;
private double pojemnoscSilnika;
..... dalsze linijki .....
Poczekaj chwilę i sprawdź, które linijki NetBeans podkreślił na czerwono. Powinny się podkreślić:
- linijki w metodzie toString klasy Ciezarowy –
skoro jest private, to nawet klasa dziedzicząca nie ma dostępu
do tych pól
- dwie linijki wypisujące przebieg w funkcji main –
skoro jest private, to nie ma dostępu z zewnętrznych klas
2.
Teraz zamień te cztery słowa private na słowa protected, poczekaj chwilę i sprawdź, co się podkreśli na
czerwono – nic się nie powinno podkreślić.
3.
Wykasuj słowa protected, zaś przed zmienną przebieg wpisz słowo private – podkreśli się na czerwono
jedna linijka w metodzie toString klasy Ciezarowy i dwie linijki w funkcji main. Dopisz w klasie Samochod
metodę, która umożliwi obejrzenie wartości zmiennej przebieg:
int getPrzebieg(){
return przebieg;
}
Dodatkowo, w linijkach podkreślonych na czerwono zamień słowo przebieg na getPrzebieg(). Skompiluj i
uruchom program.
4.
Napisz w klasie Samochod metodę, która przypisze nową wartość do zmiennej przebieg:
void setPrzebieg(int ile){
przebieg = ile;
}
W funkcji main przetestuj nową funkcję – dopisz linijki:
System.out.println("moje auto przed:"+mojeAuto.getPrzebieg());
mojeAuto.setPrzebieg(123456);
System.out.println("moje auto po:"+mojeAuto.getPrzebieg());
mgr Agnieszka Patyk, Wydział FTiMS, Politechnika Gdańska, 2007
W języku C++ pisaliśmy tylko raz private: i wszystko co
było pod spodem, było prywatne. Tutaj musimy poprzedzić
tym słowem każdą zmienną i funkcję z osobna !!! Tak
samo będzie dla public i protected.
int dlatego, że pole przebieg jest typu int.
void, bo nic nie zwracamy, tylko coś robimy.
Skompiluj i uruchom program.
Sprawdź, czy dałoby się wykonać w funkcji main linijkę:
mojeAuto.przebieg = 123456;
- dlaczego się nie da?
Przeciążenia
Podobnie jak w języku C++ możemy przeciążać metody i konstruktory.
Załóżmy, że nie mamy wszystkich danych dotyczących danego samochodu, ale i tak chcemy stworzyć obiekt. W
klasie Samochod wpisz drugi konstruktor:
public Samochod(String marka,String kolor){
this.marka = marka;
this.kolor = kolor;
przebieg = 0;
pojemnoscSilnika=0;
}
W funkcji main wpisz linijki:
Samochod nowy = new Samochod("Maybach","srebrny");
System.out.println(nowy);
Przetestuj, czy informacja o samochodzie drukuje się prawidłowo.
Teraz przeciążymy metodę setPrzebieg - w klasie Samochod dopisz:
void setPrzebieg(int ile,int jeszcze,int troche){
przebieg = ile+jeszcze+troche;
}
Przetestuj tę metodę w funkcji main korzystając z linijek:
System.out.println("moje auto przed:"+mojeAuto.getPrzebieg());
mojeAuto.setPrzebieg(100,20000,23232);
System.out.println("moje auto po:"+mojeAuto.getPrzebieg());
Uruchom program i sprawdź, czy wartość zmiennej przebieg odpowiada sumie tych trzech liczb.
Reasumując: przeciążenie jest wtedy, gdy mamy w danej klasie więcej niż jedną metodę o tej samej nazwie i
każda z nich pobiera inne parametry.
Podzielenie programu na kilka plików
Nasz program jest już dosyć spory i wypadałoby go podzielić na mniejsze kawałki.
Wybierz z menu File->New File. Pokaże się okienko, w którym po lewej musisz wybrać Java Classes, a po
prawej Empty Java File. Po naciśnięciu przycisku Next pokaże się okienko, w którym musisz wpisać (w
pierwszym polu tekstowym) nazwę klasy – wpisz Samochod i naciśnij Finish.
Pusty plik otworzył się w nowej zakładce. Przekopiuj ze starego pliku klasy Samochod oraz Ciezarowy do
nowego pliku – wykasuj je przy okazji ze starego pliku. Dodatkowo, jako pierwszą linijkę w nowym pliku wklej:
package salonsamochodowy;
- żeby pliki wiedziały, że są w tym samym projekcie.
Skompiluj i uruchom program.
Pytania sprawdzające zrozumienie materiału
Plik javowy po skompilowaniu ma rozszerzenie _ _ _ _ _.
Funkcja main nie znajduje się w żadnej klasie. TAK/NIE
Funkcja main jest publiczna i ma specyfikator static. TAK/NIE
Typ napisowy nazywa się S _ _ _ _ g.
Musimy podać, ile liter chcemy mieć w zmiennej napisowej. TAK/NIE
Nie da się po prostu przypisać napisu do zmiennej napisowej za pomocą ‘=’. DA SIĘ/NIE DA SIĘ
Możemy sklejać liczby z napisami za pomocą znaku ________ .
Zamiast operatora << do wyświetlania przyda się funkcja t o _ _ _ _ _ g.
Jeżeli wyświetlamy jakiś obiekt, ale nie ma funkcji toString, to program się skompiluje, ale będzie dziwnie
wyświetlał informacje. TAK/NIE
Metoda System.out.println po wydrukowaniu przechodzi do nowej linii. TAK/NIE
Metoda System.out.print po wydrukowaniu przechodzi do nowej linii. TAK/NIE
Dziedziczymy po jakiejś klasie używając słowa _ x _ _ _ _ _.
Odwołujemy się do konstruktora nadrzędnej klasy słowem _ _ p _ _.
Wpisujemy zera do pól, których zawartości nie znamy.
mgr Agnieszka Patyk, Wydział FTiMS, Politechnika Gdańska, 2007
Jeżeli korzystamy z super, to musi on być wywołany jako ___________ linijka w konstruktorze.
super przekazuje wartości do konstruktora klasy nadrzędnej. TAK/NIE
Drukujemy na ekranie za pomocą System.out._ _ _ _ _ .
Jaki typ zwraca funkcja toString? _ _ _ _ _ _
Metoda może nic nie zwracać. TAK/NIE
Metoda może nie pobierać żadnych parametrów. TAK/NIE
Jeżeli zmienna jest private to mogę ją np. wydrukować na zewnątrz klasy. TAK/NIE
Można przeciążyć konstruktor. TAK/NIE
Mogę mieć w klasie kilka metod o tej samej nazwie, pod warunkiem, że pobierają różne parametry. TAK/NIE
Mogę mieć w klasie kilka konstruktorów o tej samej nazwie, pod warunkiem, że pobierają różne parametry.
TAK/NIE
Konstruktor może nic nie pobierać i nic nie robić. TAK/NIE
W przedstawionych przykładach nazwy metod pisaliśmy MAŁĄ/DUśĄ literą.
Jeżeli chcemy się odwołać do bieżącego obiektu, to używamy słowa _ _ i _.
Jeżeli zmienna jest private, to klasa dziedzicząca będzie miała do niej dostęp. TAK/NIE
Jeżeli zmienna jest protected, to klasa dziedzicząca będzie miała do niej dostęp. TAK/NIE
Jeżeli zmienna jest public, to klasa dziedzicząca będzie miała do niej dostęp. TAK/NIE
Nawet jeżeli zmienimy nazwę funkcji toString, to program nadal będzie dobrze wyświetlał informacje o obiekcie.
TAK/NIE
mgr Agnieszka Patyk, Wydział FTiMS, Politechnika Gdańska, 2007