Loading...

Жалпылоо чектөөлөрү

 

Биз генериктерде жалпы параметрди көрсөткөндө, демейки боюнча ал каалаган түрүн көрсөтө алат. Бирок, кээде сиз параметр чектелген түрлөрдүн топтомуна гана дал келишин каалайсыз. Бул учурда, параметр дал келүүгө тийиш болгон базалык классты көрсөтүүгө мүмкүндүк берген чектөөлөр колдонулат.

 

Чектөө коюу үчүн универсалдуу параметрден кийин кеңейтүү сөзү коюлат, андан кийин чектөөнүн базалык классы көрсөтүлөт:

class Account{ }

class Transaction<T extends Account>{ }

Мисалы, бул учурда Транзакциядагы T параметри үчүн чектөө Эсеп классы болуп саналат. Башкача айтканда, T параметринин ордуна биз Account классын же анын тукум класстарынын бирине өтө алабыз.

 

Мисалы, төмөнкү программаны карап көрөлү:

public class Program{

     

    public static void main(String[] args) {

         

        Account acc1 = new Account("1876", 4500);

        Account acc2 = new Account("3476", 1500);

             

        Transaction<Account> tran1 = new Transaction<Account>(acc1,acc2, 4000);

        tran1.execute();

        tran1 = new Transaction<Account>(acc1,acc2, 4000);

        tran1.execute();

    }

}

class Transaction<T extends Account>{

    

    private T from;     // с какого счета перевод

    private T to;       // на какой счет перевод

    private int sum;    // сумма перевода

    

    Transaction(T from, T to, int sum){

        this.from = from;

        this.to = to;

        this.sum = sum;

    }

    public void execute(){

        

        if (from.getSum() > sum)

        {

            from.setSum(from.getSum() - sum);

            to.setSum(to.getSum() + sum);

            System.out.printf("Account %s: %d \nAccount %s: %d \n",

                from.getId(), from.getSum(),to.getId(), to.getSum());

        }

        else{

            System.out.printf("Operation is invalid");

        }

    }

}

class Account{

    

    private String id;

    private int sum;

    

    Account(String id, int sum){

        this.id = id;

        this.sum = sum;

    }

    

    public String getId() { return id; }

    public int getSum() { return sum; }

    public void setSum(int sum) { this.sum = sum; }

}

Бул учурда, эки эсептин ортосунда акча каражаттарын которуу операциясын билдирген Транзакция классы чектөө катары Эсеп классы болгон T параметри менен терилген. Транзакция объектисин түзүүдө анын конструкторуна Эсептин эки объектиси өткөрүлүп берилет - алардын ортосунда которуу жүргүзүлүүгө тийиш болгон эки эсеп жана которуунун суммасы.

 

Биз мындай чектөө койгондуктан, компилятор T түрүндөгү объекттерди Account түрүндөгү объекттер катары тааный турганын түшүнүү маанилүү. Жана бул учурда Т тибиндеги объекттерде Account классынын методдорун чакыра алабыз. Эгерде биз ушундай чектөө койбосок, муну кыла алмак эмеспиз:

class Transaction<T>{

    // остальное содержимое

}

Бул учурда, ката болот.

 

Чектөө катары жалпы түрлөр

Башка жалпылоолор чектөөлөр катары иш алып барышы мүмкүн, алардын өздөрү да чектөөлөр болушу мүмкүн:

public class Program{

     

    public static void main(String[] args) {

          

        Account<String> acc1 = new Account<String>("1876", 4500);

        Account<String> acc2 = new Account<String>("3476", 1500);

             

        Transaction<Account<String>> tran1 = new Transaction<Account<String>>(acc1,acc2, 4000);

        tran1.execute();

        tran1 = new Transaction<Account<String>>(acc1,acc2, 4000);

        tran1.execute();

    }

}

class Transaction<T extends Account<String>>{

    

    private T from;     // с какого счета перевод

    private T to;       // на какой счет перевод

    private int sum;    // сумма перевода

    

    Transaction(T from, T to, int sum){

        this.from = from;

        this.to = to;

        this.sum = sum;

    }

    public void execute(){

        

        if (from.getSum() > sum)

        {

            from.setSum(from.getSum() - sum);

            to.setSum(to.getSum() + sum);

            System.out.printf("Account %s: %d \nAccount %s: %d \n",

                from.getId(), from.getSum(),to.getId(), to.getSum());

        }

        else{

            System.out.printf("Operation is invalid");

        }

    }

}

class Account<T>{

    

    private T id;

    private int sum;

    

    Account(T id, int sum){

        this.id = id;

        this.sum = sum;

    }

    

    public T getId() { return id; }

    public int getSum() { return sum; }

    public void setSum(int sum) { this.sum = sum; }

}

Бул учурда, Transaction үчүн чектөө String тиби менен терилген Account тиби болуп саналат.

 

Чектөөлөр катары интерфейстер

Интерфейстер чектөө катары да иштей алат. Бул учурда, жалпы параметрдин ордуна өткөн тип берилген интерфейсти ишке ашырууга тийиш:

 

public class Program{

     

    public static void main(String[] args) {

         

        Account acc1 = new Account("1235rwr", 5000);

        Account acc2 = new Account("2373", 4300);

        Transaction<Account> tran1 = new Transaction<Account>(acc1, acc2, 1560);

        tran1.execute();

    }

}

interface Accountable{

    String getId();

    int getSum();

    void setSum(int sum);

}

class Account implements Accountable{

    

    private String id;

    private int sum;

    

    Account(String id, int sum){

        this.id = id;

        this.sum = sum;

    }

    

    public String getId() { return id; }

    public int getSum() { return sum; }

    public void setSum(int sum) { this.sum = sum; }

}

class Transaction<T extends Accountable>{

    

    private T from;     // с какого счета перевод

    private T to;       // на какой счет перевод

    private int sum;    // сумма перевода

    

    Transaction(T from, T to, int sum){

        this.from = from;

        this.to = to;

        this.sum = sum;

    }

    public void execute(){

        

        if (from.getSum() > sum)

        {

            from.setSum(from.getSum() - sum);

            to.setSum(to.getSum() + sum);

            System.out.printf("Account %s: %d \nAccount %s: %d \n",

                from.getId(), from.getSum(),to.getId(), to.getSum());

        }

        else{

            System.out.printf("Operation is invalid");

        }

    }

}

Бир нече чектөөлөр

Ошондой эле бир эле учурда бир нече чектөөлөрдү орното аласыз. Мисалы, Transaction классы Accountable интерфейсин ишке ашырган жана Person классынын тукумдары болгон объекттер менен гана иштей алат дейли:

class Person{}

interface Accountable{}

 

class Transaction<T extends Person & Accountable>{}