Cześć! Dzisiaj porozmawiamy o klasach w Javie. Można powiedzieć, że klasy stanowią rdzeń programowania w Javie. Kiedy zostaniesz programistą, Twoim głównym zadaniem będzie pisanie własnych klas o różnej funkcjonalności. Dowiedzmy się, co to jest i jak działa :) Jak już wiesz, Java jest obiektowym językiem programowania. Wszystkie programy składają się z obiektów, które są ze sobą w jakiś sposób powiązane. Klasa jest zasadniczo szablonem obiektu. Określa, jak obiekt będzie wyglądał i jakie będzie pełnił funkcje. Każdy obiekt jest obiektem jakiejś klasy . Spójrzmy na najprostszy przykład:
public class Cat {
String name;
int age;
}
Załóżmy, że piszemy program i w tym programie potrzebujemy do czegoś kotów (np. mamy klinikę weterynaryjną z możliwością umówienia się na wizytę online). Stworzyliśmy klasę Cat
i określiliśmy dla niej dwie zmienne – ciąg znaków name
i liczbę age
. Takie zmienne klasowe nazywane są polami . Zasadniczo jest to szablon dla wszystkich kotów, które stworzymy w przyszłości. Każdy kot (obiekt klasy Cat
) będzie miał dwie zmienne - imię i wiek.
public class Cat {
String name;
int age;
public static void main(String[] args) {
Cat barsik = new Cat();
barsik.age = 3;
barsik.name = "Barsik";
System.out.println(„Stworzyliśmy kota o imieniu” + barsik.name + ", jego wiek - " + barsik.age);
}
}
Tak to działa! Stworzyliśmy kota, nadaliśmy mu imię i wiek, a następnie wypuściliśmy wszystko na konsolę. Nic skomplikowanego :) Zajęcia najczęściej opisują przedmioty i zjawiska otaczającego świata. Kot, stół, osoba, błyskawica, strona książki, koło - to wszystko stworzysz w Twoim programie za pomocą osobnych klas. Przyjrzyjmy się teraz zmiennym, które utworzyliśmy w klasie Cat
. Są to tak zwane pola lub zmienne instancji . Nazwa właściwie odsłania całą ich istotę. Każda instancja (obiekt) klasy będzie miała te zmienne Cat
. Każdy kot, którego stworzymy, będzie miał swoją własną zmienną name
i własny plik age
. To w sumie logiczne: z prawdziwymi kotami wszystko jest tak samo :) Oprócz zmiennych instancyjnych są jeszcze inne - zmienne klasowe , czyli statyczne. Dodajmy do naszego przykładu:
public class Cat {
String name;
int age;
static int count = 0;
public static void main(String[] args) {
Cat barsik = new Cat();
barsik.age = 3;
barsik.name = "Barsik";
count++;
Cat vasia = new Cat();
vasia.age = 5;
vasia.name = "Wasya";
count++;
System.out.println(„Stworzyliśmy kota o imieniu” + barsik.name + ", jego wiek - " + barsik.age);
System.out.println(„Stworzyliśmy kota o imieniu” + vasia.name + ", jego wiek - " + vasia.age);
System.out.println(„Całkowita liczba kotów =” + count);
}
}
Wyjście konsoli:
Мы создали кота по имени Барсик, его возраст - 3
Мы создали кота по имени Вася, его возраст - 5
Общее количество котов = 2
Teraz mamy nową zmienną w naszej klasie - count
(ilość). Jest odpowiedzialna za liczenie stworzonych kotów. Za każdym razem, gdy tworzymy cat w metodzie main, zwiększamy tę zmienną o 1. Zmienna ta jest oznaczona słowem kluczowym static . Oznacza to, że należy do klasy , a nie do konkretnego obiektu klasy. Co oczywiście jest logiczne: jeśli każdy kot powinien mieć swoje imię, to potrzebujemy jednego licznika kotów dla wszystkich. To jest dokładnie to, co pozwala osiągnąć słowo statyczny – count
ta sama zmienna dla wszystkich kotów. Uwaga: kiedy drukujemy go na konsolę, nie piszemy barsik.count
ani vasia.count
. Nie należy ani do Barsika, ani do Wasyi – należy do całej klasy Cat
. Dlatego jest to proste count
. Możesz też napisać Cat.count
- to też będzie poprawne. name
To nie zadziałałoby w przypadku wysyłania zmiennej do konsoli :
public class Cat {
String name;
int age;
static int count = 0;
public static void main(String[] args) {
Cat barsik = new Cat();
barsik.age = 3;
barsik.name = "Barsik";
count++;
System.out.println(„Stworzyliśmy kota o imieniu” + name + ", jego wiek - " + barsik.age);
System.out.println(„Całkowita liczba kotów =” + count);
}
}
Błąd! name
Każdy kot ma swojego. W tym miejscu kompilator jest zdezorientowany. „Wprowadź nazwę do konsoli? Czyje to imię? :/”
Metody
Oprócz zmiennych każda klasa ma metody. Porozmawiamy o nich bardziej szczegółowo w osobnym wykładzie, ale ogólne punkty są dość proste. Metody to funkcjonalność twojej klasy; co potrafią obiekty tej klasy. Jedną z metod już znasz - jest to metodamain()
. Ale metoda main
, jak pamiętasz, jest statyczna - czyli należy do całej klasy (logika jest taka sama jak przy zmiennych). A zwykłe, niestatyczne metody można wywołać tylko na określonych obiektach, które stworzyliśmy. Przykładowo, jeśli chcemy napisać klasę dla kota, musimy zrozumieć, jakie funkcje kot powinien pełnić w naszym programie. Na tej podstawie napiszmy na to kilka metod:
public class Cat {
String name;
int age;
public void sayMeow() {
System.out.println("Miauczeć!");
}
public void jump() {
System.out.println(„Skaczący galop!”);
}
public static void main(String[] args) {
Cat barsik = new Cat();
barsik.age = 3;
barsik.name = "Barsik";
barsik.sayMeow();
barsik.jump();
}
}
Cóż, teraz nasza klasa bardziej przypomina opis prawdziwego kota! Teraz nie mamy tylko kota o imieniu Barsik z imieniem i wiekiem. Potrafi także miauczeć i skakać! Co to za kot bez takiej „funkcjonalności” :) Bierzemy konkretny obiekt - barsik
i nazywamy jego metody sayMeow()
oraz jump()
. Patrzymy na konsolę:
Мяу!
Прыг-скок!
Prawdziwy kot! :)
Tworzenie własnych klas. Abstrakcja
W przyszłości będziesz musiał pisać własne zajęcia. Na co należy zwrócić uwagę podczas ich pisania? Jeśli mówimy o zmiennych, musisz użyć czegoś, co nazywa się abstrakcją . Abstrakcja jest jedną z czterech podstawowych zasad programowania obiektowego. Polega na podkreśleniu głównych, najistotniejszych cech obiektu i odwrotnie – odrzuceniu drugorzędnych, nieistotnych. Przykładowo tworzymy kartotekę pracowników firmy. Aby utworzyć obiekty pracownicze, napisaliśmy klasęEmployee
. Jakie cechy są ważne, aby opisać pracownika w aktach firmowych? Imię i nazwisko, data urodzenia, numer PESEL, numer identyfikacji podatkowej. Ale jest mało prawdopodobne, abyśmy potrzebowali jego wzrostu, koloru oczu i włosów w karcie pracownika firmy. Firma nie potrzebuje tych informacji. Dlatego dla klasy Employee
ustawimy zmienne String name
, i int age
, a informacje dla nas niepotrzebne (np. kolor oczu) porzucimy i wyabstrahujemy . Jeśli jednak stworzymy plik zdjęć modelek dla agencji modelek, sytuacja zmieni się diametralnie. Aby opisać modelkę, bardzo ważny jest dla nas wzrost, kolor oczu i kolor włosów, ale numer NIP nie jest dla nas absolutnie ważny. Dlatego w klasie musimy utworzyć zmienne , , . Tak działa abstrakcja, to proste! :) int socialInsuranceNumber
int taxNumber
Model
int height
String hair
String eyes
Konstruktorzy
Wróćmy do naszego przykładu z kotem.public class Cat {
String name;
int age;
public static void main(String[] args) {
Cat barsik = new Cat();
System.out.println("Coś się dzieje w programie od 2 godzin...");
barsik.age = 3;
barsik.name = "Barsik";
}
}
Spójrz na ten kod i spróbuj zgadnąć, co jest nie tak z naszym programem. Przez dwie godziny w naszym programie był kot bez imienia i wieku! Oczywiście jest to całkowicie błędne. W bazie kliniki weterynaryjnej nie powinno być kotów bez informacji o nich. Teraz pozostawiamy to programiście. Jeśli nie zapomni podać swojego imienia i wieku, wszystko będzie dobrze. Jeśli zapomni, w bazie będzie błąd, nieznane koty. Jak możemy rozwiązać ten problem? Trzeba w jakiś sposób zakazać tworzenia kotów bez imienia i wieku. Tutaj z pomocą przychodzą nam funkcje konstruktora . Oto przykład:
public class Cat {
String name;
int age;
//konstruktor klasy Cat
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat("Barsik", 5);
}
}
Konstruktor jest zasadniczo szablonem dla obiektów klas. W tym przypadku określamy, że dla każdego obiektu cat
należy podać dwa argumenty - ciąg znaków i liczbę. Jeśli teraz spróbujemy stworzyć bezimiennego kota, to się nie uda.
public class Cat {
String name;
int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat(); //błąd!
}
}
Teraz, gdy klasa ma konstruktora, kompilator Java wie, jak powinny wyglądać obiekty i nie pozwoli na tworzenie obiektów bez określonych w nim argumentów. Przyjrzyjmy się teraz słowu kluczowemu this
widocznemu w konstruktorze. Z nim też wszystko jest proste. „to” w języku angielskim oznacza „to, to”. Oznacza to, że to słowo wskazuje konkretny przedmiot. Kod w konstruktorze
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
można przetłumaczyć niemal dosłownie: " imię dla tego kota (którego tworzymy) = argument nazwa podany w konstruktorze. wiek dla tego kota (którego tworzymy) = argument wiek podany w konstruktorze." Po uruchomieniu konstruktora możesz sprawdzić, czy naszemu kotowi przypisano wszystkie niezbędne wartości:
public class Cat {
String name;
int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat("Barsik", 5);
System.out.println(barsik.name);
System.out.println(barsik.age);
}
}
Wyjście konsoli:
Барсик
5
Kiedy konstruktor zakończył:
Cat barsik = new Cat("Barsik", 5);
W środku faktycznie wydarzyło się co następuje:
this.name = "Barsik";
this.age = 5;
A obiektowi barsik
(jest this
) przypisano wartości z argumentów konstruktora. Tak naprawdę, jeśli nie określisz konstruktorów w klasie, konstruktor i tak zostanie uruchomiony ! Ale jak to możliwe? O_O Faktem jest, że w Javie wszystkie klasy posiadają tzw. konstruktora domyślnego . Nie ma żadnych argumentów, ale uruchamia się za każdym razem, gdy tworzony jest dowolny obiekt dowolnej klasy.
public class Cat {
public static void main(String[] args) {
Cat barsik = new Cat(); //tutaj działał domyślny konstruktor
}
}
Na pierwszy rzut oka nie jest to zauważalne. No cóż, stworzyliśmy obiekt i stworzyliśmy, gdzie jest praca projektanta? Aby to zobaczyć, napiszmy Cat
własnymi rękami pusty konstruktor dla klasy, a wewnątrz niego wypiszemy na konsolę jakąś frazę. Jeśli jest wyświetlony, oznacza to, że konstruktor zadziałał.
public class Cat {
public Cat() {
System.out.println(„Stworzył kota!”);
}
public static void main(String[] args) {
Cat barsik = new Cat(); //tutaj działał domyślny konstruktor
}
}
Wyjście konsoli:
Создали кота!
Oto potwierdzenie. Domyślny konstruktor jest zawsze niewidoczny w twoich klasach. Ale musisz poznać jeszcze jedną jego cechę. Domyślny konstruktor znika z klasy, gdy utworzysz konstruktor z argumentami. Dowód na to widzieliśmy już powyżej. Tutaj w tym kodzie:
public class Cat {
String name;
int age;
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat(); //błąd!
}
}
Nie mogliśmy stworzyć kota bez imienia i wieku, ponieważ zdefiniowaliśmy konstruktor dla Cat
: string + liczba. Domyślny konstruktor zniknął z klasy natychmiast po tym. Dlatego pamiętaj: jeśli potrzebujesz w swojej klasie kilku konstruktorów, w tym pustego, musisz go utworzyć osobno . Na przykład nasza klinika weterynaryjna chce czynić dobre uczynki i pomagać bezdomnym kotom, których imion i wieku nie znamy. Wtedy nasz kod powinien wyglądać tak:
public class Cat {
String name;
int age;
//dla kotów domowych
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
//dla kotów ulicznych
public Cat() {
}
public static void main(String[] args) {
Cat barsik = new Cat("Barsik", 5);
Cat streetCat = new Cat();
}
}
Teraz, gdy już określiliśmy domyślny konstruktor, możemy utworzyć oba typy kotów. W konstruktorze możesz przypisywać wartości jawnie, a nie tylko pobierać je z argumentów. Na przykład możemy zapisać wszystkie koty uliczne w bazie danych pod nazwą „Numer kota ulicznego…”:
public class Cat {
String name;
int age;
static int count = 0;
public Cat() {
count++;
this.name = „Numer kota ulicznego” + count;
}
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat streetCat1 = new Cat();
Cat streetCat2 = new Cat();
System.out.println(streetCat1.name);
System.out.println(streetCat2.name);
}
}
Mamy zmienną count
, która jest licznikiem kotów ulicznych. Za każdym razem, gdy uruchamiamy domyślny konstruktor, zwiększamy go o 1 i przypisujemy tę liczbę jako imię kota. Dla konstruktora kolejność argumentów jest bardzo ważna. Zamieńmy argumenty name i age w naszym konstruktorze.
public class Cat {
String name;
int age;
public Cat(int age, String name) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat barsik = new Cat("Barsik", 10); //błąd!
}
}
Błąd! Konstruktor jasno opisuje: podczas tworzenia obiektu Cat
należy przekazać liczbę i ciąg znaków w tej kolejności . Dlatego nasz kod nie działa. Pamiętaj o tym i miej to na uwadze tworząc własne zajęcia:
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public Cat(int age, String name) {
this.age = age;
this.name = name;
}
To dwaj zupełnie różni projektanci! Teraz rozwiążcie kilka zadań w celu utrwalenia materiału :)
- Muzeum Starożytności.
Artifact
. Artefakty przechowywane w muzeum są trzech typów. Pierwsza to ta, o której nie wiadomo nic poza nadanym przez muzeum numerem seryjnym (np. 212121). Drugi dotyczy tego, o czym znany jest numer seryjny i kultura, według której został stworzony (na przykład: 212121, „Aztekowie”). Trzeci typ dotyczy tego, o czym znany jest numer seryjny, kultura, w której został stworzony, oraz dokładny wiek jego powstania (na przykład: 212121, „Aztekowie”, 12). Utwórz klasę Artifact
opisującą zabytki przechowywane w muzeum i napisz wymaganą dla niej liczbę konstruktorów. W metodzie main()
utwórz po jednym artefakcie każdego typu.
public class Artifact {
public static void main(String[] args) {
}
}
- Strona internetowa spotkania
User
, która będzie miała pola - imię ( String
), wiek ( short
) i wzrost ( int
). Utwórz dla niego wymaganą liczbę konstruktorów, aby imię, wiek i wzrost można było podać w dowolnej kolejności.
public class User {
String name;
short age;
int height;
public static void main(String[] args) {
}
}
GO TO FULL VERSION