overriding predefined methods java
Questo tutorial spiega come sovrascrivere metodi predefiniti come equals (), hashCode (), compareTo (), ecc. In Java con esempi:
come usare un file jar
Nel nostro precedente tutorial, abbiamo discusso del polimorfismo di runtime in Java. Il polimorfismo di runtime in Java viene implementato utilizzando l'override del metodo. La sostituzione del metodo implica la ridefinizione del metodo della classe padre nella sottoclasse.
Java ha vari metodi predefiniti come equals (), hashCode (), compareTo (), toString (), ecc. Che vengono usati comunemente per oggetti generali indipendentemente dalla classe a cui appartengono. Ma affinché questi metodi funzionino per tutti gli oggetti, dobbiamo sovrascrivere questi metodi o ridefinirne le implementazioni in modo che possano lavorare con i dati desiderati.
=> Visita qui per imparare Java da zero.
In questo tutorial, discuteremo l'override di tutti questi metodi insieme alle conseguenze se non sovrascriviamo questi metodi.
Cosa imparerai:
- Sostituzione dei metodi equals () e hashCode () in Java
- Sostituzione del metodo statico in Java
- Sostituzione di compareTo () in Java
- Sostituisci il metodo toString () in Java
- Domande frequenti
- Conclusione
- Lettura consigliata
Sostituzione dei metodi equals () e hashCode () in Java
Usiamo il metodo equals () in Java per confrontare due oggetti. Questo metodo restituisce true quando gli oggetti sono uguali e false quando non sono uguali.
Vengono utilizzati due modi per confrontare l'uguaglianza di due oggetti.
# 1) Confronto superficiale
Il confronto superficiale è l'implementazione predefinita per il metodo equals () definito nella classe 'java.lang.Object'. Come parte di questa implementazione, il metodo equals () controllerà se due oggetti confrontati hanno riferimenti che si riferiscono allo stesso oggetto.
Ciò significa che se obj1 e obj2 sono due oggetti, l'implementazione predefinita del metodo equals () (confronto superficiale) controllerà solo se i riferimenti di obj1 e obj2 provengono dallo stesso oggetto.
In un confronto superficiale, non vengono confrontati i contenuti dei dati.
# 2) Confronto approfondito
In un confronto approfondito, confrontiamo i membri dei dati di ciascun oggetto, ovvero gli oggetti vengono confrontati rispetto allo stato. Quindi confrontiamo gli oggetti a un livello profondo, incluso il suo contenuto.
Per confrontare gli oggetti utilizzando il confronto profondo di solito sovrascriviamo il metodo equals ().
Consideriamo ora il seguente programma 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 '); } } }
Produzione:
Se vediamo l'output del programma sopra, dice che gli oggetti non sono uguali anche se i contenuti dei due oggetti sono gli stessi. Questo perché, quando viene verificata l'uguaglianza, si determina se i due oggetti c1 e c2 si riferiscono allo stesso oggetto.
Come si vede nel programma c1 e c2 sono due oggetti differenti, quindi sono riferimenti differenti e quindi risulta tale.
Ora creiamo un terzo riferimento c3 e lo identifichiamo a c1 come segue:
Complesso c3 = c1;
In questo caso, c3 e c1 faranno riferimento allo stesso oggetto e quindi (c3 == c1) restituirà true.
Quello che ha fatto il programma di cui sopra è stato il confronto superficiale. Quindi come controlliamo se due oggetti hanno lo stesso contenuto?
Qui, effettuiamo un confronto approfondito e, a tale scopo, sovrascriviamo il metodo equals ().
Il seguente programma mostra l'override del metodo equals (). Usiamo la stessa classe 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 '); } } }
Produzione:
Ora che abbiamo un metodo equals () sovrascritto, quando confrontiamo due oggetti, l'output mostra che i due oggetti sono uguali poiché il loro contenuto è lo stesso. Nota il metodo equals () sovrascritto. Qui controlliamo se entrambi gli oggetti hanno lo stesso riferimento. In caso contrario, controlliamo individualmente il contenuto di questi oggetti.
In Java, ogni volta che sovrascriviamo il metodo equals (), è consigliabile sovrascrivere anche il metodo hashCode (). Questo perché se non sovrascriviamo il metodo hashCode (), ogni oggetto potrebbe avere hashCode diverso.
Ciò potrebbe non interferire con gli oggetti generali, ma alcune raccolte basate su hash come HashTable, HashSet e HashMap potrebbero non funzionare correttamente.
Il seguente programma mostra i metodi equals () e hashCode () sovrascritti.
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()); } } }
Produzione:
In questo programma, usiamo una hashMap. Abbiamo sovrascritto entrambi i metodi equals () e hashCode (). Quindi, quando diciamo map.put (e1, 'C ++'), esegue l'hashing in una posizione del bucket. Successivamente, chiamiamo map.put (e2, 'Python'). Questa volta sarà hash nello stesso bucket e sostituirà il valore precedente. Questo perché abbiamo sovrascritto il metodo hashCode ().
Sostituzione del metodo statico in Java
Possiamo sovrascrivere il metodo statico in Java?
come eseguire un file .bin
Per quanto riguarda l'override del metodo statico in Java, la risposta diretta a questa domanda è No, non possiamo sovrascrivere il metodo statico.
Il metodo statico viene richiamato utilizzando il nome della classe stessa. Non abbiamo bisogno di un oggetto per chiamare un metodo statico. Quindi, anche se dichiariamo un metodo con lo stesso prototipo in una sottoclasse, non possiamo chiamarlo override. Invece, stiamo solo nascondendo la definizione della classe genitore del metodo statico.
Il seguente programma Java mostra il metodo statico e il metodo non statico in un sistema di ereditarietà insieme al loro comportamento in fase di esecuzione.
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(); } }
Produzione:
Dall'output del programma possiamo concludere quanto segue.
- La chiamata al metodo statico viene sempre effettuata in base al tipo di riferimento. Quindi quando abbiamo chiamato new_obj. display () nel programma precedente, poiché il riferimento new_obj è di tipo class Parent, viene chiamato il metodo display () della classe Parent.
- D'altra parte, i metodi non statici vengono chiamati in base al contenuto dell'oggetto di riferimento con cui viene chiamato il metodo. Quindi nel programma precedente il metodo new_obj.print () chiama il metodo print () della classe figlia poiché i contenuti new_obj sono l'oggetto della classe figlia.
Questo spiega l'output del programma sopra e dobbiamo ricordare anche i seguenti punti mentre trattiamo i metodi statici nel sistema OOP.
- Un metodo statico non può nascondere un metodo di istanza non statico e un metodo di istanza non statico non può sovrascrivere un metodo statico.
- Possiamo sovraccaricare i metodi dalla classe genitore in una sottoclasse ma non sovrascrivono né nascondono i metodi della classe genitore, piuttosto sono nuovi metodi nella sottoclasse.
Sostituzione di compareTo () in Java
Sappiamo che l'interfaccia java.lang.Comparable fornisce un metodo 'compareTo ()' utilizzando il quale possiamo ordinare gli oggetti in un ordine naturale come l'ordine lessicale per gli oggetti String, l'ordine numerico per i numeri interi, ecc.
Per implementare l'ordinamento in oggetti o raccolte definiti dall'utente, è necessario sovrascrivere il metodo compareTo () per ordinare gli elementi della raccolta o gli oggetti definiti dall'utente.
Quindi cosa fa un metodo compareTo ()?
Un metodo compareTo () deve restituire un valore positivo se l'oggetto corrente è maggiore dell'oggetto passato nell'ordine e il valore negativo dell'oggetto corrente è minore dell'oggetto passato. Se entrambi gli oggetti sono uguali, il metodo compareTo () restituirà zero.
Un altro punto da notare è che il metodo equals () e compareTo () dovrebbero comportarsi in modo coerente tra loro. Ciò significa che se il metodo compareTo () restituisce che due oggetti sono uguali (restituisce zero), allora dovremmo avere lo stesso output anche dal metodo equals ().
Implementiamo un programma Java che sovrascrive il metodo compareTo (). In questo programma, stiamo usando una classe Color che ha due variabili private, ovvero nome e id. Abbiamo associato 'id' a ogni colore e sovrascriveremo il metodo compare () per disporre i colori in base all'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() + ' , '); }
Produzione:
Nell'output precedente, visualizziamo prima l'elenco dei colori e quindi l'elenco ordinato dei colori. Nel programma, abbiamo sovrascritto i metodi compareTo () e compare ().
Sostituisci il metodo toString () in Java
Il metodo 'toString ()' restituisce la rappresentazione String di un oggetto in Java. Ma quando abbiamo oggetti definiti dall'utente, questo metodo potrebbe comportarsi in modo diverso.
Per esempio,considera il seguente programma.
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); } }
Produzione:
Come mostrato in questo programma, stiamo visualizzando l'oggetto della classe Complex che abbiamo definito in precedenza. Tuttavia, l'output mostrato non è il contenuto ma è piuttosto criptico.
L'output mostra un nome di classe Complex seguito dal carattere '@' e quindi dal codice hash dell'oggetto. Questo è l'output predefinito stampato dal metodo toString () della classe Object.
Se vogliamo l'output corretto, dobbiamo sovrascrivere il metodo toString () nella nostra applicazione.
Il seguente programma Java mostra come sovrascrivere il metodo toString () per stampare il contenuto dell'oggetto Complex.
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); } }
Produzione:
Il programma sopra mostra che il metodo toString () è sovrascritto per restituire il contenuto dell'oggetto Complex nel formato dato (reale + i * immaginario).
In generale, quando vogliamo visualizzare l'oggetto della classe usando print () o println (), è sempre consigliabile sovrascrivere il metodo toString () in modo da ottenere l'output corretto.
Domande frequenti
D # 1) Perché usare .equals invece di == Java?
qual è la fase di implementazione nella sdlc?
Risposta: Usiamo '==' per confrontare tipi primitivi come int, char, boolean, ecc. Usiamo equals () per confrontare oggetti (predefiniti o definiti dall'utente). Di solito sovrascriviamo il metodo equals () per confrontare due oggetti e il valore restituito da equals () dipende dal codice sovrascritto.
D # 2) A cosa servono hashCode () ed equals ()?
Risposta: In Java, il metodo equals () viene utilizzato per confrontare l'uguaglianza di due oggetti. Il metodo hashCode () restituisce l'hashCode dell'oggetto. Mentre il metodo equals () viene utilizzato con la maggior parte degli oggetti per testarne l'uguaglianza, hashCode viene utilizzato principalmente nelle raccolte hash come HashTable, HashMap, HashSet, ecc.
D # 3) Possiamo cambiare l'elenco degli argomenti del metodo sovrascritto?
Risposta: No. Quando sovrascriviamo il metodo, manteniamo la firma del metodo o il prototipo del metodo anche nella sottoclasse. Quindi non possiamo cambiare il numero di parametri nel metodo sovrascritto.
D # 4) Perché sovrascriviamo toString ()?
Risposta: Quando il metodo toString () viene sovrascritto, possiamo restituire i valori dell'oggetto per il quale il metodo toString () è sovrascritto senza scrivere troppo codice. Questo perché il compilatore java richiama il metodo toString () quando stampiamo un oggetto.
D # 5) Cosa succederebbe se non si sovrascriverà il metodo toString ()?
Risposta: Se non sovrascriviamo il metodo toString (), non otterremo alcuna informazione sulle proprietà o sullo stato dell'oggetto. Non sapremo cosa c'è effettivamente all'interno dell'oggetto. Quindi tutte le classi dovrebbero sovrascrivere il metodo toString ().
Questo perché l'implementazione predefinita del metodo toString () visualizza la rappresentazione String, ma quando usiamo l'implementazione predefinita toString () sull'oggetto, non otterremo il contenuto dell'oggetto.
Conclusione
In questo tutorial, abbiamo discusso dell'override di alcuni metodi Java predefiniti e abbiamo anche visto perché è necessario sovrascriverli.
Quando abbiamo a che fare con gli oggetti, le implementazioni predefinite di metodi come equals (), compareTo () e toString () potrebbero non fornire le informazioni corrette. Quindi andiamo per l'override.
=> Dai un'occhiata alla guida per principianti di Java qui.
Lettura consigliata
- Tutorial Java String | Metodi Java String con esempi
- Thread Java con metodi e ciclo di vita
- Metodo Java String length () con esempi
- Invertire un array in Java - 3 metodi con esempi
- Come utilizzare il metodo Java toString?
- Java String indexOf Metodo con esempi di codice
- Tutorial sul metodo Java String contains () con esempi
- Metodo Java String Split () - Come dividere una stringa in Java