Laboratorium 1
Wstęp. Różnice pomiędzy C++ a Javą.
A. Wstęp.
Pamiętacie najprostszy kod wypisujący napis na ekran w C++? Tak wygląda to w Javie:
Hello World: C++ | Hello World: Java |
#include <iostream> using namespace std; int main(int argc, char** argv) { cout<<"Hello World!"; return 0; } |
class Hello { public static void main(String[ ] args) { System.out.println("Hello World!"); } } |
Podstawowe pętle i instrukcje warunkowe są identyczne w obu językach:
Kod działający zarówno w C++ jak i w Javie |
int foo=1, bar=3; if (foo == 1) { foo=2; } else { foo=3; } for (int ii = 0; ii < bar; ii++){ bar += 5 % 2; } |
Kompilacja: C++ | Kompilacja: Java |
g++ [lista plików do skompilowania] |
javac [lista plików do skompilowania] |
Wynik kompilacji: C++ | Wynik kompilacji: Java |
program: a.out |
plik .class: Hello.class |
W Javie po poprawnej kompilacji tworzone są pliki .class,
które mogą być uruchomione w dowolnym systemie operacyjnym posiadającym Wirtualną Maszynę Javy (JAVA VM).
Uwaga: Nazwy plików z kodem źródłowym Javy NIE SĄ dowolne:
- muszą mieć rozszerzenie .java.
- w przypadku deklarowania klasy publicznej, nazwa pliku musi być identyczna z nazwą klasy (wielkość liter ma znaczenie)
Przykładowo, klasa:
public class Example {...}
musi być zadeklarowana w pliku Example.java
i w wyniku kompilacji utworzy Example.class
Uruchomienie: C++ | Uruchomienie: Java |
./a.out |
java [nazwa pliku class] |
Uruchomienie z argumentami: C++ | Uruchomienie z argumentami: Java |
./a.out arg1 arg2 |
java [nazwa pliku class] arg1 arg2 |
Tablice
A oto przykład deklaracji tablic w Javie (w porównaniu z C++).
Tablice: C++ | Tablice: Java |
double myList1[10]; double* myList2; //deklaracja myList = new double[10]; //utworzenie tablicy double* myList = new double[10]; //dwa w jednym double total = 0; for (int i = 0; i < 10; i++) { total += myList[i]; } delete [] myList; delete [] myList2; |
double[] myList1 = new double[10]; double[] myList2; //deklaracja myList = new double[10]; //utworzenie tablicy double[] myList = new double[10]; //dwa w jednym double total = 0; for (int i = 0; i < myList.length; i++) { total += myList[i]; } |
Co należy zauważyć:
- W Javie nie występują "tablice statyczne". Tablice zawsze deklarujemy przez new.
- Nie ma delete! W Javie Garbage Collector czyści pamięć za nas.
- Pole length tablicy przechowuje jej długość.
- Odczyt oraz zapis do poszczególnych komórek tablicy jest taki sam w obu językach.
B. Eclipse
Na zajęciach nie będziemy jednak pisać w notatniku, tylko korzystać ze środowiska Eclipse. Eclipse to bardzo popularne zintegrowane środowisko programistyczne (ang. IDE), czyli zespół aplikacji służących do tworzenia, modyfikowania, testowania i konserwacji oprogramowania. Pozwala na instalację dużej ilości różnych wtyczek, dopasowanych do potrzeb programisty. Więcej informacji: tutaj.
Podstawowe informacje które mogą się przydać dzisiaj na zajęciach:
1. Po uruchomieniu zostaniesz zapytany o workspace - katalog, w którym będą zapisywane nowe projekty
2. Tworzenie nowego projektu w Eclipse
Wystarczy wybrać z menu: (File/New/Project... -> Java Project -> wybrać nazwę projektu -> Finish)
3. Dodanie do projektu nowej klasy
File/New/Class -> wybrać nazwę klasy -> Finish)
4. Dodanie do projektu nowej klasy zawierającej metodę main
File/New/Class -> wybrać nazwę klasy i zaznaczyć pole dodające metodę main -> Finish)
Run -> Run Configurations -> wybrać zakładkę arguments -> wpisać argumenty programu
Paczki java (package i import)
W dużych środowiskach problemem może być zderzenie nazw pomiędzy różnymi klasami należącymi do dwóch projektów które trzeba połączyć.
Wyobraźmy sobie taki scenariusz: sprzedawca mebli posiadający napisany w Javie system sprzedażowo-magazynowy chce rozwinąć się w kierunku sprzedaży detalicznej i postanowił stworzyć sklep internetowy i w tym celu zakupił gotowy CMS napisany w Javie oparty o Javę EE. Niestety, jego istniejący system sprzedażowy zawiera klasę o nazwie Table.java która reprezentuje różne stoły jakie opisywana firma sprzedaje. CMS również operuje klasą Table.java, która reprezentuje tabelkę HTML. Bez operowania przestrzeniami nazw (w javie określa się je paczkami) nie da się tych dwóch projektów połączyć, bo kompilator nie wiedziałby do której z klas odnosi się np. wywołanie:
Table table =
new
Table();
Jak umieścić klasę w paczce?
Jeśli chcemy umieścić naszą klasę w paczce o nazwie foo.bar
musimy dodać dyrektywę package foo.bar;
jako pierwszą linię w treści klasy.
Wszystkie klasy należące do tej paczki znajdują się w katalogu foo/bar
- Jeśli mówimy o kodzie źródłowym, to znajdują się one w tym katalogu wewnątrz katalogu ze źródłami projektu.
- Jeśli mówimy o skompilowanym kodzie, to znajdują się one w katalogu
foo/bar
katalogu głównego w pliku.jar
lub katalogu dodanego doclasspath
Import klas z paczki
By odnieść się do klasy Baz
z paczki foo.bar
możemy podać jej pełną (kwalifikowaną) nazwę:
|
|
Operowanie pełnymi nazwami jest niewygodne, ale czasem jest konieczne.
Przykładowo, gdy operujemy kilkoma klasami o tej samej nazwie (w przykładzie klasy Baz
z paczek foo
i bar
).
|
|
By skrócić ilość pisania, możemy użyć dyrektywy import
, która pozwala ominąć nazwę paczki. Proszę pamiętać że dyrektywa import znaczy tak naprawdę: "Drogi kompilatorze, wiedz, że od tej pory, gdy napiszę nazwę klasy Baz
, chodzi mi o klasę Baz
z paczki foo.bar
:
|
|
Związek między klasami w paczce
Klasy w jednej paczce widzą się nawzajem, tj. nie potrzeba ich importować.
Dodatkowo klasy z jednej paczki mają ułatwiony dostęp do swoich atrybutów. Wyobraźmy sobie taką klasę:
package foo.bar; class Foo{ private int priv; int pack; protected int prot; public int pub; private void doNothingPrivate(){}; void doNothingPack(){}; protected void doNothingProt(){}; public void doNothing(){}; }
Klasy z paczki foo.bar
nie mają dostępu tylko do atrybutu priv
i metody doNothingPrivate
.
Zadanie A - Hello i pętla. (1 pkt)
Utworzyć nowy projekt, a następnie utworzyć w nim plik tekstowy (File → New → File) o nazwie Hello.java. Następnie należy napisać w jego wnętrzu program wypisujący na ekranie słowa "Witaj!" a pod spodem liczby od 1 do [pierwszego_argumentu_programu]. Klasa powinna znajdować się w paczce pojava.lab1.zadA. Następnie należy skompilować go i uruchomić.
Wskazówki:
- Najpierw napisz program, który wyświetla liczby od 1 do X, gdzie X = 20.
2. Zmień X na w ten sposób, by X było argumentem przekazywanym z zewnątrz do metody main(String[] args).
-
Należy zauważyć, że argumenty przekazywane są do funkcji main w postaci tablicy obiektów klasy String. Czyli argumenty wywołania programu można znaleźć pisząc args[1], args[2], itp...
-
Zamiana String na int:
String myString = "1234"; int myInt = Integer.parseInt(myString);
-
Program powinien wyświetlać informację o błędzie jeśli użytkownik nie poda argumentu. Najłatwiej sprawdzić, czy długość tablicy args jest równa 0.
Zadanie B - Tablica String. (1.5 pkt)
Używając środowiska Eclipse napisz program, który utworzy tablicę na 4 ciągi znaków (String), wypełni ją słowami (cztery pierwsze parametry wywołania programu) po czym wypisze na ekranie. Klasa powinna znajdować się w paczce pojava.lab1.zadB.
C. Klasy i Dziedziczenie
Każdy pisany w Javie kod znajduje się w obrębie jakiejś klasy. Żeby stworzyć obiekt klasy i wywołać jego metody należy użyć operatora new:
KlasaPrzykladowa kp = new KlasaPrzykladowa();
Pamiętaj: obiekty w Javie zawsze tworzone są przy pomocy operatora new po którym następuje konstruktor (czyli nazwa klasy wraz z ewentualnymi argumentami).
Dziedziczenie jest znanym państwu z C++sa mechanizmem współdzielenia funkcjonalności pomiędzy klasami:
Dziedziczenie: C++ | Dziedziczenie: Java |
class Bazowa { public: Bazowa(); }; class Pochodna : public Bazowa { }; |
class Bazowa { public Bazowa(); }; class Pochodna extends Bazowa { };
|
Co należy zauważyć:
- Słowo kluczowe extends mówi o dziedziczeniu z klasy nadrzędnej
- Nie ma już dwukropków po modyfikatorach dostępu (public / private itp.), każda funkcja składowa klasy i konstruktor posiada własny modyfikator dostępu.
- Domyślnym modyfikatorem nie jest już "private" jak w C++, lecz "package protected", czyli dana funkcja / klasa / pole jest dostępne z każdego miejsca danej paczki.
Zadanie C - Dziedziczenie (2.5 pkt)
Proszę stworzyć klasę Auto, która zawiera:
- pole: float[] przebieg; - to tablica przechowująca informację o ilości przejechanych kilometrów w kolejnych miesiącach, jej rozmiar to 12; Tablica jest inicjalizowana losowymi wartościami w konstruktorze.
- metodę: float srPrzebieg(); - oblicza średni przebieg dla samochodu.
- nie posiada metody main
Proszę stworzyć klasę Taxi, która dziedziczy po klasie Auto i zawiera:
- pole: float[] zarobki; - to tablica przechowująca informację o zarobkach taksówkarza kolejnych miesiącach, jej rozmiar to 12; Tablica jest inicjalizowana losowymi wartościami w konstruktorze.
- metodę: float srZarobki(); - oblicza średnie zarobki dla taksówki.
- posiada metodę main w której proszę stworzyć obiekt klasy Taxi i wyświetlić na ekranie średni przebieg i średnie zarobki.
Wskazówka:
- każdą klasę należy zadeklarować w oddzielnym pliku (o nazwie danej klasy)
- konstruktory w Javie deklaruje się tak samo jak w C++,
- dziedziczenie również deklaruje się tak samo jak w C++, należy jedynie pamiętać o słowie extends zamiast dwukropka
- funkcję losującą liczby zmiennoprzecinkowe z danego zakresu (przy wypełnianiu tablic przebieg, zarobki) należy samodzielnie znaleźć w internecie
Poniżej kod dla dwóch przykładowych klas: bazowej i pochodnej.
Klasa bazowa
package pl.wyklad1.klasapokazowa; public class KlasaPrzykladowa { // deklaracje konstruktorow KlasaPrzykladowa() { x = 0; tekst = "domyslny"; //to jest konstruktor domyslny } // deklaracje metod void setX(int aX) { x = aX; } int getX() { return x; } void wypisz() { System.out.println(x + " " + tekst); } // deklaracje pol int x; String tekst; |
Klasa pochodna
public class KlasaPochodna extends KlasaPrzykladowa { KlasaPochodna(){ x = 1; tekst = "domyslny pochodnej"; //konstruktor domyslny } public void wypisz(){ System.out.println(x + " " + y + " " + tekst); } int y = 10; }Funkcja główna main public static void main(String[] args) { KlasaPochodna kp = new KlasaPochodna(); kp.wypisz(); } |