JavaRush /Блоги Java /Random-TG /Усулҳои пешфарз дар Java 8: Онҳо чӣ кор карда метавонанд ...
Spitfire
Сатҳи

Усулҳои пешфарз дар Java 8: Онҳо чӣ кор карда метавонанд ва наметавонанд?

Дар гурӯҳ нашр шудааст
Тарҷумаи мақолае, ки аз ҷониби Питер Верҳас аз моҳи апрели соли 2014 навишта шудааст . Усулҳои пешфарз дар Java 8: Онҳо чӣ кор карда метавонанд ва наметавонанд?  - 1Аз тарҷумон: истилоҳи " методи пешфарз " нав дар Java пайдо шудааст ва ман мутмаин нестам, ки барои он тарҷумаи муқарраршуда ба русӣ вуҷуд дорад. Ман истилоҳи "усули пешфарз" -ро истифода хоҳам кард, гарчанде ки ман фикр намекунам, ки он идеалӣ аст. Ман шуморо даъват мекунам, ки дар бораи тарҷумаи муваффақтар сӯҳбат кунед.

Усули пешфарз чист

Акнун, бо нашри Java 8, шумо метавонед усулҳои навро ба интерфейсҳо илова кунед, то интерфейс бо синфҳое, ки онро амалӣ мекунанд, мувофиқат кунад. Ин хеле муҳим аст, агар шумо китобхонаеро таҳия карда бошед, ки онро бисёр барномасозон аз Киев то Ню Йорк истифода мебаранд. Пеш аз Java 8, агар шумо интерфейсро дар китобхона муайян мекардед, шумо наметавонед ба он усулҳоро илова кунед, бидуни хатари он ки баъзе замимаҳое, ки интерфейси шуморо иҷро мекунанд, ҳангоми навсозӣ вайрон мешаванд. Пас, дар Java 8 шумо дигар аз ин тарсида наметавонед? Не, шумо наметавонед. Илова кардани усули пешфарз ба интерфейс метавонад баъзе синфҳоро корношоям гардонад. Биёед аввал чизҳои хуби усулҳои пешфарзро бубинем. Дар Java 8, усулро бевосита дар интерфейс татбиқ кардан мумкин аст. (Усулҳои статикӣ дар интерфейс ҳоло низ метавонанд амалӣ карда шаванд, аммо ин қиссаи дигар аст.) Усуле, ки дар интерфейс амалӣ карда мешавад, усули пешфарз номида мешавад ва бо калимаи калидии пешфарз ишора мешавад . Агар синф интерфейсро татбиқ кунад, он метавонад усулҳои дар интерфейс татбиқшударо татбиқ кунад, аммо талаб карда намешавад. Синф татбиқи пешфарзро мерос мегирад. Аз ин рӯ, ҳангоми тағир додани интерфейси амалӣ кардани синфҳо тағир додани синфҳо лозим нест.

Мероси чандкарата?

Агар синф зиёда аз як интерфейсро (масалан, ду) татбиқ кунад ва онҳо ҳамон усули пешфарзро татбиқ кунанд, корҳо мушкилтар мешаванд. Синф кадом усулро мерос мегирад? Ҷавоб ҳеҷ аст. Дар ин ҳолат, синф бояд худи методро амалӣ кунад (ё бевосита ё тавассути мерос гирифтани он аз синфи дигар). Вазъият ба ин монанд аст, агар танҳо як интерфейс усули пешфарз дошта бошад ва дар дигараш ҳамон усул абстрактӣ бошад. Java 8 кӯшиш мекунад, ки интизомнок бошад ва аз ҳолатҳои номуайян канорагирӣ кунад. Агар усулҳо дар зиёда аз як интерфейс эълон карда шаванд, он гоҳ ягон амалисозии пешфарз аз ҷониби синф мерос намегирад - шумо хатои компиляция мегиред. Ҳарчанд, агар синфи шумо аллакай тартиб дода шуда бошад, шумо метавонед хатогиро ба даст наоред. Java 8 дар ин бобат ба қадри кофӣ устувор нест. Сабабҳои ин вуҷуд доранд, ки ман намехоҳам ба муҳокима равам (масалан: versionи Java аллакай бароварда шудааст ва вақти муҳокимаҳо кайҳо гузаштааст ва дар маҷмӯъ, ин ҷой барои онҳо нест).
  • Фарз мекунем, ки шумо ду интерфейс доред ва синф ҳардуи онҳоро амалӣ мекунад.
  • Яке аз интерфейсҳо усули пешфарзро амалӣ мекунад m ().
  • Шумо ҳама интерфейсҳо ва синфро тартиб медиҳед.
  • Шумо интерфейсеро, ки усули m() надорад, бо эълони он ҳамчун усули абстрактӣ иваз мекунед.
  • Шумо танҳо интерфейси тағирёфтаро тартиб медиҳед.
  • Синфро оғоз кунед.
Усулҳои пешфарз дар Java 8: Онҳо чӣ кор карда метавонанд ва наметавонанд?  - 2Дар ин ҳолат синф кор мекунад. Шумо онро бо интерфейсҳои навшуда тартиб дода наметавонед, аммо он бо versionҳои кӯҳна тартиб дода шудааст ва аз ин рӯ кор мекунад. Ҳозир
  • тағир додани интерфейс бо усули абстрактии м () ва татбиқи пешфарз илова кунед.
  • Интерфейси тағирёфтаро тартиб диҳед.
  • Иҷрои синф: хато.
Ҳангоме ки ду интерфейс мавҷуд аст, ки татбиқи пешфарзии методро таъмин мекунанд, он усулро дар синф даъват кардан мумкин нест, агар он аз ҷониби худи синф амалӣ карда нашавад (аз нав, ё худ ба худ ё аз синфи дигар мерос гирифта бошад). Усулҳои пешфарз дар Java 8: Онҳо чӣ кор карда метавонанд ва наметавонанд?  - 3Синф мувофиқ. Онро бо интерфейси тағирёфта бор кардан мумкин аст. Он ҳатто метавонад то он даме, ки усуле даъват карда шавад, ки дар ҳарду интерфейс татбиқи пешфарз дорад, кор кунад.

Рамзи мисол

Методы по умолчанию в Java 8: что могут и чего не могут? - 4Барои нишон додани гуфтаҳои боло ман феҳристи санҷиширо барои синфи C.java ва 3 зеркаталог барои интерфейсҳо дар файлҳои I1.java ва I2.java сохтам. Феҳристи решавӣ барои санҷиш дорои рамзи сарчашмаи синфи C.java мебошад. Феҳристи асосӣ дорои versionи интерфейсҳое мебошад, ки барои иҷро ва компиляция мувофиқанд: интерфейси I1 усули пешфарз дорад m(); Интерфейси I2 ҳанӯз ягон усул надорад. Синф методе дорад main, ки мо метавонем онро барои санҷидани он иҷро кунем. Он тафтиш мекунад, ки оё ягон далели сатри фармон вуҷуд дорад, аз ин рӯ мо метавонем онро бо ё бидуни занг ба осонӣ иҷро кунем m().
~/github/test$ cat C.java
public class C implements I1, I2 {
  public static void main(String[] args) {
    C c = new C();
    if( args.length == 0 ){
      c.m();
    }
  }
}
~/github/test$ cat base/I1.java
public interface I1 {
  default void m(){
    System.out.println("hello interface 1");
  }
}
~/github/test$ cat base/I2.java
public interface I2 {
}
Шумо метавонед синфро аз сатри фармон тартиб диҳед ва иҷро кунед.
~/github/test$ javac -cp .:base C.java
~/github/test$ java -cp .:base C
hello interface 1
Феҳристи мувофиқ versionи интерфейси I2-ро дар бар мегирад, ки усули абстрактии m()-ро эълон мекунад ва инчунин бо сабабҳои техникӣ, нусхаи тағирнаёфтаи I1.java.
~/github/test$ cat compatible/I2.java

public interface I2 {
  void m();
}
Чунин маҷмӯаро барои тартиб додани синфи C истифода бурдан мумкин нест:
~/github/test$ javac -cp .:compatible C.java
C.java:1: error: C is not abstract and does not override abstract method m() in I2
public class C implements I1, I2 {
       ^
1 error
Паёми хато хеле дақиқ аст. Бо вуҷуди ин, мо C.class-ро аз маҷмӯаи қаблӣ дорем ва агар мо интерфейсҳоро ба директорияи мувофиқ тартиб диҳем, мо ду интерфейс дорем, ки ҳоло ҳам барои иҷро кардани синф истифода мешаванд:
~/github/test$ javac compatible/I*.java
~/github/test$ java -cp .:compatible C
hello interface 1
Феҳристи сеюм - wrong- дорои versionи I2 мебошад, ки методро низ эълон мекунад m():
~/github/test$ cat wrong/I2.java
public interface I2 {
  default void m(){
    System.out.println("hello interface 2");
  }
}
Ба шумо ҳатто дар бораи тартиб додан ғамхорӣ кардан лозим нест. Гарчанде ки усул ду маротиба эълон карда шуда бошад ҳам, синфро метавон истифода бурд ва то даъват шудани усули m() кор кунад. Ин аст он чизе ки мо ба далели сатри фармон ниёз дорем:
~/github/test$ javac wrong/*.java
~/github/test$ java -cp .:wrong C
Exception in thread "main" java.lang.IncompatibleClassChangeError: Conflicting default methods: I1.m I2.m
    at C.m(C.java)
    at C.main(C.java:5)
~/github/test$ java -cp .:wrong C x
~/github/test$

Хулоса

Вақте ки шумо китобхонаи худро ба Java 8 интиқол медиҳед ва интерфейсҳои худро барои дохил кардани усулҳои пешфарз иваз мекунед, эҳтимол шумо ягон мушкилот нахоҳед дошт. Ҳадди ақал, он чизест, ки таҳиягарони китобхонаи Java 8 ҳангоми илова кардани функсияҳо ба он умед мебанданд. Барномаҳое, ки китобхонаи шуморо истифода мебаранд, то ҳол онро барои Java 7 истифода мебаранд, ки дар он ҷо усулҳои пешфарз вуҷуд надоранд. Агар якчанд китобхона якҷоя истифода шаванд, эҳтимолияти ихтилоф вуҷуд дорад. Чӣ тавр аз он пешгирӣ кардан мумкин аст? API-и китобхонаи худро ҳамон тавре, ки қаблан буд, тарроҳӣ кунед. Бо такя ба имкониятҳои усулҳои пешфарз худдорӣ накунед. Онҳо чораи охирин мебошанд. Номҳоро бодиққат интихоб кунед, то аз бархӯрд бо интерфейсҳои дигар канорагирӣ кунед. Биёед бубинем, ки рушди Java бо истифода аз ин хусусият чӣ гуна инкишоф хоҳад ёфт.
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION