JavaRush /Java Blogu /Random-AZ /Siniflər, nümunələrlə yuvalanmış siniflərin növləri
Ярослав
Səviyyə
Днепр

Siniflər, nümunələrlə yuvalanmış siniflərin növləri

Qrupda dərc edilmişdir
Hamıya salam. Bu mövzuda mən Java dərsləri və onların növləri haqqında ətraflı danışmaq istəyirəm ki, yeni başlayanlar bu mövzunu başa düşsünlər və bəlkə də yeni başlayanlar yeni bir şey öyrənsinlər. Mümkünsə, hər şey kod nümunələri ilə birlikdə real həyat nümunələrindən istifadə edilməklə göstəriləcəkdir. Gəlin başlayaq. Siniflər, nümunələrlə yuvalanmış siniflərin növləri - 1Və qeyd etmək istərdim ki, əsas odur ki, ilk iki sinif növünü başa düşmək lazımdır, yerli və anonim isə sadəcə daxili sinfin alt tipləridir.

Sinif nədir?

Sinif bir şeyin məntiqi təsviridir, onun köməyi ilə həmin şeyin real nümunələrini yarada biləcəyiniz şablondur. Başqa sözlə, bu, sadəcə olaraq yaradılan varlıqların necə olmasının təsviridir: onların hansı xüsusiyyətlərə və üsullara malik olması lazımdır. Xüsusiyyətlər obyektin xüsusiyyətləridir, metodlar onun yerinə yetirə biləcəyi hərəkətlərdir. Sinfin nə olduğunu başa düşməyə imkan verən real həyatdan yaxşı bir sinif nümunəsi rəsmlər hesab edilə bilər: təsvirlər strukturları təsvir etmək üçün istifadə olunur (katapult, tornavida), lakin rəsm dizayn deyil. Mühəndislər dizayn yaratmaq üçün planlardan istifadə etdiyi kimi, proqramlaşdırma da xassələri və metodları təsvir edən obyektləri yaratmaq üçün siniflərdən istifadə edir.
public class Student {
    private String name, group, specialty;

    public Student(String name, String group, String specialty) {
       this.name = name;
       this.group = group;
       this.specialty = specialty;
   }

   // getters/setters
}
Bu nümunədə biz “tələbə” varlığını təsvir edən Java sinfi yaratdıq: hər bir tələbənin adı, qrupu və ixtisası var. İndi proqramın başqa yerlərində biz bu sinfin real nümunələrini yarada bilərik. Başqa sözlə: sinif Studentşagirdin necə olması lazım olduğunu göstərən bir portretdirsə, yaradılan nümunə faktiki tələbənin özüdür. Yeni şagirdin yaradılması nümunəsi: new Student("Ivan", "KI-17-2", "Computer Engineering");Operator newsinfi axtarır Studentvə sonra bu sinfin xüsusi metodunu (konstruktorunu) çağırır. Konstruktor hazır sinif obyektini qaytarır Student- bizim əziz, təqaüdsüz ac tələbə :))

Java-da siniflərin növləri

Java-da başqa bir sinif daxilində 4 növ sinif var:
  1. İç-içə daxili siniflər xarici sinif daxilində statik olmayan siniflərdir.

  2. İç-içə statik siniflər xarici sinif daxilindəki statik siniflərdir.

  3. Java yerli sinifləri metodlar daxilindəki siniflərdir.

  4. Anonim Java sinifləri tez yaradılan siniflərdir.

Onların hər biri haqqında ayrıca danışacağıq.

Xarici sinif daxilində statik olmayan siniflər

Birincisi, bunun nə olduğunu real bir nümunə ilə başa düşməyinizi istəyirəm, çünki bu, başa düşməyi çox asanlaşdırır. Beləliklə, indi biz əsl böyük şeyi daha kiçik komponentlərə ayıracağıq və bir təyyarəni sökəcəyik! Ancaq nümunə üçün bir az göstərmək kifayətdir, biz onu tamamilə parçalamayacağıq. Bu prosesi vizuallaşdırmaq üçün bir təyyarə diaqramından istifadə edəcəyik. Birincisi, bir az təsvir əlavə edə biləcəyimiz Siniflər, nümunələrlə yuvalanmış siniflərin növləri - 2 bir sinif yaratmalıyıq : təyyarənin adı, identifikasiya kodu, uçuş.Airplane
public class Airplane {
    private String name, id, flight;

    public Airplane(String name, String id, String flight) {
        this.name = name;
        this.id = id;
        this.flight = flight;
    }

    // getters/setters
}
İndi qanadları əlavə etmək istəyirik. Ayrı sinif yaradılsın? Təyyarələrin layihələndirilməsi üçün mürəkkəb proqramımız varsa və burada çoxlu sayda törəmə siniflər (ana sinif, yəni miras aldıqları siniflə eyni məntiqə malik olan siniflər) yaratmalıyıqsa, bəlkə də bu məntiqdir. buna görə də məntiq və ya daha ətraflı xüsusiyyətlər əlavə etməklə ana sinfi genişləndirirlər), ancaq bir təyyarəmiz olan bir oyunumuz varsa necə? O zaman bütün strukturu bir yerdə (bir sinifdə) tamamlamaq bizim üçün daha rasional olar. Burada statik olmayan iç-içə siniflər işə düşür. Əslində, bu, xarici sinifimizin bəzi detallarının daha ətraflı təsviridir. Bu nümunədə bir təyyarə üçün qanadlar yaratmalıyıq - sol və sağ. Yaradaq!
public class Airplane {
    private String name, id, flight;
    private Wing leftWing = new Wing("Red", "X3"), rightWing = new Wing("Blue", "X3");

    public Airplane(String name, String id, String flight) {
        this.name = name;
        this.id = id;
        this.flight = flight;
    }

    private class Wing {
        private String color, model;

        private Wing(String color, String model) {
            this.color = color;
            this.model = model;
        }

        // getters/setters
    }

    // getters/setters
}
Beləliklə, biz bir sinif (təyyarə) daxilində statik olmayan yuvalanmış sinif Wing(qanad) yaratdıq Airplanevə iki dəyişən əlavə etdik - sol qanad və sağ qanad. Və hər qanadın dəyişdirə biləcəyimiz öz xüsusiyyətləri (rəngi, modeli) var. Bu yolla siz strukturları lazım olan qədər işçi heyətinə qata bilərsiniz. Və qeyd edin: əvvəllər diaqramda təyyarə üçün kifayət qədər çox hissə var idi və əslində biz bütün hissələri daxili siniflərə ayıra bilərik, lakin belə bir proses həmişə məsləhət görülmür. Tapşırıqdan asılı olaraq belə məqamları izləmək lazımdır. Problemi həll etmək üçün ümumiyyətlə qanadlara ehtiyacınız olmaya bilər. Onda bunları etməyə ehtiyac qalmır. Bu, bir insanın ayaqlarına, qollarına, gövdəsinə və başına kəsilməsi kimidir - bu mümkündür, amma niyə bu sinif yalnız insanlar haqqında məlumatları saxlamaq üçün istifadə olunursa? Statik olmayan daxili Java siniflərinin xüsusiyyətləri:
  1. Onlar yalnız obyektlərdə mövcuddur, ona görə də onları yaratmaq üçün bir obyekt lazımdır. Başqa sözlə: biz qanadımızı təyyarənin bir hissəsi kimi dizayn etdik, ona görə də qanad yaratmaq üçün bizə təyyarə lazımdır, əks halda ona ehtiyacımız yoxdur.
  2. Java sinfində statik dəyişənlər ola bilməz. Əgər bəzi sabitlərə və ya başqa statik bir şeyə ehtiyacınız varsa, onları xarici sinifə köçürməlisiniz. Bu, statik olmayan yuvalanmış sinfin xarici siniflə sıx əlaqəsi ilə bağlıdır.
  3. Sinfin xarici sinfin bütün özəl sahələrinə tam girişi var. Bu xüsusiyyət iki şəkildə işləyir.
  4. Xarici sinfin nümunəsinə istinad əldə edə bilərsiniz. Nümunə: Təyyarə.bu təyyarəyə keçiddir, bu qanadla əlaqədir.

Xarici sinif daxilində statik siniflər

Bu tip sinfin adi xarici sinifdən heç bir fərqi yoxdur, bir şey istisna olmaqla: belə bir sinfin nümunəsini yaratmaq üçün xarici sinifdən istədiyinizə qədər bütün yolu nöqtə ilə ayırmaq lazımdır. Məsələn: Building.Plaftorm platform = new Building.Platform(); Statik siniflər məntiqi strukturla işləməyi asanlaşdırmaq üçün əlaqəli sinifləri yan-yana qoymaq üçün istifadə olunur. Məsələn: biz xarici sinif yarada bilərik Building, burada müəyyən bir binanı təmsil edəcək siniflərin xüsusi siyahısı olacaq.
public abstract class Building {
    private String name, address, type;

    Building(String name, String address) {
        this.name = name;
        this.address = address;
    }

    public static class Platform extends Building {
        public Platform(String name, String address) {
            super(name, address);
            setType("Platform");
        }

        // some additional logic
    }

    public static class House extends Building {
        public House(String name, String address) {
            super(name, address);
            setType("House");
        }

        // some additional logic
    }

    public static class Shop extends Building {
        public Shop(String name, String address) {
            super(name, address);
            setType("Shop");
        }

        // some additional logic
    }

    // getters/setters
}
Bu nümunə statik siniflərin məntiqi strukturu daha rahat formada paketləməyə necə imkan verdiyini nümayiş etdirir. Əgər onlar olmasaydı, biz tamamilə fərqli 4 sinif yaratmalı olacaqdıq. Bu yanaşmanın üstünlükləri:
  1. Dərslərin sayı azalıb.
  2. Bütün siniflər öz valideyn sinifindədir. Hər bir sinfi ayrıca açmadan bütün iyerarxiyanı izləyə bilirik.
  3. Biz Building sinfinə müraciət edə bilərik və IDE artıq bu sinfin bütün alt siniflərinin bütün siyahısını təqdim edəcək. Bu, sizə lazım olan sinifləri tapmağı asanlaşdıracaq və bütün mənzərəni daha bütöv şəkildə göstərəcək.
İç içə statik sinif nümunəsinin yaradılması nümunəsi:Building.Shop myShop = new Building.Shop(“Food & Fun!”, “Kalyaeva 8/53”); Onu da qeyd etmək istərdim ki, bu strategiya Line2D, Arc2D, Ellipse2D və başqaları kimi formaları təsvir etmək üçün AWT 2D siniflərində istifadə olunur.

Yerli siniflər

Bu siniflər digər metodların daxilində elan edilir. Əslində, onlar statik olmayan yuvalanmış sinfin bütün xassələrinə malikdirlər, yalnız onların nümunələri yalnız metodda yaradıla bilər və metod statik ola bilməz (onları yaratmaq üçün sizə xarici sinif nümunəsi, bir sinifə istinad lazımdır. çağıran obyektin nümunəsi qeyri-statik metodlara ötürülür və statik metodda bu keçid üçün metod yoxdur). Ancaq onların öz xüsusiyyətləri var:
  1. Yerli siniflər yalnız son metod dəyişənləri ilə işləyə bilər. Məsələ ondadır ki, yerli siniflərin nümunələri metod tamamlandıqdan sonra yığında saxlanıla bilər və dəyişən silinə bilər. Dəyişən yekun elan edilirsə, onda kompilyator dəyişənin nüsxəsini sonradan obyekt tərəfindən istifadə etmək üçün saxlaya bilər. Və daha bir şey: Java-nın 8+ versiyasından bəri, siz yerli siniflərdə son olmayan dəyişənlərdən istifadə edə bilərsiniz, ancaq onların dəyişməməsi şərti ilə.
  2. Yerli siniflər giriş modifikatorları ilə elan edilə bilməz.
  3. Yerli siniflərin metod dəyişənlərinə çıxışı var.
Yerli siniflər çox nadir hallarda tapıla bilər, çünki onlar kodu oxumağı çətinləşdirir və heç bir üstünlüyü yoxdur, bir istisna olmaqla - metod dəyişənlərinə giriş. Onların effektiv istifadəsini göstərən hansı yerli sinif nümunəsinin götürülə biləcəyini bilmirəm, ona görə də sadəcə öz nümunəmi göstərəcəyəm. Deyək ki, mülkləri (küçə), (ev) Personolan bir sinifimiz var (bunun bir şəxs olduğu güman ediləcək) . Biz yalnız şəxsin məkanına daxil olmaq üçün bəzi obyekti qaytarmaq istərdik. Bunun üçün biz AddressContainer interfeysini yaratdıq ki, bu da insanın yeri haqqında məlumatların saxlanmasını nəzərdə tutur. streethouse
public class Person {
    private String name, street, house;

    public Person(String name, String street, String house) {
        this.name = name;
        this.street = street;
        this.house = house;
    }

    private interface AddressContainer {
        String getStreet();
        String getHouse();
    }

    public AddressContainer getAddressContainer() {
        class PersonAddressContainer implements AddressContainer {
            final String street = Person.this.street, house = Person.this.house;

            @Override
            public String getStreet() {
                return this.street;
            }

            @Override
            public String getHouse() {
                return this.house;
            }
        }

        return new PersonAddressContainer();
    }

    public static void main(String[] args) {
        Person person = new Person("Nikita", "Sholohova", "17");

        AddressContainer address = person.getAddressContainer();

        System.out.println("Address: street - " + address.getStreet() + ", house - " + address.getHouse());
    }

    // getters/setters
}
Gördüyünüz kimi, metod daxilində biz insanın yerinin saxlanmasını həyata keçirən bir sinif yaratdıq, orada sabit dəyişənlər yaratdıq (belə ki, metoddan çıxdıqdan sonra dəyişənlər obyektdə saxlanılsın) və ünvanı və ünvanı əldə etmək üçün bir üsul həyata keçirdik. ev. İndi biz bu obyekti proqramın başqa yerlərində də istifadə edərək insanın yerini əldə edə bilərik. Mən başa düşürəm ki, bu nümunə ideal deyil və bunu sadəcə olaraq sinifdə alıcıları tərk etməklə etmək daha düzgün olardı Person, lakin bu sinfin yaradılması və onun mümkün istifadəsi göstərilib, sonra isə bu sizə bağlıdır.

Anonim siniflər

Başlıq altında anonim siniflər sadəcə statik olmayan adi siniflərdir. Onların özəlliyi istifadənin asanlığıdır. Başqa bir sinfin nümunəsini yaradarkən birbaşa sinfinizi yaza bilərsiniz.
public class Animal {
    public void meow() {
        System.out.println("Meow!");
    }

    public static void main(String[] args) {
        Animal anonTiger = new Animal() {
            @Override
            public void meow() {
                System.out.println("Raaar!");
            }
        };

        Animal notAnonTiger = new Animal().new Tiger();

        anonTiger.meow(); // будет выведено Raaar!
        notAnonTiger.meow(); // будет выведено Raaar!
    }

    private class Tiger extends Animal {
        @Override
        public void meow() {
            System.out.println("Raaar!");
        }
    }
}
Prinsipcə, biz sadəcə olaraq iki şeyi bir yerdə birləşdiririk: bir sinifin nümunəsini ( Animal) yaratmaq və onun varis daxili sinfinin nümunəsini yaratmaq ( Tiger). Əks halda, sinfi ayrıca yaratmalı və eyni nəticəni əldə etmək üçün daha uzun konstruksiyalardan istifadə etməliyik. Anonim siniflərin istifadəsi bir çox hallarda, xüsusən də:
  • sinif gövdəsi çox qısadır;
  • sinfin yalnız bir nümunəsi lazımdır;
  • sinif yaradıldığı yerdə və ya ondan dərhal sonra istifadə olunur;
  • Sinif adı vacib deyil və kodu başa düşməyi asanlaşdırmır.
Anonim siniflər tez-tez GUI-lərdə hadisə idarəçiləri yaratmaq üçün istifadə olunur. Məsələn, bir düymə yaratmaq və onun klikləməsinə reaksiya vermək üçün:
JButton b2 = new JButton("Click");
b2.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        System.out.println("Кнопка нажата!");
    }
});
Bununla belə, Java 8-dən sonra onlar lambda ifadələrindən istifadə etməyə başladılar, lakin hələ də 8-ci versiyadan əvvəl çoxlu kod yazılmışdı və siz belə yazılarla qarşılaşa bilərsiniz (və JavaRush-da təliminiz zamanı rastlaşacaqsınız).\ Lambda ilə analoq:
JButton b2 = new JButton("Click");
b2.addActionListener(e -> System.out.println("Кнопка нажата!"));
Məqalənin sonu Diqqətiniz üçün hamınıza təşəkkür edirəm və ümid edirəm ki, yeni bir şey öyrəndiniz və ya əvvəllər başa düşmədiyiniz bir şeyi başa düşdünüz. Mən də aydınlaşdırmaq istərdim ki, bu məqalə “detallara diqqət” kateqoriyasına aiddir . Bu mənim ilk işimdir, ümid edirəm kiməsə faydalı oldu. Yaxın gələcəkdə yeni ideyalar gələndə başqa bir şey yazmağa çalışacam, sadəcə bir fikrim var... Hər kəsə uğurlar və proqramlaşdırmada uğurlar :)
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION