Programavimas

Pagrindinis superklasė, 1 dalis

Patyrę „Java“ kūrėjai dažnai laiko savaime suprantamomis „Java“ funkcijomis, kurios naujokams atrodo painios. Pavyzdžiui, pradedantysis gali būti supainiotas dėl Objektas klasė. Šiuo pranešimu pradedama trijų dalių serija, kurioje pristatau ir atsakau į klausimus Objektas ir jos metodai.

Karaliaus objektas

Klausimas: Kas yra Objektas klasė?

A: Objektas klasė, kuri saugoma java.lang paketas yra pagrindinis visų „Java“ klasių (išskyrus Objektas). Be to, masyvai tęsiasi Objektas. Tačiau sąsajos nesitęsia Objektas, kuris nurodytas „Java“ kalbos specifikacijos 9.6.3.4 skirsnyje: ... mano, kad nors sąsaja neturi Objektas kaip supertipas ....

Objektas deklaruoja šiuos metodus, kuriuos aš išsamiai aptarsiu vėliau šiame įraše ir likusioje šios serijos dalyje:

  • saugomas objekto klonas ()
  • loginė lygi (Object obj)
  • apsaugotas negaliojantis baigti ()
  • Klasė „getClass“ ()
  • int hashCode ()
  • negaliojantis pranešimas ()
  • negalioja praneštiVisi ()
  • Stygos toString ()
  • tuščias laukimas ()
  • tuščias laukimas (ilgas skirtasis laikas)
  • tuščias laukimas (ilgas skirtasis laikas, int nanos)

„Java“ klasė paveldi šiuos metodus ir gali nepaisyti bet kurio nedeklaruoto metodo galutinis. Pavyzdžiui,galutinistoString () metodas gali būti nepaisomas, o galutinislaukti() metodų negalima nepaisyti.

Klausimas: Ar galiu aiškiai pratęsti Objektas klasė?

A: Taip, galite aiškiai pratęsti Objektas. Pavyzdžiui, peržiūrėkite 1 sąrašą.

Išvardinimas 1. Aiškiai pratęsiama Objektas

importuoti java.lang.Object; viešoji klasė Darbuotojas praplečia objektą {privatus eilutės pavadinimas; viešasis darbuotojas (eilutės pavadinimas) {this.name = vardas; } public String getName () {grąžinimo vardas; } public static void main (String [] args) {Darbuotojo emp = naujas darbuotojas ("John Doe"); System.out.println (emp.getName ()); }}

Galite sudaryti 1 sąrašą (javac Employee.java) ir paleiskite gautą rezultatą Darbuotojas.klasė failas (java darbuotojas), ir jūs pastebėsite Jonas Doe kaip išvestis.

Kadangi kompiliatorius automatiškai importuoja tipus iš java.lang paketas, importuoti java.lang.Object; pareiškimas nereikalingas. Be to, „Java“ neverčia jūsų aiškiai išplėsti Objektas. Jei taip būtų, negalėtumėte pratęsti jokių kitų klasių, išskyrus Objektas nes „Java“ riboja klasės pratęsimą iki vienos klasės. Todėl paprastai pratęsiate Objektas netiesiogiai, kaip parodyta 2 sąraše.

Sąrašas 2. Netiesiogiai pratęsiantis Objektas

viešoji klasė Darbuotojas {privatus Stygos vardas; viešasis darbuotojas (eilutės pavadinimas) {this.name = vardas; } public String getName () {grąžinimo vardas; } public static void main (String [] args) {Darbuotojo emp = naujas darbuotojas ("John Doe"); System.out.println (emp.getName ()); }}

Kaip ir 1 sąraše, 2 sąraše Darbuotojas klasė tęsiasi Objektas ir paveldi jos metodus.

Objektų klonavimas

Klausimas: Ką daro klonas () metodas pasiekti?

A: klonas () metodas sukuria ir grąžina objekto, kuriam vadinamas šis metodas, kopiją.

Klausimas: Kaip veikia klonas () metodo darbas?

A:Objektas padargai klonas () kaip vietinį metodą, o tai reiškia, kad jo kodas saugomas gimtojoje bibliotekoje. Kai šis kodas vykdomas, jis patikrina iškviečiančio objekto klasę (arba superklasę), ar jis įgyvendina java.lang. Klonuojamas sąsaja - Objektas neįgyvendina Klonuojamas. Jei ši sąsaja neįdiegta, klonas () metimai java.lang.CloneNotSupportedException, kuri yra pažymėta išimtis (ji turi būti tvarkoma arba perkeliama į metod-call kaminą, prie metodo, kuriame naudojamas metodas, antraštėje pridedant metimų sąlygą klonas () buvo pasitelktas). Jei ši sąsaja įdiegta, klonas () priskiria naują objektą ir nukopijuoja iškviečiamo objekto lauko vertes į naujus objekto lygiaverčius laukus ir grąžina nuorodą į naują objektą.

Klausimas: Kaip aš galiu pasinaudoti klonas () metodas klonuoti objektą?

A: Atsižvelgiant į objekto nuorodą, iškvieskite klonas () ant šios nuorodos ir išmeskite grąžintą objektą iš Objektas į klonuojamo objekto tipą. 3 sąrašas pateikia pavyzdį.

Sąrašas 3. Objekto klonavimas

viešoji klasė „CloneDemo“ įgyvendina „Cloneable“ {int x; public static void main (String [] args) meta CloneNotSupportedException {CloneDemo cd = new CloneDemo (); cdx = 5; System.out.printf ("cd.x =% d% n", cd.x); CloneDemo cd2 = (CloneDemo) cd. klonas (); System.out.printf ("cd2.x =% d% n", cd2.x); }}

3 sąraše skelbiama a „CloneDemo“ klasė, kuri įgyvendina Klonuojamas sąsaja. Ši sąsaja turi būti įdiegta arba iškviesta Objektas's klonas () metodas lems mesti CloneNotSupportedException instancija.

„CloneDemo“ deklaruoja vienintelį tarptpavadintas egzemplioriaus laukas x ir a pagrindinis () metodas, pratęsiantis šią klasę. pagrindinis () yra deklaruojamas su metimo sąlyga, kuri praeina CloneNotSupportedException pakelti metodo skambučio kaminą.

pagrindinis () pirmiausia akimirksniu „CloneDemo“ ir inicijuoja gautos egzemplioriaus kopiją x į 5. Tada jis išleidžia egzempliorius x vertę ir remiasi klonas () šiuo atveju grąžinamo objekto liejimas į „CloneDemo“ prieš saugodamas nuorodą. Galiausiai, jis išleidžia klono x lauko vertė.

Sudaryti 3 sąrašą (javac CloneDemo.java) ir paleiskite programą (java CloneDemo). Turėtumėte stebėti šį rezultatą:

cd.x = 5 cd2.x = 5

Klausimas: Kodėl turėčiau nepaisyti klonas () metodas?

A: Ankstesniam pavyzdžiui nereikėjo nepaisyti klonas () metodas, nes kodas, kuris iškviečia klonas () yra klonuojamoje klasėje (t. y „CloneDemo“ klasė). Tačiau jei klonas () iškvietimas yra kitoje klasėje, turėsite nepaisyti klonas (). Priešingu atveju gausite „klonas apsaugojo prieigą objekte"pranešimas, nes klonas () yra deklaruojamas saugomi. 4 sąraše pateikiamas atnaujintas 3 sąrašas, siekiant parodyti svarbesnį klonas ().

Sąrašas 4. Klonuoti objektą iš kitos klasės

klasės duomenys įgyvendinami Cloneable {int x; @Override public Object clone () meta CloneNotSupportedException {return super.clone (); }} public class CloneDemo {public static void main (String [] args) meta CloneNotSupportedException {Data data = new Data (); duomenys.x = 5; System.out.printf ("duomenys.x =% d% n", duomenys.x); Duomenų duomenys2 = (Duomenys) duomenys.klonas (); System.out.printf ("duomenys2.x =% d% n", duomenys2.x); }}

4 sąraše skelbiama a Duomenys klasės, kurios egzemplioriai turi būti klonuojami. Ši klasė įgyvendina Klonuojamas sąsaja užkirsti kelią CloneNotSupportedException nuo metimo, kai klonas () metodas vadinamas, deklaruoja tarptpagrįstas egzemplioriaus laukas xir nepaiso klonas () metodas. Šis metodas vykdomas super.klonas () pasinaudoti savo superklasės (Objektasšiame pavyzdyje) klonas () metodas. Svarbiausia klonas () metodas identifikuoja CloneNotSupportedException savo metimų sąlyga.

4 sąraše taip pat skelbiama a „CloneDemo“ klasė, kuri momentuoja Duomenys, inicializuoja jo egzemplioriaus lauką, pateikia šio egzemplioriaus lauko vertę, klonuoja Duomenys egzempliorių ir pateikia šio egzemplioriaus lauko reikšmę.

Sudaryti 4 sąrašą (javac CloneDemo.java) ir paleiskite programą (java CloneDemo). Turėtumėte stebėti šį rezultatą:

duomenys.x = 5 duomenys2.x = 5

Klausimas: Kas yra negilus klonavimas?

A:Negilus klonavimas (taip pat žinomas kaip seklus kopijavimas) yra objekto laukų kopija, nedubliuojant jokių objektų, į kuriuos yra nuoroda iš objekto nuorodų laukų (jei tokių yra). 3 ir 4 sąrašai rodo seklų klonavimą. Kiekvienas iš cd-, cd2-, duomenis- ir duomenys2nurodomi laukai identifikuoja objektą, kuris turi savo tarpt-pagrįstas x srityje.

Negilus klonavimas veikia gerai, kai visi laukai yra primityvaus tipo ir (daugeliu atvejų), kai nurodomi bet kurie nuorodų laukai nekintamas (nekeičiami) objektai. Tačiau, jei kuris nors nurodytas objektas yra kintamas, bet kurio iš šių objektų pakeitimus gali pamatyti originalus objektas ir jo klonas (-ai). 5 sąraše pateikiama demonstracija.

Sąrašas 5. Sekliojo klonavimo problemos parodymas atskaitos lauko kontekste

klasė Darbuotojas įgyvendina Cloneable {private String name; privatus int amžius; asmeninis adreso adresas; Darbuotojas (eilutės pavadinimas, int amžius, adreso adresas) {this.name = vardas; tai. amžius = amžius; tai.adresas = adresas; } @Paisyti viešojo objekto kloną () meta CloneNotSupportedException {return super.clone (); } Adresas getAddress () {grąžinimo adresas; } String getName () {grąžinimo vardas; } int getAge () {grįžimo amžius; }} klasės adresas {private String city; Adresas (styginis miestas) {this.city = miestas; } String getCity () {grįžimo miestas; } void setCity (Styginių miestas) {this.city = miestas; }} public class CloneDemo {public static void main (String [] args) meta CloneNotSupportedException {Employee e = naujas darbuotojas ("John Doe", 49, naujas adresas ("Denver")); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); Darbuotojas e2 = (Darbuotojas) e.klonas (); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); e.getAddress (). setCity („Čikaga“); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); }}

Išvardijamos 5 dovanos Darbuotojas, Adresasir „CloneDemo“ klasės. Darbuotojas pareiškia vardas, amžiausir adresas laukai; ir yra klonuojamas. Adresas deklaruoja adresą, susidedantį iš miesto, o jo egzemplioriai yra kintami. „CloneDemo“ varo programą.

„CloneDemo“'s pagrindinis () metodas sukuria Darbuotojas objektą ir klonuoja šį objektą. Tada jis keičia miesto pavadinimą originalu Darbuotojas objekto adresas srityje. Nes abu Darbuotojas objektai nurodo tą patį Adresas objektą, pakeistą miestą mato abu objektai.

Sudaryti 5 sąrašą (javac CloneDemo.java) ir paleiskite šią programą (java CloneDemo). Turėtumėte stebėti šį rezultatą:

John Doe: 49: Denveris John Doe: 49: Denveris John Doe: 49: Chicago John Doe: 49: Chicago

Klausimas: Kas yra gilus klonavimas?

A:Gilus klonavimas (taip pat žinomas kaip gilus kopijavimas) yra objekto laukų dublikatas, kad visi nurodyti objektai būtų dubliuojami. Be to, jų nurodyti objektai yra dubliuojami ir pan. Pavyzdžiui, 6 refaktorių sąrašas „5“ sąrašas, skirtas giliam klonavimui. Tai taip pat parodo kovariantinius grąžinimo tipus ir lankstesnį klonavimo būdą.

Sąrašas 6. Gilus klonavimas adresas srityje

klasė Darbuotojas įgyvendina Cloneable {private String name; privatus int amžius; asmeninis adreso adresas; Darbuotojas (eilutės pavadinimas, int amžius, adreso adresas) {this.name = vardas; tai. amžius = amžius; tai.adresas = adresas; } @Paisyti viešąjį darbuotojų kloną () išmeta CloneNotSupportedException {Darbuotojo e = (Darbuotojas) super.klonas (); el. adresas = adresas.klonas (); grįžti e; } Adresas getAddress () {grąžinimo adresas; } String getName () {grąžinimo vardas; } int getAge () {grįžimo amžius; }} klasės adresas {private String city; Adresas (styginis miestas) {this.city = miestas; } @Paisyti viešojo adreso kloną () {grąžinti naują adresą (nauja eilutė (miestas)); } String getCity () {grįžimo miestas; } void setCity (Styginių miestas) {this.city = miestas; }} public class CloneDemo {public static void main (String [] args) meta CloneNotSupportedException {Employee e = naujas darbuotojas ("John Doe", 49, naujas adresas ("Denver")); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); Darbuotojas e2 = (Darbuotojas) e.klonas (); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); e.getAddress (). setCity („Čikaga“); System.out.printf ("% s:% d:% s% n", e.getName (), e.getAge (), e.getAddress (). GetCity ()); System.out.printf ("% s:% d:% s% n", e2.getName (), e2.getAge (), e2.getAddress (). GetCity ()); }}

6 sąrašas išnaudoja „Java“ paramą kovariantiniams grąžinimo tipams, kad pakeistų grąžinimo tipą Darbuotojasyra svarbesnis klonas () metodas nuo Objektas į Darbuotojas. Privalumas yra tas, kad kodas yra išorinis Darbuotojas gali klonuoti Darbuotojas objekto nereikia mesti šio objekto į Darbuotojas tipo.

Darbuotojas's klonas () metodas pirmiausia remiasi super.klonas (), kuris negiliai kopijuoja vardas, amžiausir adresas laukai. Tada jis pasikviečia klonas () ant adresas lauką, kad padarytumėte nuorodos kopiją Adresas objektas.

Adresas klasė nepaiso klonas () metodas ir atskleidžia keletą skirtumų nuo ankstesnių klasių, kurios nepaiso šio metodo:

  • Adresas neįgyvendina Klonuojamas. Tai nėra būtina, nes tik Objektas's klonas () metodas reikalauja, kad klasė įdiegtų šią sąsają, ir tai klonas () metodas nėra vadinamas.
  • Svarbiausia klonas () metodas nemeta CloneNotSupportedException. Ši pažymėta išimtis pateikiama tik iš Objektas's klonas () metodas, kuris nėra vadinamas. Todėl išimtis neturi būti tvarkoma arba perkeliama į metod-call kaminą per metimo sąlygą.
  • Objektas's klonas () metodas nėra vadinamas (nėra super.klonas () skambinti), nes sekti kopijuoti nereikia Adresas klasė - yra tik vienas laukas, kurį reikia nukopijuoti.

Klonuoti Adresas objekto, pakanka sukurti naują Adresas objektą ir inicializuokite jį į objekto, į kurį nurodoma, kopiją miestas srityje. Nauja Adresas objektas grąžinamas.