overriding predefined methods java
이 자습서에서는 Java에서 equals (), hashCode (), compareTo () 등과 같은 미리 정의 된 메서드를 예제로 재정의하는 방법을 설명합니다.
이전 자습서에서 Java의 런타임 다형성에 대해 논의했습니다. Java의 런타임 다형성은 메서드 재정의를 사용하여 구현됩니다. 메서드 재정의에는 하위 클래스에서 부모 클래스 메서드를 재정의하는 작업이 포함됩니다.
Java에는 속한 클래스에 관계없이 일반 객체에 일반적으로 사용되는 equals (), hashCode (), compareTo (), toString () 등과 같은 미리 정의 된 다양한 메소드가 있습니다. 그러나 이러한 메서드가 모든 개체에 대해 작동하려면 원하는 데이터로 작업 할 수 있도록 이러한 메서드를 재정의하거나 구현을 재정의해야합니다.
=> 처음부터 Java를 배우려면 여기를 방문하십시오.
이 자습서에서는 이러한 메서드를 재정의하지 않는 경우 결과와 함께 이러한 모든 메서드의 재정의에 대해 설명합니다.
학습 내용 :
- Java에서 equals () 및 hashCode () 메서드 재정의
- 자바에서 정적 메서드 재정의
- Java에서 compareTo () 재정의
- Java에서 toString () 메서드 재정의
- 자주 묻는 질문
- 결론
- 추천 도서
Java에서 equals () 및 hashCode () 메서드 재정의
두 객체를 비교하기 위해 Java에서 equals () 메소드를 사용합니다. 이 메서드는 객체가 같으면 true를 반환하고 같지 않으면 false를 반환합니다.
두 개체의 동등성을 비교하는 데 두 가지 방법이 사용됩니다.
# 1) 얕은 비교
단순 비교는“java.lang.Object”클래스에 정의 된 equals () 메소드의 기본 구현입니다. 이 구현의 일부로 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는 두 개의 다른 객체이므로 서로 다른 참조이므로 결과가 달라집니다.
C ++에 대한 인터뷰 질문
이제 세 번째 참조 c3를 만들고 다음과 같이 c1과 동일시하겠습니다.
복잡한 c3 = c1;
이 경우 c3 및 c1은 동일한 객체를 참조하므로 (c3 == c1)은 true를 반환합니다.
위의 프로그램이 한 것은 얕은 비교였습니다. 그렇다면 두 객체가 동일한 내용인지 어떻게 확인합니까?
하드 드라이브를 복제하는 최고의 프로그램
여기서 우리는 심층 비교를하고이를 위해 equals () 메서드를 재정의합니다.
다음 프로그램은 equals () 메서드의 재정의를 보여줍니다. 우리는 동일한 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 '); } } }
산출:
이제 재정의 된 equals () 메서드가 있으므로 두 객체를 비교할 때 두 객체가 내용이 같으므로 두 객체가 같음을 출력에 표시합니다. 재정의 된 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 프로그램은 상속 시스템의 정적 메서드와 비 정적 메서드를 런타임시 동작과 함께 보여줍니다.
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를 호출했을 때. 위 프로그램에서 new_obj 참조가 Parent 클래스이므로 display () 메서드를 호출하면 Parent 클래스의 display () 메서드가 호출됩니다.
- 반면에 비 정적 메서드는 메서드가 호출되는 참조 객체의 내용을 기반으로 호출됩니다. 따라서 위의 프로그램에서 new_obj.print () 메서드는 new_obj 내용이 자식 클래스의 객체이므로 자식 클래스의 print () 메서드를 호출합니다.
이것은 위 프로그램의 출력을 설명하며 OOP 시스템에서 정적 메소드를 처리하는 동안 다음 사항도 기억해야합니다.
- 정적 메서드는 비 정적 인스턴스 메서드를 숨길 수 없으며 비 정적 인스턴스 메서드는 정적 메서드를 재정의 할 수 없습니다.
- 서브 클래스의 부모 클래스에서 메서드를 오버로드 할 수 있지만 부모 클래스 메서드를 재정의하거나 숨기지 않으며, 오히려 서브 클래스의 새로운 메서드입니다.
Java에서 compareTo () 재정의
java.lang.Comparable 인터페이스는 문자열 객체의 어휘 순서, 정수의 숫자 순서 등과 같은 자연스러운 순서로 객체를 정렬 할 수있는 'compareTo ()'메소드를 제공합니다.
사용자 정의 개체 또는 컬렉션에서 정렬을 구현하려면 compareTo () 메서드를 재정 의하여 컬렉션 요소 또는 사용자 정의 개체를 정렬해야합니다.
그래서 compareTo () 메소드는 무엇을합니까?
현재 객체가 순서대로 전달 된 객체보다 크고 현재 객체의 음수 값이 전달 된 객체보다 작은 경우 compareTo () 메서드는 양수 값을 반환해야합니다. 두 객체가 같으면 compareTo () 메서드는 0을 반환합니다.
주목해야 할 또 다른 점은 equals ()와 compareTo () 메소드가 서로 일관되게 작동해야한다는 것입니다. 즉, compareTo () 메서드가 두 개체가 같음을 반환하면 (0을 반환) equals () 메서드에서도 동일한 출력을 가져야합니다.
compareTo () 메서드를 재정의하는 Java 프로그램을 구현해 보겠습니다. 이 프로그램에서 우리는 이름과 ID라는 두 개의 개인 변수가있는 Color 클래스를 사용하고 있습니다. 'id'를 각 색상과 연관 시켰으며 비교 () 메서드를 재정 의하여 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 () 메서드를 재정의했습니다.
Java에서 toString () 메서드 재정의
메소드‘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 클래스 객체를 표시합니다. 그러나 표시된 출력은 내용이 아니라 다소 모호합니다.
출력에는 Complex라는 클래스 이름과‘@’문자, 객체의 hashCode가 차례로 표시됩니다. 이것은 Object 클래스의 toString () 메서드에 의해 인쇄되는 기본 출력입니다.
적절한 출력을 원하면 애플리케이션에서 toString () 메서드를 재정의해야합니다.
다음 Java 프로그램은 Complex 객체의 내용을 인쇄하기 위해 toString () 메서드를 재정의하는 방법을 보여줍니다.
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); } }
산출:
위 프로그램은 주어진 형식 (실제 + i * 가상)으로 Complex 객체의 내용을 반환하기 위해 toString () 메서드가 재정의되었음을 보여줍니다.
일반적으로 print () 또는 println ()을 사용하여 클래스 객체를 표시하려면 적절한 출력을 얻을 수 있도록 항상 toString () 메서드를 재정의하는 것이 좋습니다.
자주 묻는 질문
Q # 1) == Java 대신 .equals를 사용하는 이유는 무엇입니까?
최고의 무료 비디오 다운로더 Windows 10
대답: int, char, boolean 등과 같은 기본 유형을 비교하기 위해‘==’를 사용합니다. 객체 (사전 정의 또는 사용자 정의)를 비교하기 위해 같음 ()을 사용합니다. 일반적으로 equals () 메서드를 재정 의하여 두 개체를 비교하고 equals ()의 반환 값은 재정의 된 코드에 따라 다릅니다.
Q # 2) hashCode ()와 같음 ()은 무엇에 사용됩니까?
대답: Java에서 equals () 메소드는 두 객체의 동등성을 비교하는 데 사용됩니다. hashCode () 메서드는 객체의 hashCode를 반환합니다. equals () 메소드는 동등성을 테스트하기 위해 대부분의 객체에 사용되지만 hashCode는 대부분 HashTable, HashMap, HashSet 등과 같은 해시 컬렉션에서 사용됩니다.
Q # 3) 재정의 된 메서드의 인수 목록을 변경할 수 있습니까?
대답: 아니요. 메서드를 재정의 할 때 메서드 서명 또는 메서드의 프로토 타입을 하위 클래스에서도 동일하게 유지합니다. 따라서 재정의 된 메서드에서 매개 변수 수를 변경할 수 없습니다.
Q # 4) 왜 toString ()을 재정의합니까?
대답: toString () 메서드가 재정의되면 너무 많은 코드를 작성하지 않고도 toString () 메서드가 재정의 된 객체의 값을 반환 할 수 있습니다. 이는 자바 컴파일러가 객체를 인쇄 할 때 toString () 메소드를 호출하기 때문입니다.
Q # 5) toString () 메서드를 재정의하지 않으면 어떻게 되나요?
대답: toString () 메서드를 재정의하지 않으면 개체의 속성이나 상태에 대한 정보를 얻지 못합니다. 우리는 실제로 개체 내부에 무엇이 있는지 알 수 없습니다. 따라서 모든 클래스는 toString () 메서드를 재정의해야합니다.
이는 toString () 메서드의 기본 구현이 String 표현을 표시하지만 객체에 기본 toString () 구현을 사용하면 객체의 내용을 얻지 못하기 때문입니다.
결론
이 튜토리얼에서는 사전 정의 된 몇 가지 Java 메서드를 재정의하는 방법에 대해 논의했으며이를 재정의해야하는 이유도 확인했습니다.
객체를 다룰 때 equals (), compareTo (), toString ()과 같은 메소드의 기본 구현은 올바른 정보를 제공하지 않을 수 있습니다. 따라서 우리는 재정의합니다.
=> 여기에서 Java Beginners Guide를 살펴보십시오.