public class Cat {
String name;
int age;
}
Załóżmy, że piszemy program, który z jakiegoś powodu dotyczy kotów (na przykład mamy klinikę weterynaryjną, która oferuje dostęp do konta internetowego). Stworzyliśmy klasę Cat i zadeklarowaliśmy w niej dwie zmienne: String name i int age . Te zmienne składowe nazywane są polami. Zasadniczo jest to szablon dla wszystkich kotów, które stworzymy w przyszłości. Każdy obiekt Cat będzie miał dwie zmienne: imię i wiek.
public class Cat {
String name;
int age;
public static void main(String[] args) {
Cat smudge = new Cat();
smudge.age = 3;
smudge.name = "Smudge";
System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
}
}
Oto jak to działa! Tworzymy kota, nadajemy mu imię i wiek i wyświetlamy to wszystko na konsoli. Bułka z masłem. :) Najczęściej zajęcia opisują rzeczy i zjawiska w prawdziwym świecie. Kot, stół, osoba, błyskawica, strona książki, koło – to wszystko stworzysz w swoich programach za pomocą poszczególnych klas. Na razie skupmy się na zmiennych, które zadeklarowaliśmy w klasie Cat . Nazywa się je polami lub zmiennymi instancji. Ich nazwa naprawdę mówi wszystko. Każda instancja (lub obiekt) klasy Cat będzie miała te zmienne. Każdy tworzony przez nas kot będzie miał własną zmienną na imię i własny wiekzmienny. To ma sens — tak jest w zasadzie z prawdziwymi kotami. :) Oprócz zmiennych instancji istnieją również zmienne klasowe (zmienne statyczne). Zakończmy nasz przykład:
public class Cat {
String name;
int age;
static int count = 0;
public static void main(String[] args) {
Cat smudge = new Cat();
smudge.age = 3;
smudge.name = "Smudge";
count++;
Cat fluffy = new Cat();
fluffy.age = 5;
fluffy.name = "Fluffy";
count++;
System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
System.out.println("We created a cat named " + fluffy.name + ". His age is " + fluffy.age);
System.out.println("Total number of cats = " + count);
}
}
Dane wyjściowe konsoli: Stworzyliśmy kota o imieniu Smudge. Ma 3 lata Stworzyliśmy kota o imieniu Fluffy. Jego wiek to 5 lat Całkowita liczba kotów = 2 Teraz nasza klasa ma nową zmienną o nazwie count. Odpowiada za zliczanie stworzonych kotów. Za każdym razem tworzymy kota w mainmetody, zwiększamy tę zmienną o 1. Ta zmienna jest deklarowana za pomocą słowa kluczowego static. Oznacza to, że należy do klasy, a nie do konkretnego obiektu klasy. Co oczywiście ma sens: imię każdego kota należy do tego konkretnego kota, ale potrzebujemy jednego licznika kotów, który będzie dotyczył ich wszystkich. Dokładnie to osiąga słowo kluczowe static: sprawia, że zmienna count jest pojedynczą zmienną dla wszystkich kotów. Uwaga: kiedy wyświetlamy zmienną, nie używamy smudge.count ani fluffy.count. Nie należy ani do Smudge'a, ani do Fluffy'ego; należy do całej klasy Cat . Dlatego jest to po prostu liczenie. Możesz także napisać Cat.count. To też byłoby poprawne. Podczas wyświetlania zmiennej name nie wykonalibyśmy następujących czynności:
public class Cat {
String name;
int age;
static int count = 0;
public static void main(String[] args) {
Cat smudge = new Cat();
smudge.age = 3;
smudge.name = "Smudge";
count++;
System.out.println("We created a cat named " + name + ". His age is " + smudge.age);
System.out.println("Total number of cats = " + count);
}
}
To jest błąd! Każdy kot ma swoje imię. Kompilator jest tutaj zdezorientowany. „Wyprowadzić nazwę do konsoli? Czyja nazwa?” :/"
Metody
Oprócz zmiennych każda klasa ma metody. Porozmawiamy o nich bardziej szczegółowo w osobnej lekcji, ale ogólne zasady są dość proste. Metody określają funkcjonalność twojej klasy, tj. co mogą robić obiekty twojej klasy. Jedna z tych metod jest już Ci znana: metoda main() . Ale, jak być może pamiętasz, główna metoda jest statyczna, co oznacza, że należy do całej klasy (logika jest taka sama jak w przypadku zmiennych). Jednak standardowe, niestatyczne metody można wywoływać tylko na określonych obiektach, które stworzyliśmy. Na przykład, jeśli chcemy napisać klasę kota, musimy wiedzieć, jakie funkcje powinien mieć kot w naszym programie. Wychodząc z tego założenia, napiszmy kilka metod dla naszego kota:
public class Cat {
String name;
int age;
public void sayMeow() {
System.out.println("Meow!");
}
public void jump() {
System.out.println("Pounce!");
}
public static void main(String[] args) {
Cat smudge = new Cat();
smudge.age = 3;
smudge.name = "Smudge";
smudge.sayMeow();
smudge.jump();
}
}
Sprawdź to! Teraz nasza klasa znacznie bardziej przypomina kota! Teraz mamy nie tylko kota z imieniem („Smudge”) i wiekiem (3). Potrafi też miauczeć i skakać! Co to byłby za kot bez tej „funkcjonalności”? :) Bierzemy konkretny obiekt (smudge) i wywołujemy jego metody sayMeow() i jump() . Spójrzmy na konsolę: Miau! Pazur! 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, będziesz musiał skorzystać z czegoś, co nazywa się abstrakcją. Abstrakcja jest jedną z czterech podstawowych zasad programowania obiektowego. Oznacza to wydobycie najważniejszych i znaczących cech przedmiotu i odwrotnie, odrzucenie tych, które są drugorzędne lub nieistotne. Stwórzmy na przykład szafkę na akta dla pracowników firmy. Aby utworzyć obiekty pracowników, napisaliśmy plik Employeeklasa. Jakie cechy są ważnymi deskryptorami pracownika dla szafy aktowej naszej firmy? Imię i nazwisko, data urodzenia, SSN i identyfikator pracownika. Ale jest mało prawdopodobne, że będziemy potrzebować wzrostu pracownika, koloru oczu lub koloru włosów do dokumentacji pracownika firmy. Firmy nie potrzebują tych informacji. Tak więc w klasie Pracownik deklarujemy następujące zmienne: String name , int age , int socialSecurityNumber oraz int EmployeeId. I pomijamy niepotrzebne informacje (takie jak kolor oczu). Innymi słowy, tworzymy abstrakcję. Jeśli jednak tworzymy szafkę na akta dla agencji modelek, sytuacja zmienia się diametralnie. Wzrost modelki, kolor oczu i włosów to ważne cechy, ale jej SSN jest dla nas absolutnie nieistotny. Tak więc w klasie Model musimy utworzyć następujące zmienne: Wysokość sznurka , Włosy sznurka , Oczy sznurka . Tak działa abstrakcja — to proste! :)Konstruktorzy
Wróćmy do naszego przykładu z kotem.
public class Cat {
String name;
int age;
public static void main(String[] args) {
Cat smudge = new Cat();
System.out.println("Here the program does something for 2 hours...");
smudge.age = 3;
smudge.name = "Smudge";
}
}
Przejrzyj ten kod i spróbuj dowiedzieć się, co jest nie tak z naszym programem. Nasz program miał kota bez imienia i wieku przez 2 godziny! Oczywiście jest to z natury błędne. Baza danych kliniki weterynaryjnej nie powinna zawierać kotów bez informacji. Obecnie nasz kot jest zdany na łaskę programisty. Ufamy, że nie zapomni podać imienia i wieku i że wszystko będzie dobrze. Jeśli zapomni, baza danych będzie miała problem: bezimienne koty. Jak możemy rozwiązać ten problem? Musimy jakoś zapobiec powstawaniu kotów bez imienia i wieku. Tu z pomocą przychodzą konstruktorzy. Podajmy przykład:
public class Cat {
String name;
int age;
// Constructor for the Cat class
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
public static void main(String[] args) {
Cat smudge = new Cat("Smudge", 5);
}
}
Zasadniczo konstruktor jest szablonem dla obiektów klasy. W tym przypadku wskazujemy, że dla każdego obiektu cat należy podać dwa argumenty, String i int . 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 smudge = new Cat(); // Error!
}
}
Teraz, gdy klasa ma konstruktora, kompilator Java wie, jak powinny wyglądać obiekty i nie pozwala na tworzenie obiektów bez określenia argumentów. Przyjrzyjmy się teraz słowu kluczowemu this, które widzisz wewnątrz konstruktora. To też proste. Słowo kluczowe this służy do wskazania konkretnego obiektu. Kod w konstruktorze
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
można zinterpretować niemal dosłownie: „Imię tego kota (tego, którego tworzymy) = argument przekazany dla parametru nazwy konstruktora. Wiek tego kota (tego, którego tworzymy) = argument przekazany dla konstruktora parametr wieku”. Po uruchomieniu konstruktora możesz sprawdzić, czy wszystkie niezbędne wartości zostały przypisane do naszego kota:
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 smudge = new Cat("Smudge", 5);
System.out.println(smudge.name);
System.out.println(smudge.age);
}
}
Wyjście konsoli: Smudge 5 Kiedy konstruktor został wywołany:
Cat smudge = new Cat("Smudge", 5);
Oto, co faktycznie wydarzyło się wewnętrznie:
this.name = "Smudge";
this.age = 5;
A wartości argumentów przekazanych do konstruktora zostały przypisane do obiektu smudge (do tego właśnie odnosi się to w tym przypadku). W rzeczywistości, nawet jeśli nie zadeklarujesz żadnych konstruktorów w klasie, nadal wywoła ona konstruktora! Ale jak to możliwe? О_О Ponieważ wszystkie klasy Javy mają tak zwany konstruktor domyślny. Nie przyjmuje żadnych argumentów, ale jest wywoływana za każdym razem, gdy tworzysz obiekt dowolnej klasy.
public class Cat {
public static void main(String[] args) {
Cat smudge = new Cat(); // The default constructor is invoked here
}
}
Na pierwszy rzut oka może to nie być oczywiste. Stworzyliśmy obiekt i co z tego? Gdzie konstruktor cokolwiek tu robi? Aby to zobaczyć, napiszmy jawnie pusty konstruktor dla klasy Cat . W środku wypiszemy jakąś frazę na konsolę. Jeśli fraza jest wyświetlana, to konstruktor został wywołany.
public class Cat {
public Cat() {
System.out.println("A cat has been created!");
}
public static void main(String[] args) {
Cat smudge = new Cat(); // The default constructor is invoked here
}
}
Wyjście konsoli: Utworzono kota! Jest potwierdzenie. Domyślny konstruktor jest zawsze niewidocznie obecny w twoich klasach. Ale musisz wiedzieć o tym jeszcze jedną rzecz. Konstruktor domyślny jest usuwany z klasy po utworzeniu konstruktora z argumentami. W rzeczywistości widzieliśmy już dowód na to powyżej. To było 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 smudge = new Cat(); // Error!
}
}
Nie mogliśmy stworzyć kota bez imienia i wieku, ponieważ zadeklarowaliśmy konstruktora Cat z parametrami string i int. Spowodowało to natychmiastowe zniknięcie domyślnego konstruktora z klasy. Pamiętaj więc, że jeśli potrzebujesz kilku konstruktorów w swojej klasie, w tym konstruktora bezargumentowego, będziesz musiał zadeklarować go osobno. Nasza przychodnia chce robić dobre uczynki i pomagać bezdomnym kociakom, których imienia i wieku nie znamy. Wtedy nasz kod powinien wyglądać tak:
public class Cat {
String name;
int age;
// For cats with owners
public Cat(String name, int age) {
this.name = name;
this.age = age;
}
// For street cats
public Cat() {
}
public static void main(String[] args) {
Cat smudge = new Cat("Smudge", 5);
Cat streetCat = new Cat();
}
}
Teraz, gdy określiliśmy jawny domyślny konstruktor, możemy stworzyć oba typy kotów. W konstruktorze możesz bezpośrednio przypisywać wartości. Nie zawsze musisz brać je z argumentów. Na przykład moglibyśmy oznaczyć wszystkie koty uliczne w bazie danych, używając jako szablonu „Nr kota ulicznego <liczba>”. :
public class Cat {
String name;
int age;
static int count = 0;
public Cat() {
count++;
this.name = "Street cat No. " + 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ą zliczającą , która zlicza nasze uliczne koty. Za każdym razem, gdy uruchamiany jest domyślny konstruktor, zwiększamy liczbę o 1 i dołączamy tę liczbę do imienia kota. Kolejność argumentów jest bardzo ważna dla konstruktorów. Zamieńmy argumenty name i age przekazane naszemu konstruktorowi.
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 smudge = new Cat("Smudge", 10); // Error!
}
}
Mamy błąd! Konstruktor wyraźnie określa, że podczas tworzenia obiektu Cat należy przekazać mu liczbę i ciąg znaków w tej kolejności. Więc nasz kod nie działa. Pamiętaj, aby pamiętać i szanować tę zasadę podczas deklarowania własnych klas:
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 konstruktorzy! Teraz wykonaj kilka zadań, aby utrwalić zrozumienie materiału. :)
-
Muzeum Starożytności.
Twoim zadaniem jest zaprojektowanie klasy artefaktu .
W muzeum przechowywane są trzy rodzaje artefaktów.
O pierwszym typie nic nie wiemy poza numerem seryjnym nadanym przez muzeum (np. 212121).
W przypadku drugiego typu znamy numer seryjny i kulturę, która go stworzyła (na przykład: 212121, „Aztekowie”).
W przypadku trzeciego typu znamy numer seryjny, kulturę, która go stworzyła oraz wiek, w którym powstał (na przykład: 212121, „Aztekowie”, 12).Utwórz klasę artefaktów , która opisuje antyki przechowywane w muzeum, i napisz wymagany zestaw konstruktorów dla tej klasy. Następnie w metodzie main() utwórz jeden artefakt każdego rodzaju.
public class Artifact { // Write your code here public static void main(String[] args) { // Write your code here } }
-
Portal randkowy
Stwórzmy bazę danych użytkowników portalu randkowego.
Ale oto problem: zapomniałeś wymaganej kolejności argumentów i nie ma dostępnej dokumentacji technicznej.
Zaprojektuj klasę User , która będzie miała następujące pola: name ( String ), age ( short ) i height ( int ).
Utwórz odpowiednią 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; // Write your code here public static void main(String[] args) { } }
GO TO FULL VERSION