overriding predefined methods java
Tento výukový program vysvětluje, jak v Javě přepsat předdefinované metody jako equals (), hashCode (), compareTo () atd.:
V našem předchozím tutoriálu jsme diskutovali o runtime polymorfismu v Javě. Runtime polymorfismus v Javě je implementován pomocí přepsání metody. Přepsání metody zahrnuje předefinování metody nadřazené třídy v podtřídě.
Java má různé předdefinované metody, jako jsou equals (), hashCode (), compareTo (), toString () atd., Které se běžně používají pro obecné objekty bez ohledu na to, do které třídy patří. Aby ale tyto metody fungovaly pro všechny objekty, musíme tyto metody přepsat nebo předefinovat jejich implementace, aby mohly pracovat s daty, která chceme.
=> Navštivte zde a dozvíte se Java od začátku.
V tomto kurzu probereme přepsání všech těchto metod spolu s důsledky, pokud tyto metody nepřepíšeme.
Co se naučíte:
- Přepsat metody equals () a hashCode () v Javě
- Přepsání statické metody v Javě
- Přepsání porovnáníTo () v Javě
- Přepsat metodu toString () v Javě
- Často kladené otázky
- Závěr
- Doporučené čtení
Přepsat metody equals () a hashCode () v Javě
V Javě používáme metodu equals () k porovnání dvou objektů. Tato metoda vrací true, když jsou objekty stejné, a false, pokud nejsou stejné.
K porovnání rovnosti dvou objektů se používají dva způsoby.
nejlepší software pro obnovu souborů Windows 10
# 1) Mělké srovnání
Mělké porovnání je výchozí implementací pro metodu equals () definovanou ve třídě „java.lang.Object“. Jako součást této implementace metoda equals () zkontroluje, zda dva porovnávané objekty mají odkazy odkazující na stejný objekt.
To znamená, že pokud obj1 a obj2 jsou dva objekty, pak výchozí implementace metody equals () (mělké srovnání) zkontroluje pouze to, zda jsou odkazy na obj1 a obj2 ze stejného objektu.
V mělkém srovnání se nesrovnává žádný obsah dat.
# 2) Hluboké srovnání
V hlubokém srovnání porovnáváme datové členy každého objektu, tj. Objekty jsou porovnávány s ohledem na stav. Porovnáváme tedy objekty na hluboké úrovni včetně jejich obsahu.
Pro porovnání objektů pomocí hlubokého srovnání obvykle přepíšeme metodu equals ().
Nyní zvažte následující 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ýstup:
Pokud vidíme výstup výše uvedeného programu, říká, že objekty nejsou stejné, i když je obsah těchto dvou objektů stejný. Důvodem je, že při kontrole rovnosti se určuje, zda dva objekty c1 a c2 odkazují na stejný objekt.
Jak je vidět v programu, c1 a c2 jsou dva různé objekty, takže se jedná o různé reference, a proto je výsledkem.
Nyní vytvořme třetí odkaz c3 a srovnejme jej s c1 následujícím způsobem:
Komplex c3 = cl;
V tomto případě budou c3 a c1 odkazovat na stejný objekt, a proto (c3 == c1) vrátí hodnotu true.
Výše uvedený program udělal jen povrchní srovnání. Jak tedy zkontrolujeme, zda jsou dva objekty obsahově stejné?
Zde přejdeme k hlubokému srovnání a za tímto účelem přepíšeme metodu equals ().
Následující program ukazuje přepsání metody equals (). Používáme stejnou třídu Complex.
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ýstup:
Nyní, když máme metodu overridden equals (), když porovnáme dva objekty, výstup ukazuje, že dva objekty jsou stejné, protože jejich obsah je stejný. Všimněte si přepsané metody equals (). Zde zkontrolujeme, zda mají oba objekty stejnou referenci. Pokud ne, pak jednotlivě zkontrolujeme obsah těchto objektů.
Kdykoli v Javě přepíšeme metodu equals (), je vhodné přepsat také metodu hashCode (). Je to proto, že pokud nepřepíšeme metodu hashCode (), pak může mít každý objekt jiný hashCode.
To nemusí zasahovat do obecných objektů, ale některé kolekce založené na hash jako HashTable, HashSet a HashMap nemusí fungovat správně.
Následující program ukazuje přepsání metod 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ýstup:
V tomto programu používáme hashMap. Přepsali jsme metody equals () i hashCode (). Takže když řekneme map.put (e1, „C ++“), hashuje to do nějakého umístění kbelíku. Dále voláme map.put (e2, „Python“). Tentokrát bude hash do stejného kbelíku a nahradí předchozí hodnotu. Je to proto, že jsme přepsali metodu hashCode ().
Přepsání statické metody v Javě
Můžeme přepsat statickou metodu v Javě?
Pokud jde o přepsání statické metody v Javě, přímá odpověď na tuto otázku je Ne, nemůžeme přepsat statickou metodu.
Statická metoda je vyvolána pomocí samotného názvu třídy. K volání statické metody nepotřebujeme objekt. Takže i když deklarujeme metodu se stejným prototypem v podtřídě, nemůžeme ji nazvat přepsáním. Místo toho pouze skrýváme definici nadřazené třídy statické metody.
Následující program Java ukazuje statickou metodu a nestatickou metodu v dědickém systému spolu s jejich chováním za běhu.
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ýstup:
Z výstupu programu můžeme uzavřít následující.
- Volání statické metody se vždy provádí na základě typu odkazu. Proto, když jsme volali new_obj. display () ve výše uvedeném programu, protože odkaz new_obj má typovou třídu Parent, nazývá se metoda display () rodičovské třídy.
- Na druhou stranu jsou nestatické metody volány na základě obsahu referenčního objektu, kterým je metoda volána. Proto ve výše uvedeném programu volá metoda new_obj.print () metodu print () podřízené třídy, protože obsah new_obj je předmětem podřízené třídy.
To vysvětluje výstup výše uvedeného programu a při práci se statickými metodami v systému OOP si musíme pamatovat také následující body.
- Statická metoda nemůže skrýt nestatickou metodu instance a metoda nestatické instance nemůže přepsat statickou metodu.
- Můžeme přetížit metody z nadřazené třídy v podtřídě, ale ani nepřepíší, ani skryjí metody nadřazené třídy, jsou to nové metody v podtřídě.
Přepsání porovnáníTo () v Javě
Víme, že rozhraní java.lang.Comparable poskytuje metodu ‚compareTo () ', pomocí které můžeme třídit objekty v přirozeném pořadí, jako je lexikální pořadí pro řetězce, číselné pořadí pro celá čísla atd.
Chcete-li implementovat třídění v uživatelsky definovaných objektech nebo kolekcích, musíme přepsat metodu compareTo (), která seřadí prvky kolekce nebo objekty definované uživatelem.
Co tedy dělá metoda compareTo ()?
Metoda compareTo () musí vrátit kladnou hodnotu, pokud je aktuální objekt větší než předaný objekt v pořadí a záporná hodnota aktuálního objektu je menší než předaný objekt. Pokud jsou oba objekty stejné, vrátí metoda compareTo () nulu.
Dalším bodem, který je třeba poznamenat, je, že metoda equals () a compareTo () by se měla chovat konzistentně navzájem. To znamená, že pokud metoda compareTo () vrátí, že dva objekty jsou stejné (vrátí nulu), měli bychom mít stejný výstup také z metody equals ().
Pojďme implementovat program Java, který přepíše metodu compareTo (). V tomto programu používáme třídu Color, která má dvě soukromé proměnné, tj. Jméno a id. S každou barvou jsme spojili „id“ a přepíšeme metodu compare (), abychom uspořádali barvy podle 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ýstup:
Ve výše uvedeném výstupu nejprve zobrazíme seznam barev a poté seřazený seznam barev. V programu jsme přepsali metody compareTo () a compare ().
Přepsat metodu toString () v Javě
Metoda ‚toString () 'vrací Stringovou reprezentaci objektu v Javě. Ale když máme objekty definované uživatelem, pak se tato metoda může chovat jinak.
Například,zvažte následující 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ýstup:
Jak je znázorněno v tomto programu, zobrazujeme objekt třídy Complex, který jsme definovali dříve. Zobrazený výstup však není obsah, ale je poněkud záhadný.
Výstup ukazuje název třídy Complex následovaný znakem @ a poté hashCode objektu. Toto je výchozí výstup vytištěný metodou toString () třídy Object.
Pokud chceme správný výstup, musíme v naší aplikaci přepsat metodu toString ().
Následující program Java ukazuje, jak přepsat metodu toString () pro tisk 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ýstup:
Výše uvedený program ukazuje, že metoda toString () je přepsána, aby vrátila obsah komplexního objektu v daném formátu (real + i * imaginární).
Obecně platí, že když chceme objekt třídy zobrazit pomocí print () nebo println (), je vždy vhodné přepsat metodu toString (), abychom získali správný výstup.
Často kladené otázky
Otázka č. 1) Proč používat .equals místo == Java?
pl / sql rozhovor otázky a odpovědi
Odpovědět: Používáme „==“ k porovnání primitivních typů jako int, char, boolean atd. K porovnání objektů (předdefinovaných nebo definovaných uživatelem) používáme equals (). Obvykle přepíšeme metodu equals (), abychom porovnali dva objekty, a návratová hodnota equals () závisí na přepsaném kódu.
Otázka č. 2) Na co se používá hashCode () a equals ()?
Odpovědět: V Javě se metoda equals () používá k porovnání rovnosti dvou objektů. Metoda hashCode () vrací hashCode objektu. Zatímco metoda equals () se používá u většiny objektů k testování jejich rovnosti, hashCode se většinou používá v hash kolekcích jako HashTable, HashMap, HashSet atd.
Otázka č. 3) Můžeme změnit seznam argumentů přepsané metody?
Odpovědět: Ne. Když přepíšeme metodu, ponecháme podpis metody nebo prototyp metody stejný i v podtřídě. Takže nemůžeme změnit počet parametrů v přepsané metodě.
Otázka č. 4) Proč přepíšeme toString ()?
Odpovědět: Když je metoda toString () přepsána, můžeme vrátit hodnoty objektu, pro který je metoda toString () přepsána, aniž bychom museli psát příliš mnoho kódu. Je to proto, že kompilátor Java vyvolá metodu toString (), když tiskneme objekt.
Otázka č. 5) Co by se stalo, pokud metodu toString () nepotlačíte?
Odpovědět: Pokud metodu toString () nepřepíšeme, nedostaneme žádné informace o vlastnostech nebo stavu objektu. Nebudeme vědět, co je ve skutečnosti uvnitř objektu. Všechny třídy by tedy měly přepsat metodu toString ().
Je to proto, že výchozí implementace metody toString () zobrazuje String reprezentaci, ale když použijeme výchozí implementaci toString () na objekt, nedostaneme obsah objektu.
Závěr
V tomto kurzu jsme diskutovali o přepsání několika předdefinovaných metod Java a také jsme viděli, proč je musíme přepsat.
Když se zabýváme objekty, výchozí implementace metod jako equals (), compareTo () a toString () nemusí poskytovat správné informace. Proto jdeme na přepsání.
=> Prohlédněte si příručku Java Beginners Guide zde.
Doporučené čtení
- Výukový program Java String | Metody řetězců Java s příklady
- Java vlákna s metodami a životním cyklem
- Metoda Java String length () S příklady
- Obrátit pole v Javě - 3 metody s příklady
- Jak používat metodu Java toString?
- Java String indexOf metoda s příklady kódu
- Java String obsahuje () Výukový program metod s příklady
- Metoda Java String Split () - Jak rozdělit řetězec v Javě