JavaRush /Java блогу /Random-KY /Класстар, уя класстардын түрлөрү мисалдар менен
Ярослав
Деңгээл
Днепр

Класстар, уя класстардын түрлөрү мисалдар менен

Группада жарыяланган
Баарына салам. Бул темада мен башталгычтарга бул теманы түшүнүүгө жардам берүү үчүн Java класстары жана алардын түрлөрү жөнүндө кеңири сүйлөшкүм келет, балким, жаңыдан үйрөнбөгөндөр жаңы нерсени үйрөнүшөт. Мүмкүн болгон учурда, бардыгы тирүү мисалдар менен коштолгон code мисалдары менен көрсөтүлөт. Келиңиз баштайлы. Класстар, уя класстардын түрлөрү мисалдар менен - ​​1Мен негизги нерсе класстардын биринчи эки түрүн түшүнүү экенин белгилегим келет, ал эми жергorктүү жана анонимдүү ички класстын жөн эле субтиптери болуп саналат.

Класс деген эмне?

Класс - бул бир нерсенин логикалык сүрөттөмөсү, анын жардамы менен сиз ошол нерсенин реалдуу мисалдарын түзө аласыз. Башка сөз менен айтканда, бул жөн гана түзүлгөн an objectтер кандай болушу керек экенин сүрөттөп турат: алар кандай касиеттерге жана ыкмаларга ээ болушу керек. Кыймылдар субъекттин мүнөздөмөлөрү, методдор - ал аткара ала турган иш-аракеттер. Класс деген эмне экенин түшүнгөн чыныгы жашоодон класстын жакшы үлгүсү катары чиймелер каралышы мүмкүн: чиймелер конструкцияларды сүрөттөө үчүн колдонулат (катапульт, бурагыч), бирок чийме дизайн эмес. Инженерлер долбоорлорду түзүү үчүн схемаларды колдонгондой эле, программалоо да касиеттери жана ыкмалары сүрөттөлгөн an objectтерди түзүү үчүн класстарды колдонот.
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
}
Бул мисалда биз Java классын түздүк, ал "студент" an objectисин сүрөттөйт: ар бир студенттин аты, тобу жана адистиги бар. Эми программанын башка жерлеринде биз бул класстын чыныгы үлгүлөрүн түзө алабыз. Башка сөз менен айтканда: класс Studentстудент кандай болушу керек портрети болсо, анда түзүлгөн инстанция чыныгы окуучунун өзү болуп саналат. Жаңы студентти түзүүнүн мисалы: new Student("Ivan", "KI-17-2", "Computer Engineering");Оператор newклассты издеп Student, андан кийин бул класстын атайын ыкмасын (конструкторун) чакырат. Конструктор даяр класс an objectисин кайтарып берет Student- биздин кымбаттуу, ачка студент стипендиясыз :))

Java тorндеги класстардын түрлөрү

Javaда башка класстын ичинде класстардын 4 түрү бар:
  1. Уюшкан ички класстар тышкы класстын ичиндеги статикалык эмес класстар.

  2. Уюшкан статикалык класстар сырткы класстын ичиндеги статикалык класстар.

  3. Java жергorктүү класстары методдордун ичиндеги класстар.

  4. Анонимдүү Java класстары учуу учурунда түзүлгөн класстар.

Алардын ар бири жөнүндө өзүнчө сөз кылабыз.

Сырткы класстын ичиндеги статикалык эмес класстар

Биринчиден, мен аны чыныгы мисал менен түшүнүшүңөрдү каалайм, анткени бул түшүнүүнү бир топ жеңилдетет. Эми биз чыныгы чоң нерсени майда бөлүктөргө бөлүп, учакты демонтаждайбыз! Бирок, мисал үчүн бир аз көрсөтүү жетиштүү болот, биз аны толугу менен сындырбайбыз. Бул процессти элестетүү үчүн биз учактын диаграммасын колдонобуз. Биринчиден, биз бир аз сүрөттөмө кошо турган Класстар, уя класстардын түрлөрү мисалдар менен - ​​2 классты түзүшүбүз керек : учактын аталышы, идентификациялык codeу, учуу.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
}
Эми биз канаттарды кошкубуз келет. Өзүнчө класс түзөсүзбү? Балким, бул логика, эгерде бизде учактарды долбоорлоо үчүн комплекстүү программа болсо жана анда биз эбегейсиз көп сандагы туунду класстарды (ата-эне класс менен бирдей логикага ээ класстар, башкача айтканда, алар тукум кууп өткөн класс, бирок ошондуктан алар логиканы же деталдуу мүнөздөмөлөрдү кошуу менен ата-эне классын кеңейтишет), бирок бизде бир учак бар оюн болсочу? Ошондо бүт структураны бир жерде (бир класста) бүтүргөнүбүз туурараак болот. Бул жерде статикалык эмес уя класстар ишке кирет. Негизинен, бул биздин тышкы класстын кээ бир майда-чүйдөсүнө чейин деталдуу сүрөттөлүшү болуп саналат. Бул мисалда, биз учак үчүн канаттарды түзүү керек - сол жана оң. Келгиле түзөлү!
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
}
WingОшентип, биз класстын (учак) ичинде статикалык эмес уя класс (канат) түзүп Airplane, эки өзгөрмө коштук - сол канат жана оң канат. Жана ар бир канаттын биз өзгөртө турган өзүнүн касиеттери (түсү, модели) бар. Мына ушундай жол менен сиз структураларды керек болсо, ошончо штатта аласыз. Жана көңүл буруңуз: мурда диаграммада учактын бөлүктөрү абдан көп болчу, жана, чынында, биз бардык бөлүктөрүн ички класстарга бөлсө болот, бирок мындай процесс дайыма эле сунуштала бербейт. Мындай учурларды тапшырмага жараша издөө керек. Маселени чечүү үчүн сизге канат такыр керек эмес болушу мүмкүн. Анда аларды жасоонун кереги жок. Бул адамдын бутуна, колуна, тулкусуна жана башына кесүү сыяктуу - бул мүмкүн, бирок эмне үчүн бул класс адамдар жөнүндө маалыматтарды сактоо үчүн гана колдонулса? Статикалык эмес уя салынган Java класстарынын өзгөчөлүктөрү:
  1. Алар an objectтерде гана бар, ошондуктан аларды түзүү үчүн an object керек. Башкача айтканда: биз канатыбызды учактын бир бөлүгү болушу үчүн долбоорлогонбуз, ошондуктан канат жасоо үчүн бизге учак керек, антпесе анын кереги жок.
  2. Java классынын ичинде статикалык өзгөрмөлөр болушу мүмкүн эмес. Эгер сизге кандайдыр бир туруктуулар же башка статикалык нерсе керек болсо, аларды тышкы класска жылдырышыңыз керек. Бул статикалык эмес уя класстын тышкы класс менен тыгыз байланышы менен шартталган.
  3. Класс сырткы класстын бардык жеке талааларына толук мүмкүнчүлүгү бар. Бул функция эки жол менен иштейт.
  4. Сиз тышкы класстын инстанциясына шилтеме ала аласыз. Мисал: Учак.бул учакка шилтеме, бул канатка шилтеме.

Сырткы класстын ичиндеги статикалык класстар

Класстын бул түрү кадимки сырткы класстан эч кандай айырмасы жок, бир нерседен башкасы: мындай класстын мисалын түзүү үчүн чекит менен бөлүнгөн тышкы класстан каалаганга чейинки жолдун баарын тизмектеш керек. Мисалы: Building.Plaftorm platform = new Building.Platform(); Статикалык класстар логикалык түзүлүш менен иштөө оңой болушу үчүн, тиешелүү класстарды жанаша коюу үчүн колдонулат. Мисалы: биз тышкы класс түзө алабыз Building, анда белгилүү бир имаратты чагылдырган класстардын белгилүү бир тизмеси болот.
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
}
Бул мисал статикалык класстар логикалык структураны ыңгайлуу формага топтоого кантип мүмкүнчүлүк берерин көрсөтөт. Эгерде алар жок болсо, биз 4 такыр башка класстарды түзүшүбүз керек болчу. Бул ыкманын артыкчылыктары:
  1. Класстардын саны кыскарды.
  2. Бардык класстар ата-энелер классынын ичинде. Биз ар бир классты өзүнчө ачпастан эле бүт иерархияны карай алабыз.
  3. Биз Building классына кайрылсак болот жана IDE бул класстын бардык субкласстарынын толук тизмесин сунуштайт. Бул сизге керектүү класстарды табууну жеңилдетет жана бүт сүрөттү толугураак көрсөтөт.
Уюшкан статикалык класстын мисалын түзүүнүн мисалы:Building.Shop myShop = new Building.Shop(“Food & Fun!”, “Kalyaeva 8/53”); Мен дагы белгилегим келет, бул стратегия AWT 2D класстарында Line2D, Arc2D, Ellipse2D жана башкалар сыяктуу фигураларды сүрөттөө үчүн колдонулат.

Жергorктүү класстар

Бул класстар башка методдордун ичинде жарыяланды. Чынында, алар статикалык эмес уя класстын бардык касиеттерине ээ, алардын инстанциялары гана методдо түзүлүшү мүмкүн, ал эми метод статикалык болушу мүмкүн эмес (аларды түзүү үчүн сизге тышкы класстын үлгүсү, шилтеме керек. чакыруучу an objectинин мисалы статикалык эмес методдорго кыйыр түрдө өткөрүлүп берилет, ал эми статикалык методдо бул шилтеме үчүн метод жок). Бирок алардын өз өзгөчөлүктөрү бар:
  1. Жергorктүү класстар акыркы метод өзгөрмөлөрү менен гана иштей алат. Эң негизгиси, метод аяктагандан кийин жергorктүү класстардын инстанциялары үймөктө сакталып, өзгөрүлмө жок кылынышы мүмкүн. Эгерде өзгөрмө акыркы деп жарыяланган болсо, анда компилятор өзгөрмөнүн көчүрмөсүн кийинчерээк an object тарабынан колдонуу үчүн сактай алат. Жана дагы бир нерсе: Javaнын 8+ versionсынан бери, сиз жергorктүү класстарда акыркы эмес өзгөрмөлөрдү колдоно аласыз, бирок алар өзгөрбөй турган шартта гана.
  2. Жергorктүү класстарды кирүү модификаторлору менен жарыялоо мүмкүн эмес.
  3. Локалдык класстар метод өзгөрмөлөрүнө мүмкүнчүлүк алышат.
Локалдык класстарды өтө сейрек кездештирүүгө болот, анткени алар codeду окууну кыйындатат жана эч кандай артыкчылыктарга ээ эмес, бирөөсү - метод өзгөрмөлөрүнө жетүү. Мен жергorктүү класстын кандай үлгүсүн алсак болорун билбейм, бул алардын натыйжалуу колдонулушун көрсөтөт, ошондуктан мен өзүмдүн үлгүмдү көрсөтөм. Бизде касиеттери (көчө), (үй) бар класс Person(бул адам деп болжолдонот) бар дейли . Биз жөн гана адамдын жайгашкан жерине кирүү үчүн кандайдыр бир an objectти кайтаргыбыз келет. Бул үчүн биз AddressContainer интерфейсин түздүк, ал адамдын жайгашкан жери тууралуу маалыматтарды сактоону билдирет. 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
}
Көрүнүп тургандай, методдун ичинде биз адамдын жайгашкан жерин сактоону ишке ашырган классты түздүк, ал жерде туруктуу өзгөрмөлөрдү түздүк (ушинтип методдон чыккандан кийин өзгөрмөлөр an objectте сакталат) жана даректи алуу ыкмасын ишке ашырдык жана үй. Эми биз адамдын жайгашкан жерин алуу үчүн бул an objectти программанын башка жерлеринде колдоно алабыз. Мен бул мисал идеалдуу эмес экенин түшүнөм жана аны класста гетерлерди калтыруу менен жасоо туурараак болмок Person, бирок бул класстын түзүлүшү жана анын мүмкүн болгон колдонулушу көрсөтүлдү, андан кийин бул сизден көз каранды.

Анонимдүү класстар

Капоттун астында анонимдүү класстар жөн гана статикалык эмес уя класстар. Алардын өзгөчөлүгү колдонууга жеңил. Башка класстын мисалын түзүүдө классыңызды түз жазсаңыз болот.
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!");
        }
    }
}
Негизи, биз жөн гана эки нерсени бир жерге бириктирип жатабыз: бир класстын үлгүсүн түзүү ( Animal) жана анын мураскорунун ички классынын ( ) үлгүсүн түзүү Tiger. Болбосо, классты өзүнчө түзүп, ошол эле натыйжага жетүү үчүн узунураак конструкцияларды колдонушубуз керек. Анонимдүү класстарды колдонуу көптөгөн учурларда, атап айтканда:
  • класстын денеси абдан кыска;
  • класстын бир гана нускасы керек;
  • класс түзүлгөн жерде же андан кийин дароо колдонулат;
  • Класстын аталышы маанилүү эмес жана codeду түшүнүүнү жеңилдетпейт.
Анонимдүү класстар көбүнчө GUIде окуяны иштеткичтерди түзүү үчүн колдонулат. Мисалы, баскычты түзүү жана аны чыкылdateуга жооп берүү үчүн:
JButton b2 = new JButton("Click");
b2.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        System.out.println("Кнопка нажата!");
    }
});
Бирок, Java 8ден кийин алар lambda туюнтмаларын колдоно башташты, бирок дагы эле 8 versionсына чейин көп code жазылган жана сиз мындай жазууларга туш болушуңуз мүмкүн (жана JavaRush программасында машыгууңузда кездешет).\ Ламбдалардын аналогу:
JButton b2 = new JButton("Click");
b2.addActionListener(e -> System.out.println("Кнопка нажата!"));
Макаланын аягы Көңүл бурганыңыз үчүн рахмат жана сиз жаңы нерсени үйрөндүңүз же мурда түшүнбөгөн нерсени түшүндүңүз деп үмүттөнөм. Ошондой эле бул макала "деталдарга көңүл буруу" категориясына кирерин тактагым келет . Бул менин биринчи эмгегим, ошондуктан кимдир бирөөгө пайдалуу болду деп ишенем. Жакын арада жаны идеялар келгенде дагы бир нерсе жазганга аракет кылам, менде бир гана ой бар... Баарына ийгorк жана программалоодо ийгorк :)
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION