Pierwszy program obiektowy

Tym razem wykorzystamy mechanizmy programowania obiektowego (ang. Object oriented programming). To co go będzie odróżniało od innych to fakt, że będzie on rozbity początkowo na dwa, a później na więcej plików, z których każdy będzie stanowił oddzielną klasę, a to z kolei pozwoli nam na jej reprezentację w innej klasie jako obiekt.

Najprostszym przykładem jaki przychodzi mi do głowy jest przedstawienie za pomocą jednej klasy punktu, a w drugiej odczytanie i ustawienie jego współrzędnych. Napiszmy więc pierwszą klasę, nazwijmy ją Punkt i zapiszmy w pliku o nazwie Punkt.java

public class Punkt{
 	int wspX;
 	int wspY;
 }

Jak widać ma ona banalną budowę i przechowuje wyłącznie dwie wartości opisujące położenie punktu na powierzchni. Utwórzmy teraz drugą klasę, w której wykorzystamy klasę punkt do utworzenia obiektu. Nazwijmy ją UstawPunkt i zapiszmy pod nazwą UstawPunkt.java - musi znajdować się w tym samym folderze co plik Punkt.java

public class UstawPunkt{
 	public static void main(String args[]){
 		Punkt punkt = new Punkt();
 		punkt.wspX = 10;
 		punkt.wspY = 20;
 		System.out.println("Współrzędne punktu to ("+punkt.wspX+", "+punkt.wspY+")");
 	}
 }

Jak widać utworzyliśmy tutaj instancję klasy Punkt, czyli inaczej mówiąc obiekt Punkt o nazwie punkt . Wykorzystaliśmy do tego operator new (nie zapomnij o nawiasach () po nazwie klasy). Następnie możemy dowolnie modyfikować pola klasy Punkt, a jak wiemy przechowuje ona dwie wartości całkowitoliczbowe. Możemy je także po zainicjowaniu bez problemu wyświetlić. Do działania na polach i metodach obiektu używamy operatora .(kropka). Zapis:

punkt.wspX = 10;

oznacza, że do współrzędnej X obiektu zapisujemy wartość 10. Analogicznie robimy ze współrzędną Y.

Aby zobaczyć działanie programu skompiluj klasę UstawPunkt poleceniem javac i uruchom przy pomocy komendy java. Jak widzisz klasa Punkt jest kompilowana automatycznie i nie musimy tego robić oddzielnie. Będzie się tak działo z każdą klasą, z której obiektów korzystamy w naszym programie.

Rozszerzmy teraz klasę punkt o cztery metody:

-dwie ustawiające współrzędne punktów

-dwie pozwalające na dostęp do nich

Kurs Java

Nowa klasa punkt wygląda zatem następująco:

public class Punkt {
 	int wspX;
 	int wspY;
 
 	void ustawX(int x){
 		wspX = x;
 	}
 	void ustawY(int y){
 		wspY = y;
 	}
 
 	int dajX(){
 		return wspX;
 	}
 	int dajY(){
 		return wspY;
 	}
 }

Jak widać dwie pierwsze metody posiadają parametr całkowitoliczbowy. W wyniku wywołania jednej z nich możemy przypisać współrzędną do odpowiedniego pola.

Z kolei dwie kolejne metody zwracają odpowiednio współrzędną X oraz współrzędną Y. Zobaczmy ich wykorzystanie w praktyce, modyfikując klasę UstawPunkt:

public class UstawPunkt{
 	public static void main(String args[]){
 		Punkt punkt = new Punkt();
 		punkt.ustawX(10);
 		punkt.ustawY(20);
 
 		System.out.println("Współrzędne to: ("+ punkt.dajX() + ", "+ punkt.dajY() +")");
 	}
 }

Ma ona dokładnie takie samo działanie, lecz wykorzystaliśmy nasze metody. Najpierw tak samo utworzyliśmy instancję klasy Punkt. Następnie przy pomocy operatora . wywołujemy dwie metody ustawiające odpowiednio współrzędne. Wyświetlamy je pobierając wartości z metod, które zwracają współrzędne w formie liczby całkowitoliczbowej.

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.

Poniżej znajdziesz archiwalne wpisy z czasów, gdy strona była jeszcze hobbystycznym blogiem.

Mark

znalazłem błąd: w klasie Punkt stworzyłeś metody pobierzX i pobierzY, natomiast potem w klasie UstawPunkt w metodzie głównej main wywołujesz już je jako ustawX i ustawY - chyba raczej nie podziała, więc popraw nazewnictwo

Damian

wszystko robię tak jak w instrukcji i podczas gdy kompiluje UstawPunkt.java wyskakuje mi coś takiego: java: file not found: ustawpunkt.java Usage: java use -help for a list of possible options Dlaczego?

Slawek

najprawdopodobniej źle wpisujesz nazwę pliku - zwróć uwagę, czy plik nazywa się identycznie jak nazwa klasy z uwzględnieniem wielkości liter.

Damian

nazwy sie zgadzaja, nawet jesli skopiuje to co jest w instrukcji to i tak wyskaktje błąd. Wcześniej nie miałem takich problemów tylko teraz gdy zacząłem programowanie obiektowe nie wiem...

Damian

juz wiem dlaczego tak sie działo, zapisałem plik w formacie .txt zamiast w .java

Mereel

"Następnie >>przy<< możemy dowolnie modyfikować pola klasy Punkt, a jak wiemy przechowuje ona dwie wartości całkowitoliczbowe." czy potrzebujemy "przy"??

Greg

Ahoj, mam pytanie - czy ktoś się orientuję w NetBeans? Chciałem się przerzucić na niego i w tych akurat zadaniach (progr.obiektowe) mam problem z klasami/paczkami. Mam wszystkie pliki.java w jednym katalogu, ale wyskakuje: "że nie znajude paczki pracownik" w pliku Firma.java podczas tworzenia obiektu z klasy Pracownik. ??? Wiem ze to pewnie nie problem ale nawigacja na pierwszy rzut oka w netbeans nie jest za latwa.

Slawek

skoro nawigacja nie jest dla Ciebie za łatwa, to po co przesiadać się na coś, z czego mało kto korzysta :) Wrzuć gdzieś swój projekt, albo podaj oryginalny błąd z konsoli.

Greg

nie wiedzialem ze z netbeansa malo kto korzysta - to moje pierwsze doswiadczenia z programowaniem w java i gdzies przeczytalem ze netbeans jest super...polecasz cos innego? w kazdym razie tak wyglada kod: package programowanieobiektowe; /** * * @author Mysth */ public class Firma { Pracownik pracownik = new Pracownik(); //tutaj blad ktory mowi: package pracownik does not exist pracownik.imie = "Jacek"; }

Greg

a tak wyglada dobry kod do Pracownik.java public class Pracownik { String imie; String nazwisko; int wiek; void ustal_i(String I){ imie=I; } void ustal_n(String N){ nazwisko = N; } void ustal_w(int W){ wiek = W; } String daj_i(){ return imie; } String daj_n(){ return nazwisko; } int daj_w(){

Slawek

Polecam eclipse - naprawdę częściej się go wykorzystuje, zarówno jeżeli chodzi o "domowych programistów" jak i korporacje. Co do kodu to w klasie Pracownik nie widzę nagłówka z pakietem - powinny być albo w tym samym, albo w klasie firma powinieneś zaimportować pakiet z klasą Pracownik.

Greg

podziękowawszy:) Eclipse był moim pierwszym wyborem tylko gdzies po drodze nawinal mi sie ten NetBeans. A co sądzisz o JCreator? Odnośnie kodu - stworzyłem je pod jednym pakietem, poszło.

Arkadiusz

JCreator jest bardzo fajny, lekki i prosty w obsłudze, wersja pro posiada dodatkowo podpowiedzi podczas pisania. Używałem go długo, ale teraz staram się nauczyć obsługi Eclipse.

Karol

Witam, czy mógłby mi ktoś wytłumaczyć jaka jest różnica pomiędzy "String[] args" ,a "String args[]"?

Slawek

nie ma różnicy

Janosch

A ja się głowiłem czemu raz tak, a raz tak, teraz wszystko jasne :)

Asia

Witam, mam taki problem...otóż pracuje w NetBeans ponieważ na studiach prowadzący wymaga używania właśnie tego programu...Dopiero zaczynam przygodę z javą, .ale przy obiektowym programowaniu już na początku pojawiły sie problemy. Zrobiłam tak jak pisałeś, uwtorzyłam klasę Punkt, utworzyłam zmienne wspX i wspY...ale przy utorzeniu drugiej klasy tj. Ustaw Punkt, NetBeans podkreśla mi nazwy tych zmiennych tj. wspX i wspY, a są one identyczne jak w klasie Punkt. I nie rozumiem o co chodzi? Gdzie jest błąd?:( Z góry dziękuje za odpowiedź.

Asia

Za szybko pospieszyłam się z pytaniem...już wiem w czym błąd...banalny błąd zrobiłam otóż niepotrzebnie wpisałam metodę main do pierwszej klasy Punkt...Ale to przestroga dla innych, aby nie byli tak nieuważni jak ja;) P.S. Bardzo chwalę sobie ten kurs, jest naprawdę przydatny! Ciesze się, że ktoś postanowił podzielić się swoją wiedzą i potrafi ją przekazać innym...to dobrze świadczy o takim człowieku:) ;)

blezus

mnie tylko zastanawia, dlaczego jak nie zdefiniujemy żadnej wartości dla wspX, wspY w klasie Punkt to wtedy wynik dajX() i dajY() będzie 0??

Slawek

Do pól typów prostych zostają przypisane domyślne wartości, a do typów obiektowych wartość null - dobrze, że zapytałeś, dopiszę to w lekcji o typach :)

Michał

Pewne rzecz jest dla mnie niejasna. Skoro kompilator wie, że jak w kodzie znajdzie gdzieś: Punkt p = new Punkt(); ...to ma dodatkowo skompilować sobie plik Punkt.java to dlaczego musimy importować np. klasę Scanner: [import java.utils.Scanner]? Nasuwa mi się tylko jeden wniosek: poprzez [import] odnosimy się do standardowego katalogu z bibliotekami. Jego (tj. [import ...]) brak oznacza, iż kompilator ma szukać plików w aktualnym katalogu?

Slawek

importy pomagają kompilatorowi znaleźć odpowiednie klasy. Możesz mieć na przykład kilka różnych klas Point w kilku bibliotekach - kompilator sam nie zgadnie o którą Ci chodzi.

gandy

Nie do końca zrozumiałem Sławek twoją odpowiedź na pytanie Michała(#20). Pozwolę sobie powtórzyć jego pytanie lekko je rozwijając, gdyż czytając twój wykład te same wątpliwości mi się nasunęły czyli czy np import java .utils.Scanner definiuje położenie pliku zawierającego klasę Scanner? I dalej czy jest możliwość przeniesienia np plików definiujących klasę Scanner ( pomijając czy ma to głębszy sens czy nie) do naszego katalogu z plikami, które tworzymy i w takim przypadku gdybyśmy w utworzonej przez siebie klasie potrzebowali klasy Scanner to nie musielibyśmy jej już importować bo byłaby w tym samym katalogu co nasz plik ćwiczeniowy?

Kubax

Witam, Te 2 klasy to sztuka dla sztuki troche chyba? Można by to dac w klasie punkt a ustawienie wspołrzednych jako metode :>

krzysiek

"Następnie możemy dowolnie modyfikować pola klasy Punkt"??? Chyba powinno być "Następnie możemy dowolnie modyfikować pola (utworzonego) obiektu klasy Punkt", pola te nie są przeciesz polami statycznymi.

sasiad252

Mam problem, z ktorym nawet moj docent sobie nie radzi.Ucze sie od 2 miesiecy programowania w szkole.Napisalem 130-linijkowa aplikacje/gre tzw.MasterMind.W eclipse kompiluje i odpala sie poprawnie, jednak jak pruboje odpalic ten sam plik class w cmd to wyskakuje mi ponizszy blad: C:\JAVA\Samples\Java\bin>cd .. C:\JAVA\Samples\Java>java bin/MasterMind Exception in thread „main” java.lang.NoClassDefFoundError: bin/MasterMind (wrong name: MasterMind) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(Unknown Source) at java.security.SecureClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.defineClass(Unknown Source) at java.net.URLClassLoader.access$100(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source) Dziwne w ty<m jest ze w eclipse uruchamia sie poprawnie a w cmd nie.Mam tylko 1 wersje javy.Nie jest to literowka czy cos takiego.Moj docent doradzil mi napisac cd .. + powrot do folderu(jak wyzej) bo podobno u niego to pomoglo.U mnie nie. Czy ktos zna rozwiazanie tego problemu? Jesli by ktos zechcial mi pomoc, a potrzebuje dodatkowych informacji, piszcie prosze na: sasiad252@gmail.com z gory dziekuje zas pomoc. sasiad252®

Szymon

nmam problem z wysyleniem komantarzy gdy wklejam linijke kodu. dlaczego?

Szymon

po skompilowaniu treningowego powyzszego programy wyskakuje mi blad ze opereto + nie jest zdefiniowany dla argumetu typu String, void jak sobie z tym poradzic?

Szymon

juz po problemie :D

Sławek Ludwiczak

złagodziłem filtr antyspamowy, następnym razem powinno być już ok :)

Maciej

Chciałem napisać program, który pozwala na stworzenie dowolnej liczby pracowników i wczytaniu ich danych: import java.util.Scanner; public class Firma{ public static void main(String[] args){ Scanner IN = new Scanner(System.in); System.out.println("Podaj liczbe pracownikow"); int n = IN.nextInt(); Pracownik worker[] = new Pracownik[n]; int a; for(int i=0; i<worker.length; i++){ a=i+1; System.out.println("Podaj Imie pracownika nr " + a); worker[i].imie = IN.nextLine(); System.out.println("Podaj Nazwisko pracownika nr " + a); worker[i].nazwisko = IN.nextLine(); System.out.println("Podaj Wiek pracownika nr " + a); worker[i].wiek = IN.nextInt(); } for(int i=0; i<worker.length; i++){ System.out.println(worker[i].imie + " " + worker[i].nazwisko + ", " + worker[i].wiek); } }} Kompiluje i uruchamia się normalnie, jednak po podaniu liczb n, wyskakuje błąd: Exception in thread "main" java.lang.nullPointerException at Firma.main...

Sławek Ludwiczak

utworzyłeś tablicę referencji Pracowników, ale nie utworzyłeś obiektów. Musisz wypełnić tablicę: worker[i] = new Pracownik(); itp. Protip - błąd wyrzucany w konsoli pokazuje Ci linię kodu, która spowodowała błąd, dzięki temu można dosyć łatwo dojść do problemu NullPointera na ogół.

Mukesh

I was seuisroly at DefCon 5 until I saw this post.

mwarw

"Punkt punkt = new Punkt();" - punktocepcja

adrian

Może mi ktoś powiedzieć czy da radę umieścić dane np. współrzędnych z kodu pierwszego programu, 10 i 20 w pliku Punkt.java? Żeby w plik Ustaw Punkt.java pobierał dane z zewnętrznego pliku? Bo coś mi nie wychodzi. Nie wiem, użyć do tego metody, czy coś innego? Jeżeli wie ktoś jak to zrobić to niech da cynk.

Oskar

ja to widzę tak. klasa Punkt w Punkt.java jest tylko takim szablonem, który później wykorzystujemy do tworzenia obiektów, które otrzymują "właściwości" jak tym szablonie. czyli dane nie będą zapisane w klasie Punkt tylko w obiekcie o właściwościach klasy Punkt. jak źle to widzę to proszę o poprawę :P jak źle zrozumiałem Twoje pytanie to sorka..

Tomek

Witam Przy kompilacji przykładowego programu wyskakuje mi taki błąd. O co chodzi i jak temu zaradzić? The public type Punkt must be defined in its own file

lolo

Wszystko masz w jednym pliku? A przy okazji jest forum gdzie mógłbyś wkleić cały kod swojego programu i ładnie by go sformatowało.

Sławek Ludwiczak

Zastosowałbym się dokładnie do komunikatu błędu - prawdopodobnie cały kod wrzuciłeś w jeden plik, a powinieneś kod klasy "Punkt" umieścić w osobnym pliku Punkt.java

ska

Myślę, że pierwszy program obiektowy byłby łatwiejszy do zrozumienia, gdybyśmy w klasie Punkt zadeklarowali już jakieś wartości a klasą UstawPunkt je wyświetlili: Punkt.java public class Punkt{ int wspX = 11; int wspY = 22; } UstawPunkt.java public class UstawPunkty{ public static void main(String args[]){ Punkt punkt = new Punkt(); //punkt.wspX = 10; //punkt.wspY = 20; System.out.println("Wspolrzedne punktu to ("+punkt.wspX+", "+punkt.wspY+")"); } }

Walterowicz

(...) <q>Rozszerzmy teraz klasę punkt o cztery metody:</q> (...) Autor chyba na myśli miał klasę "Punkt"? Bo "punkt" w tym wypadku jak rozumiem to objekt.

Mateusz

Czy może ktoś mi pomóc i wyjaśnić co konkretnie robi linijka: Punkt punkt = new Punkt(); O ile rozumiem podobny zapis przy tablicach tak, tego tutaj nie bardzo (za dużo tych punktów :D) Z góry dzięki za pomoc.

Janosch

Punkt punkt = new Punkt(); Może te porównania będą jaśniejsze: 1. Receptura piernik = new Receptura(); Na bazie receptury (Receptura) upiecz piernik (piernik) = nowe ciasto (new) zgodnie z recepturą Receptura() 2. Projekt audi = new Projekt(); Na bazie projektu (Projekt) wyprodukuj audi (audi) = nowy egzemplarz (new) zgodnie z projektem Projekt()

Tomek

Hej, krótkie 2 pytania: 1. "+punkt.wspX+" - czemu mamy tutaj te plusy i do tego jeszcze cudzysłów, bo tego wczesniej nie bylo (jak się nie mylę). Tak po prostu w programowaniu obiektowym wywołujemy metodę print na obiekcie, który zmienne ma zadeklarowane w innej klasie?? 2. nie rozumiem za bardzo tych metod z Ustaw X i daj X (żeby nie kopiować całego kodu). Możecie to przetłumaczyć jak chłopu na miedzy... void ustawX(int x){ wspX = x; } int dajY(){ return wspY; }

Lolo

ad.1. te + służą do łączenia np. zmiennych z statycznym tekstem. ad2. metoda ustawX(int x) Służy jak nazwa wskazuje do ustawiania punktu X a dajY służy do powiebania wartości punktu Y

Tomek

dzieki za odp, z punktem 2 nie do końca potrafię chyba przekazać, o co mi chodzi... :( tutaj poniżej masz metodę ustawX z parametrem intX. Jak należy czytać i rozumieć tą metodę w związku z parametrem x? Co oznacza parametr generalnie w metodach i jak to należy rozumieć? Bo jak mam metodę z pustym nawiasem jest spoko, a jak z parametrem to mi ciężko to sobie uzmysłowić jakoś.... :) void ustawX(int x){ wspX = x; }

Janosch

Tomek, spróbuj to tak zrozumieć, tak na chłopski rozum, mam nadzieję, że znalazłem trafne porównanie. Załóżmy, że masz pewną kwotę pieniędzy w ręce i chcesz je włożyć do pustego portfela. Czynność, czyli samo włożenie pieniędzy do portfela to dla nas metoda "wlozDoPortfela" Ilość pieniędzy, które masz w ręce to dla nas argument dla powyższej metody i nazwiemy go "kwota_w_rece", niech będzie to zmienna double, bo załóżmy, że masz też jakieś grosze. Kwotę, która będzie w portfelu po włożeniu pieniędzy nazwiemy kwota_w_portfelu void wlozDoPortfela(double kwota_w_rece) { kwota_w_portfelu=kwota_w_rece} Teraz wyobraź sobie samą czynność, kwotę którą masz w ręce (double kwota_w_rece) wkładasz (metoda wlozDoPortfela) i teraz ta kwota znajduje się w portfelu, czyli z rąk do portfela: kwota_w_portfelu=kwota_w_rece; Czy teraz trochę bardziej jest to dla Ciebie zrozumiałe? ;)

Janosch

I przykład: Wkładamy do portfela 50,45 zł. void wlozDoPortfela(double 50.45){ kwota_w_portfelu=50.45;}

Lolo

jak masz metodę: void ustawX(int x){ wspX = x; } To czytasz to w ten sposób metoda typu void(czyli nic nie zwracająca) o nazwie ustawX przyjmująca argumenty typu int, Metoda ta przypisuje zmiennej wspX(będącej typu int i należącej w tym przypadku do klasy Punkt) wartość przekazaną w wywołaniu funkcji ustawX(). Chodzi o to, że czasem do działania jakiejś funkcji potrzebujemy przekazać jej jakieś dane na których ma operować. Swoją drogą jak dotarłeś tak daleko w tym kursie jak nawet nie rozumiesz takich podstaw jak funkcje?

Tomek

dzięki wszystkim, podoba mi się to forum :) nie jest tak źle ze mną, ale uwużam że lepiej dopytać 3 razy robiąc z siebie nieuka i pojąć temat dobrze niż tak nie do końca... ;)