ĆWICZENIE 2
1. Słowo kluczowe this
Możliwość niekwalifikowanego odwoływania się w ciele funkcji składowej do komponentów jej klasy wynika z tego, że:
- w ciele każdej niestatycznej funkcji składowej klasy jest dostępna zmienna this , która jest odwołaniem do obiektu klasy, na rzecz którego aktywowano daną funkcję składową,
- każde niekwalifikowane odwołanie do niestatycznego komponentu klasy np. nazwa jest traktowane jako skrócony zapis wyrażenia this.nazwa
//Program 2.1
public class Produkt
{ String nazwa; //deklaracja pola obiektu
int cena; //deklaracja pola obiektu
public void ustaw (String a, int b) //metoda przypisująca wartości polom obiektu
{ this.nazwa=a;
cena=b; //this można pominąć
}
public void wypisz() //metoda wypisująca wartości pól obiektu
{
System.out.println( "Produkt o nazwie "+ nazwa + " kosztuje " +this.cena);
}
public static void main(String args[])
{ Produkt lampa, stolik; //zadeklarowanie referencji do obiektów
lampa=new Produkt(); //utworzenie obiektu
stolik=new Produkt();
System.out.println (" " );
lampa.ustaw("Solar",550); //przypisanie wartości polom obiektu
System.out.println ("Oto nazwa lampy: " + lampa.nazwa );
stolik.ustaw("Kler",37);
System.out.println ("Utworzono 2 obiekty klasy Produkt:" );
lampa.wypisz(); //wypisanie zawartości pól obiektu
stolik.wypisz();
Produkt zegar = new Produkt();
System.out.println ("Utworzono trzeci obiekt klasy Produkt - jest pusty:" );
zegar.wypisz();
zegar.ustaw("kwarc",3);
System.out.println ("Utworzono nowy obiekt klasy Produkt :" );
zegar.wypisz();
}
}// koniec klasy Produkt
Zadania do samodzielnego wykonania:
Program 2.1 umożliwia wypisanie informacji o produktach. Należy go uruchomić i przeanalizować zasadę działania tego programu, a następnie:
1. a) Zmodyfikować klasę Produkt zwiększając liczbę informacji o produktach o kolor: dodać pole, zmodyfikować metody ustaw() i wypisz().
b) Utworzyć dwa nowe produkty, porównać ich ceny i wypisać nazwę droższego.
2. Czytanie danych z klawiatury
Operacje we-wy realizuje się w Javie przy użyciu strumieni:
- System.in - strumień wejściowy,
- System.out - strumień wyjściowy,
- System. err - strumień z obsługą błędów.
Czytać z klawiatury można jedynie wiersze tekstu, które można po wczytaniu konwertować (rzutować) na zmienne innych typów.
Java pozwala na rzutowanie każdego typu podstawowego na każdy inny typ podstawowy, oprócz typu bool, który w ogóle nie może być rzutowany.
Dla operacji wejścia musi być oprogramowana obsługa błędów (blok try - catch).
Poniższy program pobiera linię tekstu z klawiatury.
//Program 2.2
import java.io.*; //import pakietu z klasami do obsługi operacji we/wy
public class CzytajTekst{
public static void main(String args[])
{ BufferedReader webuf;
InputStreamReader we;
we = new InputStreamReader(System.in);
webuf = new BufferedReader(we);
/* powyższe 4 wiersze można zastąpić instrukcją:
BufferedReader webuf = new BufferedReader(new InputStreamReader(System.in));
*/
System.out.println("Podaj tekst");
try{
String s = webuf.readLine();
/* Jeśli chcemy wczytać liczbę, należy przekonwertować zmienną typu String na typ liczbowy np.
int a=Integer.parseInt(s);
System.out.println("Oto twoja liczba: " + a ); */
System.out.println("Oto twój tekst:" + s + "!"); //wyświetlenie łańcucha tekstowego
}
catch(IOException e) {System.out.println("blad czytania");
}
}
}
Uwaga 1: Do czytania z klawiatury można używać również klasy StringBuffer, która tworzy bufor dla znaków pobieranych z konsoli:
char c;
try
{
c=(char)System.in.read();
System.out.print( " Oto znak: " + c);
}
catch(IOException e) {}
Proszę uzupełnić program 2.2 poniższymi instrukcjami i uruchomić.
System.out.print("Podaj liczbe rzeczywistą: ");
double a;
StringBuffer str=new StringBuffer();
char ch;
double liczba1;
try
{
while ((ch=(char)System.in.read()) !='\n')
str.append(ch);
liczba1=Double.valueOf(str.toString()).doubleValue();
}
catch(java.io.IOException e)
{
liczba1=0;
}
System.out.println("Oto twoja liczba:" + liczba1 + " ! ");
Zadania do samodzielnego wykonania:
2. Napisać program, który pyta o imię, nazwisko i rok urodzenia osoby i po wczytaniu danych z klawiatury wyświetla na ekranie imię, nazwisko i ile lat ma ta osoba.
Uwaga 2: Instrukcja lb1=Double.valueOf(str.toString()).doubleValue();
wykonuje konwersję obiektu typu StringBuffer na zmienną double. Dokonuje tego metoda valueOf z klasy Double. Ponieważ wymaga ona argumentu typu String należy użyć metody toString() która przekonwertuje StringBuffer na String. Instrukcja doubleValue() - jest wskazaniem opakowania na typ double. Podobnie wykonuje się konwersję z typu String do innych typów opakowanych.
Uwaga 3: Instrukcja try{ ... } catch(java.io.IOException e)
wykonuje obsługę wyjątków instrukcji wejścia - wyjścia. W Javie wszystkie operacje WE-WY muszą mieć obsługę wyjątków.
3. Program uruchamiany z parametrami wejściowymi
Funkcja main zawsze posiada argumenty umieszczone w tablicy typu String.
Aby uruchomić program z parametrami wejściowymi należy skompilować program 2.3. Następnie z menu Build wybrać opcję Set Project Configuration, potem opcję Customize i w polu Arguments wpisać wartości argumentów oddzielone spacjami.
Następnie uruchomić program, który wypisze wartości podanych argumentów.
//Program 2.3
public class Parametry
{
public static void main(String args[])
{
for (int i=0; i < args.length; i++ )
//długość tablicy zawsze jest zawarta w publicznym polu length
{
System.out.println("Parametr nr " + i + ": " + args[i]);
}
}
}
Zadania do samodzielnego wykonania:
3. a) Uruchomić program 2.3 z trzema parametrami wejściowymi imieniem, nazwiskiem i rokiem urodzenia osoby i wypisać na ekranie z ile lat ma dana osoba.
b) Uruchomić program 2.3 z dwoma parametrami wejściowymi - liczbami rzeczywistymi i wypisać na ekranie iloczyn tych liczb.
4. Funkcje przeciążone.
W języku Java w jednej klasie mogą występować funkcje o tej samej nazwie, ale muszą różnić się ilością lub typami argumentów. Typ wartości zwracanej przez funkcję nie ma znaczenia. Takie funkcje nazywamy przeładowanymi lub przeciążonymi (overloading). O tym, która z funkcji będzie wykonana decydują parametry wywołania. Jeśli przy wywołaniu funkcji występuje rozbieżność między parametrami formalnymi a parametrami wywołania, to następują standardowe konwersje typów w celu dopasowania odpowiedniej funkcji.
//Program 2.4
import java.io.*;
class Auto
{
String marka;
String kolor;
int cena;
//definicja przeciążonej metody ustaw:
void ustaw(String a, String b, int c)
{
this.marka = a;
this.kolor = b;
this.cena = c;
}
/*wskaźnik this zawsze wskazuje obiekt, dla którego wywołano funkcję składową klasy - może być pomijany*/
//definicja przeciążonej metody ustaw:
void ustaw(int nowacena)
{
this.marka = "Audi";
this.kolor = "czarny";
this.cena = nowacena;
}
// definicja przeciążonej metody ustaw:
void ustaw()
{
this.marka = "Mercedes";
this.kolor = "biały";
this.cena = 30000;
}
void wypisz()
{
System.out.println (this.marka +" jest " + this.kolor+ " kosztuje " + this.cena);
}
public static void main(String args[])
{
Auto moje;
moje = new Auto();
System.out.println ("Dane mojego auta: )");
moje.wypisz();
moje.ustaw();
System.out.println ("Dane mojego auta: ");
moje.wypisz();
moje.ustaw("Polonez","szary",200000);
System.out.println ("Dane mojego auta po zmianie ");
moje.wypisz();
moje.ustaw(5000);
System.out.println ("Dane mojego auta z nową ceną: ");
moje.wypisz();
Auto autobus=new Auto();
autobus.ustaw();
System.out.println ("Dane autobusu: ");
autobus.wypisz();
/*
System.out.println ("Podaj markę autobusu: ");
//czytanie danych z klawiatury
BufferedReader webuf;
InputStreamReader we;
we = new InputStreamReader(System.in);
webuf = new BufferedReader(we);
try{
autobus.marka = webuf.readLine();
autobus.wypisz();
System.out.println ("Podaj cene autobusu: ");
String s = webuf.readLine();
//Jeśli chcemy wczytać liczbę, należy przekonwertować zmienną typu String na typ liczbowy:
autobus.cena=Integer.parseInt(s);
autobus.wypisz();
}
catch(IOException f){System.out.println("blad czytania");
*/
}
}
Zadanie do samodzielnego wykonania:
4. a) W klasie Auto zdefiniować dodatkowe przeciążone metody ustaw i wypisz i sprawdzić ich działanie.
b) W klasie Auto zdefiniować kilka metod pozwalających na stwierdzenie, czy obiekt jest na parkingu, czy aktualnie jest w drodze (stoi, wiezie pasażerów, rusza, skręca, tankuje paliwo, wyprzedza...). Zastosować je w swoim programie.
5. Konstruktory.
Podczas tworzenia obiektu danej klasy wywoływana jest funkcja składowa zwana konstruktorem, która przypisuje wartości początkowe polom obiektu.
Konstruktor zawsze nosi nazwę swojej klasy i nie może mieć określonego typu zwracanej wartości (nawet void ). Może być funkcją przeciążoną.
Jeśli nazwy argumentów konstruktora są identyczne z nazwami pól klasy, wtedy występuje przesłanianie nazw. Aby odwołać się do pól klasy należy ich nazwy poprzedzić słowem kluczowym this. Jeśli w klasie nie zdefiniowano żadnego konstruktora, to wtedy i tylko wtedy kompilator wygeneruje konstruktor domyślny, bezargumentowy, który zeruje pola obiektu. Konstruktor domyślny jest zadeklarowany jako publiczny wtedy i tylko wtedy, gdy klasa jest publiczna.
Java zawiera rezydentny odśmiecacz - program, który odzyskuje pamięć po obiektach, do których nie ma już referencji.
Jeśli obiekt alokuje specjalną pamięć (np. zajętą przez funkcję z języka C) nie używając operatora new, to można tę pamięć zwolnić używając metody finalize() zdefiniowanej wewnątrz klasy.
W jednym pliku może występować kilka klas, z których każda może zawierać funkcję main służącą do jej testowania. Wykonywana jest jednak tylko funkcja main tej kasy, której nazwa jest podana przy wywołaniu programu.
Jedna klasa może zawierać jako pola obiekty innej klasy (relacja "ma" - np. Auto ma Silnik ) - nazywa się to kompozycją lub agregacją.
//Program 2.5
class Osoba{
static int licznik_osob=0; //inicjalizowanie zmiennej statycznej
private String imie;
private int nr_osoby; //niezainicjowana zmienna niestatyczna ma domyślną //wartość 0
Osoba (String im) //konstuktor jednoargumentowy w klasie Osoba
{
this.imie=im;
licznik_osob++;
nr_osoby=licznik_osob;
System.out.println("Witaj: "+ imie+" jestes nowy! Twój numer to " + nr_osoby);
}
Osoba () //konstuktor bezargumentowy w klasie Osoba
{licznik_osob++;
nr_osoby=licznik_osob;
System.out.println("Witaj: jestes nowy, nie masz imienia i masz numer " + nr_osoby);
}
}// koniec klasy Osoba
Zadania do samodzielnego wykonania:
5. a) W klasie Osoba zdefiniować funkcję main, w której tworzy się obiekty: ja, ojciec, matka, brat, siostra oraz wyświetla ich imiona i numery oraz liczbę utworzonych obiektów.
b) Zdefiniować metodę statyczną wyświetlającą ile obiektów klasy Osoba utworzono w programie.
c) Do klasy Osoba dodać niestatyczne pole nazwisko. Zdefiniować konstruktor przeciążony. Wykorzystać go w programie prezentującym dane wszystkich członków pięcioosobowej rodziny Nowaków.
2013-02-26 T. Wiśniewska
INFORMATYKA II - laboratorium JAVA
INFORMATYKA I ROK
STUDIA STACJONARNE I STOPNIA
semestr letni, r. a. 2012/2013
3