Pagsasalin ng isang artikulo na isinulat ni Peter Verhas na may petsang Abril 2014. Mula sa tagasalin: ang terminong " default na pamamaraan " ay kakalabas lang sa Java at hindi ako sigurado kung mayroong itinatag na pagsasalin sa Russian para dito. Gagamitin ko ang terminong "default na paraan", kahit na sa tingin ko ay hindi ito perpekto. Inaanyayahan kita na talakayin ang isang mas matagumpay na pagsasalin.
Ano ang default na paraan
Ngayon, sa paglabas ng Java 8, maaari kang magdagdag ng mga bagong pamamaraan sa mga interface upang manatiling tugma ang interface sa mga klase na nagpapatupad nito. Napakahalaga nito kung bubuo ka ng library na ginagamit ng maraming programmer mula Kyiv hanggang New York. Bago ang Java 8, kung tinukoy mo ang isang interface sa isang library, hindi ka maaaring magdagdag ng mga pamamaraan dito nang hindi nanganganib na masira ang ilang application na tumatakbo sa iyong interface kapag na-update ito. Kaya, sa Java 8 hindi ka na matakot dito? Hindi hindi mo kaya. Ang pagdaragdag ng isang default na paraan sa isang interface ay maaaring gumawa ng ilang mga klase na hindi magamit. Tingnan muna natin ang magagandang bagay tungkol sa mga default na pamamaraan. Sa Java 8, ang pamamaraan ay maaaring ipatupad nang direkta sa interface. (Ang mga static na pamamaraan sa isang interface ay maaari na ring ipatupad, ngunit iyon ay isa pang kuwento.) Ang isang pamamaraan na ipinatupad sa isang interface ay tinatawag na isang default na paraan, at ito ay tinutukoy ng default na keyword . Kung ang isang klase ay nagpapatupad ng isang interface, maaari itong, ngunit hindi kinakailangan na, ipatupad ang mga pamamaraan na ipinatupad sa interface. Ang klase ay nagmamana ng default na pagpapatupad. Ito ang dahilan kung bakit hindi kinakailangang baguhin ang mga klase kapag binabago ang interface na kanilang ipinapatupad.Maramihang mana?
Ang mga bagay ay nagiging mas kumplikado kung ang isang klase ay nagpapatupad ng higit sa isa (sabihin, dalawa) na mga interface, at ipinapatupad nila ang parehong default na paraan. Aling pamamaraan ang mamanahin ng klase? Ang sagot ay wala. Sa kasong ito, dapat ipatupad ng klase ang mismong pamamaraan (alinman sa direkta o sa pamamagitan ng pagmamana nito mula sa ibang klase). Ang sitwasyon ay magkatulad kung ang isang interface lamang ang may default na pamamaraan, at sa iba pang paraan ay abstract. Sinusubukan ng Java 8 na maging disiplinado at maiwasan ang mga hindi maliwanag na sitwasyon. Kung ang mga pamamaraan ay ipinahayag sa higit sa isang interface, kung gayon walang default na pagpapatupad ang minana ng klase - makakakuha ka ng error sa compilation. Bagaman, maaaring hindi ka makakuha ng error sa compilation kung na-compile na ang iyong klase. Ang Java 8 ay hindi sapat na matatag sa bagay na ito. May mga dahilan para dito, na hindi ko gustong talakayin (halimbawa: ang paglabas ng Java ay nailabas na at ang oras para sa mga talakayan ay matagal nang lumipas at sa pangkalahatan, hindi ito ang lugar para sa kanila).- Sabihin nating mayroon kang dalawang interface at ang isang klase ay nagpapatupad ng pareho sa mga ito.
- Ang isa sa mga interface ay nagpapatupad ng default na paraan m().
- Isasama mo ang lahat ng mga interface at ang klase.
- Binago mo ang isang interface na walang m() na pamamaraan sa pamamagitan ng pagdedeklara nito bilang abstract na paraan.
- I-compile mo lang ang binagong interface.
- Simulan ang klase.
- baguhin ang interface gamit ang abstract m() na pamamaraan at magdagdag ng default na pagpapatupad.
- I-compile ang binagong interface.
- Patakbuhin ang klase: error.
Halimbawang code
Upang ipakita ang nasa itaas, gumawa ako ng direktoryo ng pagsubok para sa klase ng C.java at 3 subdirectory para sa mga interface sa mga file na I1.java at I2.java. Ang root directory para sa pagsubok ay naglalaman ng source code para sa C.java class. Ang base na direktoryo ay naglalaman ng isang bersyon ng mga interface na angkop para sa pagpapatupad at pagsasama-sama: ang interface I1 ay may default na paraan m(); Ang interface ng I2 ay wala pang anumang mga pamamaraan. Ang klase ay may isang pamamaraanmain
upang maisagawa namin ito upang subukan ito. Sinusuri nito kung mayroong anumang mga argumento ng command line, upang madali nating maisagawa ito nang may o walang pagtawag sa 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 {
}
Maaari mong i-compile at patakbuhin ang klase mula sa command line.
~/github/test$ javac -cp .:base C.java
~/github/test$ java -cp .:base C
hello interface 1
Ang katugmang direktoryo ay naglalaman ng isang bersyon ng interface ng I2 na nagdedeklara ng paraan ng m() na abstract, at gayundin, para sa mga teknikal na kadahilanan, isang hindi binagong kopya ng I1.java.
~/github/test$ cat compatible/I2.java
public interface I2 {
void m();
}
Ang nasabing set ay hindi maaaring gamitin upang mag-compile ng isang C class:
~/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
Ang mensahe ng error ay napaka-tumpak. Gayunpaman, mayroon kaming C.class mula sa isang nakaraang compilation at, kung isasama namin ang mga interface sa katugmang direktoryo, magkakaroon kami ng dalawang interface na magagamit pa rin upang patakbuhin ang klase:
~/github/test$ javac compatible/I*.java
~/github/test$ java -cp .:compatible C
hello interface 1
Ang ikatlong direktoryo - wrong
- ay naglalaman ng bersyon I2, na nagdedeklara rin ng pamamaraan m()
:
~/github/test$ cat wrong/I2.java
public interface I2 {
default void m(){
System.out.println("hello interface 2");
}
}
Hindi mo na kailangang mag-alala tungkol sa compilation. Kahit na ang pamamaraan ay idineklara nang dalawang beses, ang klase ay maaari pa ring gamitin at patakbuhin hanggang sa ang m() na pamamaraan ay tinatawag. Ito ang kailangan natin ng argumento ng command line para sa:
~/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$
GO TO FULL VERSION