overriding predefined methods java
Tento tutoriál vysvetľuje, ako v Java prepísať preddefinované metódy ako equals (), hashCode (), compareTo () atď.:
V našom predchádzajúcom tutoriáli sme diskutovali o runtime polymorfizme v Jave. Runtime polymorfizmus v Jave je implementovaný pomocou prepísania metódy. Prepísanie metódy zahŕňa predefinovanie metódy nadradenej triedy v podtriede.
Java má rôzne preddefinované metódy ako equals (), hashCode (), compareTo (), toString () atď., Ktoré sa bežne používajú pre všeobecné objekty bez ohľadu na to, do ktorej triedy patria. Ale aby tieto metódy fungovali pre všetky objekty, musíme tieto metódy prepísať alebo predefinovať ich implementácie, aby mohli pracovať s údajmi, ktoré chceme.
=> Navštívte tu a dozviete sa Java od začiatku.
V tomto výučbe sa budeme zaoberať prepísaním všetkých týchto metód spolu s následkami, ak tieto metódy neprepíšeme.
Čo sa dozviete:
- Prepísanie metód equals () a hashCode () v Jave
- Prekonanie statickej metódy v prostredí Java
- Prekonanie porovnávania () v Jave
- Metóda override toString () v Jave
- často kladené otázky
- Záver
- Odporúčané čítanie
Prepísanie metód equals () a hashCode () v Jave
V Jave používame metódu equals () na porovnanie dvoch objektov. Táto metóda vracia hodnotu true, keď sú objekty rovnaké, a hodnotu false, ak nie sú rovnaké.
Na porovnanie rovnosti dvoch objektov sa používajú dva spôsoby.
najlepší softvér na klonovanie hdd na ssd
# 1) Plytké porovnanie
Plytké porovnanie je predvolenou implementáciou metódy equals () definovanej v triede „java.lang.Object“. V rámci tejto implementácie metóda equals () skontroluje, či majú dva porovnávané objekty odkazy odkazujúce na rovnaký objekt.
To znamená, že ak sú obj1 a obj2 dva objekty, potom predvolená implementácia metódy equals () (plytké porovnanie) skontroluje iba to, či odkazy obj1 a obj2 pochádzajú z rovnakého objektu.
V povrchnom porovnaní sa neporovnávajú žiadne údaje.
# 2) Hlboké porovnanie
V hlbokom porovnaní porovnávame dátové členy každého objektu, t. J. Objekty sa porovnávajú s ohľadom na stav. Takže porovnávame objekty na hlbokej úrovni vrátane ich obsahu.
Na porovnanie objektov pomocou hlbokého porovnania obvykle prepíšeme metódu equals ().
Teraz zvážte nasledujúci program Java.
class Complex { private double r, i; //declare real and imaginary component as private public Complex(double r, double i) { //constructor this.r = r; this.i = i; } } public class Main { public static void main(String() args) { Complex c1 = new Complex(5, 10); //c1 object Complex c2 = new Complex(5, 10); //c2 object if (c1 == c2) { System.out.println('Two Complex objects are Equal '); } else { System.out.println('Two Complex objects are not Equal '); } } }
Výkon:
Ak vidíme výstup vyššie uvedeného programu, hovorí sa, že objekty nie sú rovnaké, aj keď je obsah týchto dvoch objektov rovnaký. Je to tak preto, lebo pri kontrole rovnosti sa určuje, či dva objekty c1 a c2 odkazujú na rovnaký objekt.
Ako je vidieť v programe c1 a c2, sú to dva rôzne objekty, takže ide o odlišné referencie, a tým je výsledkom.
Teraz vytvoríme tretiu referenciu c3 a prirovnáme ju k c1 nasledovne:
Komplex c3 = cl;
V takom prípade budú c3 a c1 odkazovať na rovnaký objekt, a preto (c3 == c1) vráti hodnotu true.
Vyššie uvedený program urobil len povrchné porovnanie. Ako teda zistíme, či sú dva objekty rovnaké z hľadiska obsahu?
Tu ideme do hlbokého porovnania a za týmto účelom prepíšeme metódu equals ().
Nasledujúci program ukazuje prepísanie metódy equals (). Používame rovnakú komplexnú triedu.
class Complex { private double r, i; public Complex(double r, double i) { this.r = r; this.i = i; } // override equals () method to compare two complex objects @Override public boolean equals(Object obj) { // returns true=>object is compared to itself if (obj == this) { return true; } //return false if obj is not an instance of Complex class if (!(obj instanceof Complex)) { return false; } // typecast obj to Complex type Complex c = (Complex) obj; // Compare the contents of two objects and return value return Double.compare(r, c.r) == 0 && Double.compare(i, c.i) == 0; } } public class Main { public static void main(String() args) { Complex c1 = new Complex(5, 10); Complex c2 = new Complex(5, 10); if (c1.equals(c2)) { System.out.println('Complex objects c1 and c2 are Equal '); } else { System.out.println('Complex objects c1 and c2 are not Equal '); } } }
Výkon:
aplikácia pre špehovanie telefónov s Androidom
Teraz, keď máme metódu overridden equals (), keď porovnávame dva objekty, výstup ukazuje, že dva objekty sú rovnaké, pretože ich obsah je rovnaký. Všimnite si metódu overridden equals (). Tu skontrolujeme, či majú oba objekty rovnakú referenciu. Pokiaľ nie, potom obsah týchto objektov individuálne skontrolujeme.
V Jave je vhodné kedykoľvek prepísať metódu equals (), a tiež metódu hashCode (). Je to tak preto, lebo ak neprepíšeme metódu hashCode (), potom môže mať každý objekt iný hashCode.
Toto nemusí zasahovať do všeobecných objektov, ale niektoré kolekcie založené na hashe, ako je HashTable, HashSet a HashMap, nemusia fungovať správne.
Nasledujúci program zobrazuje prepísané metódy equals () a hashCode ().
import java.io.*; import java.util.*; class EqualsHashCode { String name; int id; EqualsHashCode(String name, int id) { this.name = name; this.id = id; } @Override public boolean equals(Object obj) @Override public int hashCode() { // return current object's id as hashCode return this.id; } } class Main { public static void main (String() args) { // create two objects with same state EqualsHashCode e1 = new EqualsHashCode('Java', 1); EqualsHashCode e2 = new EqualsHashCode('Java', 1); //update the objects Map map = new HashMap(); map.put(e1, 'C++'); map.put(e2, 'Python'); //display contents for(EqualsHashCode eh : map.keySet()) { System.out.println(map.get(eh).toString()); } } }
Výkon:
V tomto programe používame hashMap. Prepísali sme metódy equals () aj hashCode (). Takže keď povieme map.put (e1, „C ++“), hashuje sa do nejakého umiestnenia segmentu. Ďalej voláme map.put (e2, „Python“). Tentokrát bude hash do rovnakého segmentu a nahradí predchádzajúcu hodnotu. Je to tak preto, lebo sme prepísali metódu hashCode ().
Prekonanie statickej metódy v prostredí Java
Môžeme prepísať statickú metódu v Jave?
Pokiaľ ide o prepísanie statickej metódy v Jave, priama odpoveď na túto otázku je Nie, nemôžeme prepísať statickú metódu.
Statická metóda sa vyvoláva pomocou samotného názvu triedy. Na volanie statickej metódy nepotrebujeme objekt. Takže aj keď deklarujeme metódu s rovnakým prototypom v podtriede, nemôžeme ju nazvať prepracovanou. Namiesto toho iba skrývame definíciu rodičovskej triedy statickej metódy.
Nasledujúci program Java zobrazuje statickú metódu a nestatickú metódu v dedičskom systéme spolu s ich správaním za behu programu.
class Parent { // Parent class static method cannot be overridden by Child public static void display() { System.out.println('Parent class::static display()'); } // parent class non-static print method to be overridden by Child public void print() { System.out.println('Parent class::non-static print()'); } } // Subclass class Child extends Parent { // static display() method =>hides display() in Parent class public static void display() { System.out.println('Child class:: static display()'); } //overrides print() in Parent class public void print() { System.out.println('Child class::Non-static print()'); } } public class Main { public static void main(String args( )) { Parent new_obj = new Child(); // static methods are call as per the reference type. Since reference type //Parent, this call will execute Parent class's display method new_obj.display(); // here the print () method of Child class is called new_obj.print(); } }
Výkon:
Z výstupu programu môžeme vyvodiť záver.
- Volanie statickej metódy sa vždy uskutočňuje na základe typu referencie. Preto, keď sme volali new_obj. display () vo vyššie uvedenom programe, pretože odkaz new_obj má typovú triedu Parent, volá sa metóda display () nadradenej triedy.
- Na druhej strane sa volajú nestatické metódy na základe obsahu referenčného objektu, s ktorým sa metóda volá. Preto vo vyššie uvedenom programe metóda new_obj.print () volá metódu print () podradenej triedy, pretože obsah new_obj je predmetom podradenej triedy.
To vysvetľuje výstup vyššie uvedeného programu a pri práci so statickými metódami v systéme OOP si musíme pamätať tiež nasledujúce body.
- Statická metóda nemôže skryť nestatickú metódu inštancie a metóda nestatickej inštancie nemôže prepísať statickú metódu.
- Môžeme preťažiť metódy z nadradenej triedy v podtriede, ale ani neprekonajú, ani neskryjú metódy nadradenej triedy, sú to v podtriede nové metódy.
Prekonanie porovnávania () v Jave
Vieme, že rozhranie java.lang.Comparable poskytuje metódu ‘compareTo ()‘, pomocou ktorej môžeme triediť objekty v prirodzenom poradí, ako je lexikálne poradie pre reťazcové objekty, číselné poradie pre celé čísla atď.
Ak chcete implementovať triedenie v používateľom definovaných objektoch alebo zbierkach, musíme prepísať metódu compareTo (), aby sa zoradili prvky kolekcie alebo objekty definované používateľom.
Čo teda robí metóda compareTo ()?
Metóda compareTo () musí vrátiť kladnú hodnotu, ak je aktuálny objekt väčší ako odovzdaný objekt v poradí a záporná hodnota aktuálneho objektu je menšia ako odovzdaný objekt. Ak sú obidva objekty rovnaké, potom metóda compareTo () vráti nulu.
Ďalším bodom, ktorý je potrebné poznamenať, je, že metóda equals () a compareTo () by sa mala správať navzájom konzistentne. To znamená, že ak metóda compareTo () vráti, že dva objekty sú si rovné (vráti nulu), mali by sme mať rovnaký výstup aj z metódy equals ().
Poďme implementovať program Java, ktorý prepíše metódu compareTo (). V tomto programe používame triedu Color, ktorá má dve súkromné premenné, tj. Meno a id. S každou farbou sme spojili ‘id’ a prepíšeme metódu compare (), aby sme usporiadali farby podľa id.
import java.util.*; //color class class Color implements Comparator, Comparable { private String name; private int id; Color() { } Color(String n, int id) { this.name = n; this.id = id; } public String getColorName() { return this.name; } public int getColorId() { return this.id; } // Overriding the compareTo method @Override public int compareTo(Color c) { return (this.name).compareTo(c.name); } // Overriding the compare method to sort the colors on id @Override public int compare(Color c, Color c1) { return c.id - c1.id; } } public class Main { public static void main(String args()) { // List of Colors List list = new ArrayList(); list.add(new Color('Red', 3)); list.add(new Color('Green', 2)); list.add(new Color('Blue', 5)); list.add(new Color('Orange', 4)); list.add(new Color('Yellow', 1)); Collections.sort(list); // Sorts the array list System.out.println('The list of colors:'); for(Color c: list) // print the sorted list of colors System.out.print(c.getColorName() + ', '); // Sort the array list using comparator Collections.sort(list, new Color()); System.out.println(' '); System.out.println('The sorted list of colors:'); for(Color c: list) // print the sorted list of colors as per id System.out.print(c.getColorId() + ':' + c.getColorName() + ' , '); }
Výkon:
Vo vyššie uvedenom výstupe najskôr zobrazíme zoznam farieb a potom zoradený zoznam farieb. V programe sme prepísali metódy compareTo () a compare ().
Metóda override toString () v Jave
Metóda „toString ()“ vráti reťazcovú reprezentáciu objektu v Jave. Ale keď máme objekty definované používateľom, potom sa táto metóda môže správať inak.
Napríklad,zvážte nasledujúci program.
class Complex { private double r, i; public Complex(double r, double i) { this.r = r; this.i = i; } } public class Main { public static void main(String() args) { Complex c1 = new Complex(5, 20); //create complex class Object //print the contents of complex number System.out.println('Complex number contents: ' + c1); } }
Výkon:
Ako je znázornené v tomto programe, zobrazujeme objekt triedy Complex, ktorý sme už definovali. Zobrazený výstup však nie je obsahom, ale je skôr záhadný.
Výstup zobrazuje názov triedy Complex, za ktorým nasleduje znak „@“ a potom hashCode objektu. Toto je predvolený výstup vytlačený metódou toString () triedy Object.
Ak chceme správny výstup, musíme v našej aplikácii prepísať metódu toString ().
Nasledujúci program Java ukazuje, ako prepísať metódu toString () na tlač obsahu komplexného objektu.
class Complex { private double r, i; public Complex(double r, double i) { this.r = r; this.i = i; } //override toString () method to return String representation of complex number @Override public String toString() { return String.format(r + ' + i ' + i); } } public class Main { public static void main(String() args) { Complex c1 = new Complex(10, 15); System.out.println('Complex Number contents: ' + c1); } }
Výkon:
Vyššie uvedený program ukazuje, že metóda toString () je prepísaná, aby vrátila obsah komplexného objektu v danom formáte (real + i * imaginárny).
Všeobecne platí, že ak chceme objekt triedy zobraziť pomocou print () alebo println (), je vždy vhodné prepísať metódu toString (), aby sme dosiahli správny výstup.
často kladené otázky
Otázka 1) Prečo používať .equals namiesto == Java?
videá na pozeranie s náhlavnou súpravou vr
Odpoveď: Použijeme „==“ na porovnanie primitívnych typov ako int, char, boolean atď. Na porovnanie objektov (preddefinovaných alebo používateľom definovaných) používame equals (). Metódu equals () zvyčajne prepíšeme, aby sme porovnali dva objekty, a návratová hodnota metódy equals () závisí od prepísaného kódu.
Otázka 2) Na čo sa používa hashCode () a equals ()?
Odpoveď: V Jave sa na porovnanie rovnosti dvoch objektov používa metóda equals (). Metóda hashCode () vracia hashCode objektu. Zatiaľ čo metóda equals () sa používa u väčšiny objektov na testovanie ich rovnosti, hashCode sa väčšinou používa v hash zbierkach ako HashTable, HashMap, HashSet atď.
Otázka č. 3) Môžeme zmeniť zoznam argumentov prepísanej metódy?
Odpoveď: Nie. Keď prepíšeme metódu, ponecháme rovnaký podpis metódy alebo prototyp metódy aj v podtriede. Takže nemôžeme zmeniť počet parametrov v prepísanej metóde.
Otázka č. 4) Prečo prepíšeme toString ()?
Odpoveď: Keď je prepísaná metóda toString (), môžeme vrátiť hodnoty objektu, pre ktorý je prepísaná metóda toString (), bez toho, aby sme napísali príliš veľa kódu. Je to tak preto, lebo kompilátor javy vyvoláva pri tlači objektu metódu toString ().
Otázka č. 5) Čo by sa stalo, keby ste neprepísali metódu toString ()?
Odpoveď: Pokiaľ metódu toString () neprepíšeme, nedostaneme žiadne informácie o vlastnostiach alebo stave objektu. Nebudeme vedieť, čo sa v skutočnosti nachádza vo vnútri objektu. Všetky triedy by teda mali prepísať metódu toString ().
Je to preto, že predvolená implementácia metódy toString () zobrazuje String reprezentáciu, ale keď na objekt použijeme predvolenú implementáciu toString (), nedostaneme obsah objektu.
Záver
V tomto tutoriáli sme diskutovali o prepísaní niekoľkých preddefinovaných metód Java a tiež sme videli, prečo ich musíme prepísať.
Keď pracujeme s objektmi, predvolené implementácie metód ako equals (), compareTo () a toString () nemusia poskytovať správne informácie. Preto ideme na vynútenie.
=> Tu si pozrite príručku Java Beginners Guide.
Odporúčané čítanie
- Výukový program pre Java String Metódy reťazca Java s príkladmi
- Vlákna Java s metódami a životným cyklom
- Metóda Java String length () s príkladmi
- Obrátiť pole v prostredí Java - 3 metódy s príkladmi
- Ako používať metódu Java toString?
- Metóda Java String indexOf s príkladmi kódu
- Java String obsahuje () Výukový program metód s príkladmi
- Metóda Java String Split () - Ako rozdeliť reťazec v Jave