Kurs Java Podstawy - rozszerzony

Klasy, metody i obiekty

W pierwszej części kursu powiedzieliśmy tylko pobieżnie czym są klasy i metody w języku Java. Tym razem przyjrzymy im się nieco bliżej. Dowiemy się jak mogą wyglądać, po co ich używać oraz jak przekazywać im parametry.

Pierwszy program jaki napisaliśmy wyglądał następująco:

public class Hello{
  public static void main(String[] args){
    System.out.print("Hello World");
  }
}

Jest to ogólnie mówiąc klasa Hello z metodą main. Omówmy jednak ten przykład słowo po słowie.

public class Hello

Jest to publiczna klasa o nazwie Hello (zgodnie z nazewnictwem podanym w rozdziale pierwszym). Każda klasa musi się rozpoczynać od:

class NazwaKlasy{ ... }

Słowo public to modyfikator dostępu, omówimy je w oddzielnej lekcji.

W następnej linii widzimy metodę main:

public static void main(String[] args){ ... }

Jak już kiedyś wspominaliśmy jest to metoda rozruchowa programu. To od niej zaczyna się wykonywanie wszystkich instrukcji.

Wiemy co oznacza słowo public, jednak dalej jest "static" - oznacza ono, że metoda jest statyczna - i właśnie taka musi być także metoda main. Z wnętrza metody statycznej Nie możemy odwoływać się do pól i metod nie zadeklarowanych jako statyczne. Dodatkowo metody i zmienne zadeklarowane jako static związane są z konkretną klasą, a nie jej instancją - obiektem.

Kolejne słówko to void - jest to słówko określające typ zwracany przez metodę, w przypadku innych metod niż main() mogłoby tutaj równie dobrze stać int, lub double, albo jakiś typ obiektowy. Do zwrócenia wyniku, bądź obiektu służy słowo kluczowe return.

Kolejny krok to tablica Stringów: String[] args - jest to parametr metody. Mogą one przyjmować zarówno liczby jak i tablice, a także inne obiekty. Możemy się do nich bez problemu odwoływać we wnętrzu metody, a także je modyfikować. Trzeba jednak pamiętać, że operujemy na referencji do tego obiektu, więc jego modyfikacja może wpłynąć na zmianę w innej części programu - w tym wypadku warto posłużyć się defensywnym kopiowaniem obiektów, które omówimy w dziale "efektywne programowanie".

Metody

Oczywiście metoda main() nie musi być jedyną metodą danej klasy. Mogą być ich równie dobrze setki. Zbierając wszystkie informacje w całość możemy przedstawić przykład różnych metod w klasie:

public class Tablice{
	public void metoda1(){
		System.out.println("Ta metoda nic nie zwraca");
	}

	public int trzy(){
		return 3; // ta metoda zwraca liczbę 3
	}

	public int suma(int a, int b){
		return a+b;  //ta metoda zwraca sumę dwóch parametrów
	}
}

natomiast schematycznie wygląda to tak:

specyfikator_dostepu class NazwaKlasy{

specyfikator_dostepu typ_zwracany nazwaMetody(parametry_po_przecinku){
  jeśli typ zwracany inny niż void to trzeba użyć słówka return i zwrócić wynik odpowiadający właśnie temu typowi
}
}

Klasy

Klasy mogą zawierać zarówno metody jak i zmienne. Równie dobrze mogą mieć tylko jedne, lub drugie z tych elementów, a nawet nie posiadać ich wcale (choć po co komu taka klasa). Jak wyżej wspomnieliśmy każdą klasę rozpoczyna słowo kluczowe class, a te z kolei poprzedza specyfikator dostępu. Występuje wiele rodzajów klas i mają one różne przeznaczenie. Z tego powodu poświęcimy im także oddzielną lekcję kursu.

Obiekt

Jest to naturalna reprezentacja klasy. Przechowuje informacje o zmiennych i pozwala się do nich odwoływać, a także za jego pomocą możemy wywoływać metody. Przekonaliśmy się o tym już wielokrotnie, ponieważ użycie metody print() wyświetlającej tekst na ekranie to nic innego jak wywołanie tejże metody na rzecz obiektu out. Utworzenie nowego obiektu - czyli instancji klasy dokonujemy za pomocą słowa kluczowego new - podobnie jak miało to miejsce w przypadku tablic.

specyfikator_dostepu typ_Obiektu nazwaObiektu = new typ_Obiektu();

Typem obiektu jest oczywiście klasa, którą on reprezentuje.

<- Poprzednia LekcjaNastępna Lekcja ->

Komentarze

Grzegorz

specyfikator_dostepu typ_Obiektu nazwaObiektu = new typ_Obiektu();

Chyba nie zawsze trzeba ten specyfikator dostępu dawać? Domyślnie jest public?

Slawek

Jeżeli pominiesz specyfikator dostępu to domyślnie jest pakietowy.

przemi

Witam,
mam takie pytanie napisałes "użycie metody print() wyświetlającej tekst na ekranie to nic innego jak wywołanie tejże metody na rzecz obiektu out. " czyli wywołujac
System.out.printlm(); wywołujemy
klase System .obiekt out.metode println.
Tak mi sie wydanie tylko chce się upewnic.

pozdrawiam

Slawek

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/System.html
obiekt out to standardowy strumień wyjścia typu PrintStream, ta z kolei klasa zawiera metody print(), println() ...
Odwołujemy się do tej metody w ten sposób, ponieważ obiekt out jest statyczny w klasie System (wywoływany na rzecz klasy, a nie jej konkretnej instancji), dodatkowo nie da się utworzyć obiektu tej klasy np
System s = new System();
s.out.print("test");
Otrzymamy błąd o tym, że konstruktor nie jest widoczny.

Rain345

Nie do końca rozumiem działanie słówka return.
Mógłby ktoś mi to lepiej wytłumaczyć, albo dać link do strony gdzie to będzie.

Pozdrawiam Rain345

tojazenn

gdy metoda ma takie parametry
public VOID nazwa()
nie mozesz uzyc slowa return bo Void oznacza ze metoda nic nie zwraca oprocz ewentualnych komunikatow (System.out.println("komunikat");)

gdy metoda jest zwracalna - zamiast void jest double lub dowolnie inny parametr na przyklad
public double nazwaMetody()
wtedy musisz zwrocic double - uzyc slowa return
//przyklad srodka takiej metody
{
double liczba = 12.34;
return liczba;
}

Sławek Ludwiczak

Tutaj należy się ważne uzupełnienie, że Void (pisane z wielkiej litery) i void (z małej litery) mają akurat zupełnie inne znaczenie.
Void to typ obiektowy:
http://docs.oracle.com/javase/6/docs/api/java/lang/Void.html
posiadający wartość Void.TYPE - zadeklarowanie metody jako zwracającej Void, MUSI zwracać Void.TYPE, lub null.
Może to być użyteczne przy refleksji, lub aplikacji wielowątkowej (choć bardzo rzadko spotykane).

Ictis

Operator return pozwala na zakończenie wykonywania metody, zwrócenie wyniku metody i powrót do miejsca wywołania metody.
Operator return zwraca obiekt, przy czym może to być jakieś wyrażenie i zwrócony będzie wynik tego wyrażenia. Oczywiście zwracany element musi być tego samego typu co w deklaracji metody.

http://download.oracle.com/javase/tutorial/java/javaOO/returnvalue.html

Emil

Skoro

specyfikator_dostepu typ_Obiektu nazwaObiektu = new typ_Obiektu();

tworzy instancję klasy, to gdzie w tej linijce jest nazwa klasy, której instancję chcemy utworzyć?

dude

ostatnie zdanie w bieżącej lekcji.

Luksus

public class Tablice{
public void metoda1(){
System.out.println("Ta metoda nic nie zwraca");
}

public int trzy(){
return 3; // ta metoda zwraca liczbę 3
}

public int suma(int a, int b){
return a+b; //ta metoda zwraca sumę dwóch parametrów
}
}

Witam, po wklepaniu powyższego kodu kompilacja przebiega prawidłowo, natomiast kiedy próbuję uruchomić program wyskakuje mi Error związany z brakiem metody main. I prosi o zdefiniowanie "public static void main(String[] args)". Czy ten Program powinien zadziałać w takiej postaci jak w artykule?

Witek

Witam
poprawiłem twój kod, dodałem metodę main() oraz nowy obiekt, można to zrobić w oddzielnej klasie testowej np. jak poniżej, ale można zrobić to w jednej klasie tak jak w poprawionym kodzie.

Poprawiony kod:

public class Tablice{

public void metoda1(){
System.out.println("Ta metoda nic nie zwraca");
}

public int trzy(){
return 3; // ta metoda zwraca liczbę 3
}

public int suma(int a, int b){
return a+b; //ta metoda zwraca sumę dwóch parametrów
}

public static void main(String[] args){

Tablice tab1 = new Tablice();

tab1.metoda1();

System.out.println("To jest z metody - trzy, która zwraca: " + tab1.trzy());

System.out.println("Wynik z metody suma: " + tab1.suma(3, 6));
}
}



Kod z klasy Testowej


public class TestTablica {

public static void main(String[] args){

Tablice tab1 = new Tablice();

tab1.metoda1();

System.out.println("To jest z metody - trzy, która zwraca: " + tab1.trzy());

System.out.println("Wynik z metody suma: " + tab1.suma(3, 6));

}
}

Marek

Czy ktoś mógłby mi wytłumaczyć o co chodzi z słówkiem static, który pojawia się przy metodzie main ?

Slawek

Metody i pola statyczne to takie, które wywołujemy na rzecz klasy, a nie instancji klasy. Żeby się do nich odwołać wystarczy wpisać
NazwaKlasy.NazwaPola, lub
NazwaKlasa.NazwaMetody(argumenty)

Nie musimy tworzyć instancji obiektu przez new NazwaKlasy().nazwaPolaLubMetody.
A konkretnie metoda main jest statyczna dlatego, że maszyna wirtualna nie wiedziałaby, który konstruktor wywołać - zakładając, że byłoby ich kilka.

Marek

czyli metoda main jest konstruktorem?

Marek

a jaka jest różnica między wywołaniem na rzecz klasy a na rzecz obiektu klasy ?

Marek

co to znaczy, że maszyna wirtualna nie wiedziałaby który konstruktor wywołać ?

Slawek

Nie, metoda main nie jest konstruktorem. Przykład:

public class Klasa{

public Klasa(int x){ }
public Klasa(int x, int y){ }
public Klasa(String s){ }

public void main(String[] args) { }
}


Aby uruchomić w takim przypadku program, maszyna wirtualna musiałaby utworzyć sobie obiekt Klasa, czyli new Klasa(), no ale jak widać są w niej 3 konstruktory, przyjmujące różne parametry. Skąd więc Maszyna wirtualna miałaby wiedzieć co tam przekazać i w ogóle który konstruktor wywołać?
Gdy mamy public STATIC void main(String[] args){ } wywołanie programu wygląda w uproszczeniu tak: Klasa.main(ewentualne_argumenty), gdzie"ewentualne_argumenty" to parametry, które możemy przekazać wywołując program z konsoli korzystając z polecenia:
java NazwaKlasy ewentualne_argumenty
Marek

Z wnętrza metody statycznej Nie możemy odwoływać się do pól i metod nie zadeklarowanych jako statyczne.

To znaczy, że z wnętrza metody main nie możemy się odwoływać do pól i metod statycznych ?

Marek

Może jakiś przykład ?

Dzieki

rydlik

"Z wnętrza metody statycznej Nie możemy odwoływać się do pól i metod nie zadeklarowanych jako statyczne." naprawdę logiczne zdanie, tak jakby nie można było prościej.

"Z poważaniem"

Jędrzej

„Z wnętrza metody statycznej Nie możemy odwoływać się do pól i metod nie zadeklarowanych jako statyczne.”
Ha!!! I tu nam łamiesz Sławku!!! Można z metody statycznej odwołać się do metody/funkcji NIE statycznej.
Wystarczy stworzyć instancję klasy i odwołać się w niej do metody/funkcji NIE statycznej. Przykład:
public class Hello{
public static void main(String[] args){
Hello h = new Hello();
System.out.print(h.omg);
}
static String omg(){return "OMG!!!";}
}





Działa!!!

Gościu

Przecież w statycznej metodzie main odwołujesz się do static String omg(), czyli też obiekt statyczny... Czegoś nie rozumiem, czy się czepiasz? :-)

Jędrzej

public class Hello{
public static void main(String[] args){
Hello h = new Hello();
System.out.print(h.omg);
}
String omg(){return "OMG!!!";}
}

Sorry, ctrl + c i ctrl + v kłamie. Teraz też działa.

papiszon

Dobre, dzięki.

arveit

Mam tak:
metodę wprowadzDane, która uzupełnia tablicę danymi

Chcę, by metoda wypiszDane wypisała dane z tej tablicy i nie mam pojęcia jak mam to zrobić, by po zapisie tablica była dostępna dla innych metod

Lukasz

A co jesli metoda w klasie zapisanej w innym pliku niz "main()" oraz sama "main()" nie beda zadeklarowane jako statyczne, to lepiej czy gorzej? Jakie sa glowne zastosowania dla metod statycznych? Nie rozumiem tego za bardzo. Czy metoda "main()" powinna byc zawsze statyczna?