Podstawy klas w JAVA
Ponieważ cały kod programów w Javie należy do klas, używaliśmy klasy od początku tej książki. Oczywiście przedstawione przykłady były bardzo proste i nie wykorzystywały większości możliwości klas. Jak się teraz przekonasz, możliwości klas są znacznie większe niż te, które poznałeś w dotychczasowych przykładach.
Zacznijmy zatem od podstaw. Klasa jest szablonem definiującym postać obiektu. Określa ona zarówno dane obiektu, jak i kod, który działa na tych danych. Java używa specyfikacji klasy podczas tworzenia obiektu. Obiekty są instancjami klasy. Innymi słowy, klasa jest zestawem planów określających sposób konstrukcji obiektu. Fizyczna reprezentacja klasy w pamięci komputera powstaje dopiero na skutek utworzenia obiektu tej klasy. I jeszcze jedno: przypominam, że zmienne i metody tworzące klasę nazywamy składowymi klasy.
Ogólna postać klasy
Definiując klasę, deklarujemy jej dokładną postać i zachowanie. W tym celu określamy zmienne, które zawiera klasa, i metody, które działają na tych zmiennych. Chociaż najprostsze klasy mogą zawierać tylko same metody bądź same zmienne składowe, to większość klas zawiera jedne i drugie. Klasę tworzymy przy użyciu słowa kluczowego class. Uproszczoną ogólną definicję klasy przedstawiłem poniżej.
// deklaracje zmiennych składowych
typ zmienna1;
typ zmienna2;
// ...
typ zmiennaN;
// deklaracje metod
typ metoda1(parametry) {
// ciało metody
}
typ metoda2(parametry) {
// ciało metody
}
// ...
typ metodaN(parametry) {
// ciało metody
}
}
Chociaż nie wymuszają tego żadne reguły składni, poprawnie zaprojektowana klasa powinna definiować jedną i tylko jedną logiczną jednostkę. Na przykład klasa przechowująca nazwiska i numery telefonów nie powinna zwykle przechowywać również informacji o notowaniach akcji na giełdzie, średniej opadów i cyklach słonecznych czy innych niepowiązanych informacji. Poprawnie zaprojektowane klasy grupują jedynie te informacje, które są powiązane logicznie. Jeśli umieścisz w klasie niezwiązane ze sobą dane, to szybko przekonasz się, że odbije się to niekorzystnie na strukturze Twojego kodu! Dotychczas używane przez nas klasy miały tylko jedną metodę: main(). Wkrótce dowiesz się, jak tworzyć inne metody. Zwróć jednak uwagę, że ogólna postać klasy nie określa metody main(). Metoda main() jest wymagana tylko wtedy, gdy od danej klasy rozpoczyna się działanie programu. Niektóre rodzaje aplikacji w Javie, na przykład aplety, w ogóle nie wymagają istnienia metody main().
Definiowanie klasy
Omawiane zagadnienia zilustruję na przykładzie klasy hermetyzującej informacje o samochodach takich jak osobowe, vany i dostawcze. Klasę tę nazwę Vehicle i umieszczę w niej trzy informacje o pojeździe: liczbę pasażerów, pojemność zbiornika paliwa i średnie zużycie paliwa (w litrach na 100 kilometrów).
Pierwszą wersję klasy Vehicle przedstawiłem na listingu 4.1. Definiuje ona trzy zmienne składowe: passengers, fuealcap i lkm. Zwróć uwagę, że klasa Vehicle nie ma na razie żadnej metody (dodamy je w kolejnych przykładach).
Listing 4.1. Vehicle.java
int passengers; // liczba pasażerów
int fuelcap; // pojemność zbiornika paliwa w litrach
double lkm; // zużycie paliwa w litrach na 100 kilometrów
}
Klasa definiuje nowy typ danych. W tym przypadku nazwą tego typu jest Vehicle. Nazwy tej będziesz używać, aby deklarować obiekty typu Vehicle. Pamiętaj, że klasa stanowi jedynie opis typu i nie tworzy żadnego obiektu. Zatem w powyższym przykładzie nie powstał ani jeden obiekt typu Vehicle.
Aby utworzyć obiekt typu Vehicle, użyj następującej instrukcji:
Po wykonaniu tej instrukcji minivan będzie instancją klasy Vehicle i tym samym będzie posiadać fizyczną reprezentację w pamięci komputera. Na razie nie musisz zagłębiać się w szczegóły tej instrukcji.
Za każdym razem, gdy tworzysz instancję klasy, powstaje obiekt zawierający własną kopię każdej zmiennej składowej zdefiniowanej przez klasę. Zatem każdy obiekt typu Vehicle będzie zawierać własną kopię zmiennych składowych passengers, fuelcap i lkm. Dostęp do tych zmiennych odbywa się za pomocą operatora zapisywanego za pomocą kropki (.). Operator ten łączy nazwę obiektu z nazwą zmiennej składowej. Oto ogólny sposób jego stosowania:
Zatem nazwa obiektu znajduje się po lewej stronie operatora, a nazwa składowej po jego prawej stronie. Na przykład: aby przypisać wartość 65 składowej fuelcap obiektu minivan, użyjesz następującej instrukcji:
W ogólnym przypadku operatora w postaci kropki możesz używać zarówno do dostępu do zmiennych składowych, jak i metod. Na listingu 4.2 przedstawiłem przykład programu używającego klasy Vehicle.
Listing 4.2. VehicleDemo.java
Nazwij ten plik VehicleDemo.java
*/
class Vehicle {
int passengers; // liczba pasażerów
int fuelcap; // pojemność zbiornika paliwa w litrach
double lkm; // zużycie paliwa w litrach na 100 kilometrów
}
// Ta klasa deklaruje obiekt typu Vehicle.
class VehicleDemo {
public static void main(String args[]) {
Vehicle minivan = new Vehicle();
int range;
// przypisuje wartości składowym obiektu minivan
minivan.passengers = 7;
minivan.fuelcap = 65; // Zwróć uwagę na dostęp do składowej przy użyciu operatora w postaci kropki.
minivan.lkm = 9.1;
// oblicza zasięg pojazdu przy pełnym zbiorniku
range = (int) (minivan.fuelcap / minivan.lkm * 100);
System.out.println("Minivan przewozi " + minivan.passengers + " osób na odległość do " + range + " kilometrów.");
}
}
Plik zawierający ten program nazwij VehicleDemo.java, gdyż metoda main() należy do klasy VehicleDemo, a nie klasy Vehicle. Kompilacja programu spowoduje utworzenie dwóch plików .class, jednego dla klasy Vehicle i drugiego dla klasy VehicleDemo. Kompilator języka Java automatycznie umieszcza każdą klasę we własnym pliku .class. Kod źródłowy klas Vehicle i VehicleDemo nie musi się znajdować w jednym pliku. Możesz umieścić je w osobnych plikach źródłowych o nazwach Vehicle.java i VehicleDemo.java.
Aby wykonać program, musisz uruchomić plik VehicleDemo.class. Wykonanie programu spowoduje wyświetlenie poniższego komunikatu:
Minivan przewozi 7 osób na odległość do 714 kilometrów.
Przypomnijmy w tym miejscu podstawową zasadę dotyczącą klas i obiektów: każdy obiekt ma własne kopie zmiennych składowych zdefiniowanych przez jego klasę. Dlatego wartość zmiennych składowych jednego obiektu może różnić się od wartości tych samych zmiennych należących do innego obiektu. Dwóch obiektów nic nie łączy poza przynależnością do tej samej klasy. Na przykład jeśli masz dwa obiekty klasy Vehicle, to każdy ma własną kopię zmiennych passengers, fuelcap i lkm, a ich wartość w obu obiektach może być różna. Ilustruje to program przedstawiony na listingu 4.3 (zwróć uwagę, że metoda main() należy teraz do klasy TwoVehicles).
Listing 4.3. TwoVehicles.java
class Vehicle {
int passengers; // liczba pasażerów
int fuelcap; // pojemność zbiornika paliwa w litrach
double lkm; // zużycie paliwa w litrach na 100 kilometrów
}
// Ta klasa deklaruje obiekt typu Vehicle.
class TwoVehicles {
public static void main(String args[]) {
Vehicle minivan = new Vehicle();
Vehicle sportscar = new Vehicle();
int range1, range2;
// przypisuje wartości składowym obiektu minivan
minivan.passengers = 7;
minivan.fuelcap = 65;
minivan.lkm = 9.1;
// przypisuje wartości składowym obiektu sportscar
sportscar.passengers = 2;
sportscar.fuelcap = 55;
sportscar.lkm = 12.5;
// oblicza zasięg pojazdów przy pełnym zbiorniku
range1 = (int) (minivan.fuelcap / minivan.lkm * 100);
range2 = (int) (sportscar.fuelcap / sportscar.lkm * 100);
System.out.println("Minivan przewozi " + minivan.passengers + " osób na odległość do " + range1 + " kilometrów.");
System.out.println("Auto sportowe przewozi " + sportscar.passengers + " osoby na odległość do " + range2 + " kilometrów.");
}
}
Wykonanie programu spowoduje wyświetlenie następujących informacji:
Minivan przewozi 7 osób na odległość do 714 kilometrów.
Auto sportowe przewozi 2 osoby na odległość do 440 kilometrów.
Jak widać, dane obiektu minivan różnią się od danych obiektu sportscar. Ilustruje to rysunek 4.1.
Rysunek 4.1.Zawartość dwóch obiektów klasy Vehicle
Java. Przewodnik dla początkujących. Wydanie VI, Autor: Herbert Schildt, Wydawnictwo: Helion