Loading...

Наследованянын иерархиясы

 

Акыркы бөлүмдө биз жөнөкөй типтеги объекттердин конверсиялары жөнүндө сүйлөштүк. Бирок, класстык объектилер менен нерселер бир аз башкача. Бизде төмөнкү класс иерархиясы бар дейли:

public class Program{

     

    public static void main(String[] args) {

            

        Person tom = new Person("Tom");

        tom.display();

        Person sam = new Employee("Sam", "Oracle");

        sam.display();

        Person bob = new Client("Bob", "DeutscheBank", 3000);

        bob.display();

    }

}

// класс человека

class Person {

    

    private String name;

    

    public String getName() { return name; }

   

    public Person(String name){

    

        this.name=name;

    }

 

    public void display(){

        

        System.out.printf("Person %s \n", name);

    }

}

// служащий некоторой компании

class Employee extends Person{

 

    private String company;

    

    public Employee(String name, String company) {

    

        super(name);

        this.company = company;

    }

    public String getCompany(){ return company; }

    

    public void display(){

        

        System.out.printf("Employee %s works in %s \n", super.getName(), company);

    }

}

// класс клиента банка

class Client extends Person{

      

    private int sum; // Переменная для хранения суммы на счете

    private String bank;

      

    public Client(String name, String bank, int sum) {

      

        super(name);

        this.bank=bank;

        this.sum=sum;

    }

      

    public void display(){

          

        System.out.printf("Client %s has account in %s \n", super.getName(), bank);

    }

      

    public String getBank(){ return bank; }

    public int getSum(){ return sum; }

}

Бул класс иерархиясында мурастын төмөнкү чынжырчасын байкоого болот: Объект (бардык класстар Объекттин түрүнөн кыйыр түрдө мурасталат) -> Адам -> Кызматкер|Клиент.

Суперкласстар адатта подкласстардын үстүнө жайгаштырылат, ошондуктан Объект классы мурастын жогору жагында, ал эми Кызматкер менен Кардар эң ылдыйында.

 

субкласс объекти да суперкласс объектисин билдирет. Ошондуктан, программада биз төмөнкүдөй жаза алабыз:

Object tom = new Person("Tom");

Object sam = new Employee("Sam", "Oracle");

Object kate = new Client("Kate", "DeutscheBank", 2000);

Person bob = new Client("Bob", "DeutscheBank", 3000);

Person alice = new Employee("Alice", "Google");

Бул upcasting (төмөндөгү субкласстан иерархиянын жогору жагындагы суперкласска чейин) же жогорулоо деп аталган. Бул өзгөртүү автоматтык түрдө жүзөгө ашырылат.

 

Ар дайым тескери боло бербейт. Мисалы, Person объекти дайыма Кызматкер же Кардар объектиси боло бербейт. Демек, суперкласстан субкласска төмөндөтүү же төмөндөтүү автоматтык түрдө аткарылбайт. Бул учурда, биз түрүн өзгөртүү операциясын колдонуу керек.

Object sam = new Employee("Sam", "Oracle");

        

// нисходящее преобразование от Object к типу Employee

Employee emp = (Employee)sam;

emp.display();

System.out.println(emp.getCompany());

Бул учурда, sam өзгөрмө Кызматкер түрүнө чыгарылат. Анан emp объекти аркылуу биз Кызматкер объектинин функционалдуулугуна кире алабыз.

 

Биз Кызматкер объектин мурастын түз сызыгы аркылуу Объекттен Кызматкерге айландыра алабыз.

 

Төмөндөгү трансформациялардын мисалдары:

Object kate = new Client("Kate", "DeutscheBank", 2000);

((Person)kate).display();

        

Object sam = new Employee("Sam", "Oracle");

((Employee)sam).display();

Бирок дагы бир жагдайды карап көрөлү:

Object kate = new Client("Kate", "DeutscheBank", 2000);

Employee emp = (Employee) kate;

emp.display();

        

// или так

((Employee)kate).display();

Бул учурда Object түрүндөгү өзгөрмө Клиент объектисине шилтемени сактайт. Биз бул объектти Адамга же Кардарга катасыз чыгара алабыз. Бирок, биз Кызматкер түрүнө которууга аракет кылганда, биз иштөө убактысынын катасын алабыз. Анткени Кейт Кызматкер түрүндөгү объектти билдирбейт.

instanceof оператор

Жогорудагы мисалда биз Кейт өзгөрмөсү Кызматкер объектине эмес, Кардар объектисине шилтеме экенин ачык көрө алабыз. Бирок, көп учурда маалыматтар сырттан келет жана биз бул маалымат кандай объектти билдирерин так биле албашыбыз мүмкүн. Демек, катага туш болуу ыктымалдыгы жогору. Жана типти конвертациялоодон мурун, instanceof операторунун жардамы менен чыгарууну аткара аларыбызды текшере алабыз:

Object kate = new Client("Kate", "DeutscheBank", 2000);

if(kate instanceof Employee){

     

    Employee employeeKate = (Employee) kate;

    employeeKate.display();

}

else{

                     

    System.out.println("Conversion is invalid");

}

Kate instanceof Employee туюнтмасы kate өзгөрмөсү Кызматкер түрүндөгү объект экендигин текшерет. Бирок бул учурда андай эмес болгондуктан, мындай текшерүү жалганды кайтарып берет жана конверсия иштебейт.

 

Жана Кейт instance of Client туюнтмасы чындыкка кайтып келет:

Object kate = new Client("Kate", "DeutscheBank", 2000);

if(kate instanceof Client){

               

    Client clientKate = (Client) kate;

    clientKate.display();

}

else{

                     

    System.out.println("Conversion is invalid");

}

Белгилей кетчү нерсе, Java 16дан бери биз типти өзгөртүүнү төмөнкүдөй жөнөкөйлөштүрө алабыз

Object kate = new Client("Kate", "DeutscheBank", 2000);

if(kate instanceof Client clientKate){

    

    clientKate.display();

}

else{

                     

    System.out.println("Conversion is invalid");

}

Экспресс

kate instanceof Client clientKate

kate өзгөрмөсү Client классын билдирерин текшерет жана эгер ал көрсөтсө (б.а. instanceof оператору чындыкты кайтарса), анда Client түрүндөгү clientKate өзгөрмөсүн түзөт. Ал эми келечекте биз бул clientKate өзгөрмөсүн колдонуп, аны менен ар кандай операцияларды аткара алабыз.