overriding predefined methods java
Този урок обяснява как да замените предварително дефинирани методи като equals (), hashCode (), compareTo () и др. В Java с примери:
В предишния ни урок обсъдихме полиморфизма по време на изпълнение в Java. Полиморфизмът по време на изпълнение в Java се реализира с използване на метода, заместващ. Замяна на метода включва предефиниране на метода на родителския клас в подкласа.
Java има различни предварително дефинирани методи като equals (), hashCode (), compareTo (), toString () и др., Които се използват често за общи обекти, независимо към кой клас принадлежат. Но за да работят тези методи за всички обекти, трябва да заменим тези методи или да дефинираме повторно техните имплементации, за да могат да работят с данните, които искаме.
=> Посетете тук, за да научите Java от нулата.
В този урок ще обсъдим заместването на всички тези методи заедно с последиците, ако не заменим тези методи.
c # интервю въпроси и отговори за опитни с примери
Какво ще научите:
- Замяна на методите equals () и hashCode () в Java
- Замяна на статичния метод в Java
- Заменяне на compareTo () в Java
- Замяна на метода toString () в Java
- често задавани въпроси
- Заключение
- Препоръчително четене
Замяна на методите equals () и hashCode () в Java
Използваме метода equals () в Java, за да сравним два обекта. Този метод връща true, когато обектите са равни и false, когато не са равни.
Използват се два начина за сравняване на равенството на два обекта.
# 1) Плитко сравнение
Плиткото сравнение е изпълнението по подразбиране за метода equals (), дефиниран в класа „java.lang.Object“. Като част от това изпълнение, методът equals () ще провери дали два обекта, които се сравняват, имат препратки, отнасящи се до един и същ обект.
Това означава, че ако obj1 и obj2 са два обекта, тогава изпълнението по подразбиране на метода equals () (плитко сравнение) ще провери само дали препратките към obj1 и obj2 са от един и същ обект.
При плитко сравнение няма сравнение на съдържанието на данни.
# 2) Дълбоко сравнение
При дълбоко сравнение сравняваме членовете на данните на всеки обект, т.е.обектите се сравняват по отношение на състоянието. Затова сравняваме обектите на дълбоко ниво, включително съдържанието им.
За да сравним обектите, използвайки дълбоко сравнение, ние обикновено отменяме метода equals ().
Сега помислете за следната програма 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 '); } } }
Изход:
Ако видим изхода на горната програма, той казва, че обектите не са равни, въпреки че съдържанието на двата обекта е еднакво. Това е така, защото при проверка на равенството се определя дали двата обекта c1 и c2 се отнасят за един и същ обект.
Както се вижда в програмата c1 и c2 са два различни обекта, така че те са различни препратки и по този начин се получава така.
Сега нека създадем трета препратка c3 и я приравним на c1, както следва:
Комплекс c3 = c1;
В този случай c3 и c1 ще се отнасят до един и същ обект и следователно (c3 == c1) ще върнат true.
Това, което направи горната програма, беше плиткото сравнение. И така, как да проверим дали два обекта са еднакви по съдържание?
Тук се насочваме към задълбочено сравнение и за тази цел заместваме метода equals ().
Следващата програма показва замяна на метода equals (). Използваме същия комплексен клас.
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 '); } } }
Изход:
Сега, когато имаме метод на overridden equals (), когато сравняваме два обекта, изходът показва, че двата обекта са равни, тъй като съдържанието им е еднакво. Обърнете внимание на метода overridden equals (). Тук проверяваме дали и двата обекта имат една и съща препратка. Ако не, тогава проверяваме индивидуално съдържанието на тези обекти.
В Java, когато заменим метода equals (), препоръчително е да заменим и метода hashCode (). Това е така, защото ако не заменим метода hashCode (), тогава всеки обект може да има различен hashCode.
Това може да не пречи на общите обекти, но някои колекции, базирани на хеш като HashTable, HashSet и HashMap, може да не работят правилно.
Следващата програма показва заменени методи equals () и 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()); } } }
Изход:
В тази програма използваме hashMap. Ние сме заменили методите equals () и hashCode (). Така че, когато казваме map.put (e1, “C ++”), той хешира до някакво местоположение на сегмента. След това извикваме map.put (e2, “Python”). Този път ще хешира към същата група и ще замени предишната стойност. Това е така, защото сме заменили метода hashCode ().
Замяна на статичния метод в Java
Можем ли да заменим статичния метод в Java?
Що се отнася до заместването на статичния метод в Java, прекият отговор на този въпрос е Не, не можем да заменим статичния метод.
Статичният метод се извиква, като се използва самото име на класа. Нямаме нужда от обект, който да извика статичен метод. Така че дори ако декларираме метод със същия прототип в подклас, не можем да го наречем заместващ. Вместо това ние просто крием дефиницията на родителския клас на статичния метод.
Следващата Java програма показва статичния метод и нестатичния метод в система за наследяване заедно с тяхното поведение по време на изпълнение.
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(); } }
Изход:
От изхода на програмата можем да заключим следното.
- Извикването на статичния метод винаги се извършва въз основа на типа препратка. Следователно, когато извикахме new_obj. display () в горната програма, тъй като препратката new_obj е от тип клас Parent, извиква се методът display () на Parent class.
- От друга страна, нестатичните методи се извикват въз основа на съдържанието на референтния обект, с който се извиква методът. Следователно в горната програма метод new_obj.print () извиква метода print () на дъщерния клас, тъй като съдържанието new_obj е обект на дъщерния клас.
Това обяснява изхода на програмата по-горе и трябва да запомним и следните точки, докато се занимаваме със статични методи в OOP системата.
- Статичният метод не може да скрие нестатичен метод на екземпляр, а нестатичният метод не може да замени статичния метод.
- Можем да претоварим методите от родителския клас в подклас, но те нито заменят, нито скриват методите на родителския клас, а са нови методи в подкласа.
Заменяне на compareTo () в Java
Знаем, че интерфейсът java.lang.Comparable осигурява метод ‘compareTo ()’, чрез който можем да сортираме обектите в естествен ред като лексикален ред за обекти String, числов ред за Integers и т.н.
За да приложим сортирането в дефинирани от потребителя обекти или колекции, трябва да заменим метода compareTo (), за да сортираме елементите на колекцията или дефинираните от потребителя обекти.
И така, какво прави методът compareTo ()?
Методът compareTo () трябва да върне положителна стойност, ако текущият обект е по-голям от подадения обект по ред и отрицателната стойност на текущия обект е по-малка от подадения обект. Ако и двата обекта са равни, тогава методът compareTo () ще върне нула.
Друг момент, който трябва да се отбележи е, че методът equals () и compareTo () трябва да се държи последователно един с друг. Това означава, че ако методът compareTo () връща, че два обекта са равни (връща нула), тогава трябва да имаме същия изход и от метода equals ().
regex_match c ++
Нека да приложим Java програма, която заменя метода compareTo (). В тази програма използваме клас Color, който има две частни променливи, т.е.име и id. Свързали сме ‘id’ с всеки цвят и ще заменим метода compare (), за да подредим цветовете според 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() + ' , '); }
Изход:
В горния изход първо показваме списъка с цветове и след това сортирания списък с цветове. В програмата сме заменили методите compareTo () и compare ().
Замяна на метода toString () в Java
Методът ‘toString ()’ връща низовото представяне на обект в Java. Но когато имаме дефинирани от потребителя обекти, тогава този метод може да се държи по различен начин.
Например,разгледайте следната програма.
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); } }
Изход:
Както е показано в тази програма, ние показваме обекта на комплексния клас, който сме дефинирали по-рано. Показаният изход обаче не е съдържанието, а е доста загадъчен.
Изходът показва име на клас Complex, последвано от символа ‘@’ и след това hashCode на обекта. Това е изходът по подразбиране, отпечатан от метода toString () на класа Object.
Ако искаме правилния изход, тогава трябва да заменим метода toString () в нашето приложение.
Следващата програма Java показва как да замените метода toString (), за да отпечатате съдържанието на обекта 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); } }
Изход:
Горната програма показва, че методът toString () е заменен, за да върне съдържанието на сложен обект в дадения формат (реално + i * въображаемо).
По принцип, когато искаме да покажем обекта на класа, използвайки print () или println (), винаги е препоръчително да заменим метода toString (), така че да получим правилния изход.
често задавани въпроси
В # 1) Защо да използвам .equals вместо == Java?
кой е най-добрият компютър оптимизатор
Отговор: Използваме ‘==’ за сравняване на примитивни типове като int, char, boolean и др. Използваме equals () за сравняване на обекти (предварително дефинирани или дефинирани от потребителя). Обикновено заместваме метода equals (), за да сравняваме два обекта и възвръщаемата стойност на equals () зависи от отменения код.
В # 2) За какво се използва hashCode () и equals ()?
Отговор: В Java методът equals () се използва за сравняване на равенството на два обекта. Методът hashCode () връща hashCode на обекта. Докато методът equals () се използва с повечето обекти за тестване на тяхното равенство, hashCode се използва най-вече в хеш колекции като HashTable, HashMap, HashSet и др.
В # 3) Можем ли да променим списъка с аргументи на заменения метод?
Отговор: Не. Когато заменим метода, запазваме подписа на метода или прототипа на метода същите и в подкласа. Така че не можем да променим броя на параметрите в заменения метод.
В # 4) Защо заместваме toString ()?
Отговор: Когато методът toString () е заменен, можем да върнем стойностите на обекта, за който методът toString () е заменен, без да пишем твърде много код. Това е така, защото java компилаторът извиква метода toString (), когато отпечатваме обект.
В # 5) Какво би се случило, ако не замените метода toString ()?
Отговор: Ако не заменим метода toString (), тогава няма да получим информация за свойствата или състоянието на обекта. Няма да разберем какво всъщност има вътре в обекта. Така че всички класове трябва да заменят метода toString ().
Това е така, защото изпълнението по подразбиране на метода toString () показва представянето на String, но когато използваме изпълнението по подразбиране toString () на обекта, тогава няма да получим съдържанието на обекта.
Заключение
В този урок обсъдихме заменянето на няколко предварително дефинирани Java метода и също така видяхме защо трябва да ги заменим.
Когато се занимаваме с обекти, изпълнението по подразбиране на методи като equals (), compareTo () и toString () може да не даде правилната информация. Следователно ние отиваме за заменяне.
=> Погледнете тук ръководството за начинаещи Java.
Препоръчително четене
- Java урок за низове | Низови методи на Java с примери
- Java нишки с методи и жизнен цикъл
- Дължина на низа на Java () Метод с примери
- Обръщане на масив в Java - 3 метода с примери
- Как да използвам Java toString метод?
- Java String indexOf метод с примери за кодове
- Java String съдържа () Урок за метод с примери
- Метод за разделяне на низове в Java () - Как да разделя низ в Java