JAVA AWS 클라우드 기반 Devops 개발자 과정 상속, Object
상속이란?
객체 지향 프로그래밍의 중요한 특징 중 하나가 상속(inheritance)이다. 흔히 우리가 알고 있는 상속의 뜻과 비슷하다.
A클래스와 B클래스가 있다고 할 때 B클래스가 A클래스를 상속받으면 B클래스는 A클래스의 멤버 변수와 메서드를 사용할 수 있다.
객체 지향 프로그램에서 유지보수하기 편하고 프로그램을 수정하거나 새로운 내용을 추가하는 것이 유연한데 그 기반이 되는 기술이 상속이다.
클래스 간 상속을 표현할 때는 위 그림에 표현한 것처럼 상속받는 클래스에서 상속하는 클래스로 화살표가 가므로 헷갈리면 안 된다.
클래스 상속 문법
class B extends A{ // B클래스가 A클래스를 상속받는다.
}
자바는 단일 상속 이면서, 다중 상속을 허용하지 않아서 extends 뒤에는 하나의 부모 클래스만 와야 한다.
C++은 다중 상속이 가능하지만 자바에서는 다중 상속을 허용하지 않은 이유는?
클래스 간의 관계가 매우 복잡해지기 때문이다.
다중 상속을 허용하면 클래스의 성질이 복합적으로 섞여 부모와 상속받은 멤버 간의 이름이 같을 경우 구별할 수 있는 방법이 없기 때문이다.
Object클래스
Object 클래스는 모든 클래스의 부모, 조상이자 모든 자바의 클래스는 Object 클래스로부터 시작된다.
우리는 클래스 파일을 만들면서 클래스명을 작성하면 자동적으로 Object클래스가 extends가 된다.
Object클래스는 필드가 없고 메서드로 구성되어 있으며 모든 클래스의 부모, 조상이기 때문에 모든 클래스에서 이용할 수 있다.
만약 다른 클래스를 상속시킨다면 클래스는 한 개밖에 상속할 수 없기 때문에 extends Object는 사라진다.
하지만 부모 클래스에서 Object를 상속하고 있기에 모든 클래스는 Object클래스를 상속받고 있는 형태가 된다.
calss MemberObject{
}
public class Main{
public static void main(String[] args){
MemberObject m = new MemberObject();
//MemberObject 클래스에 메소드를 명시하지 않아도 동작하는 이유는 자동으로 Object를 상속하기 때문에 부모의 메서드를 쓰는 것이다.
m.toString();
m.hashCode();
}
}
Object클래스에서 빈번하게 쓰이는 메서드는 equals(), hashCode(), toString, clone()
메서드 | 설명 | 특징 |
equals() | 객체 자신과 객체 obj가 같은 객체인지 알려주는 메서드 | ㆍ참조 변수에 저장된 주소를 비교 ㆍ오버라이딩을 통해 다른 메모리에 있는 객체여도 논리적으로 비교할 수 있다. ㆍ동작은 '=='이기 때문에 결과는 true 또는 false가 된다. |
hashCode() | 객체 자신의 해시 코드를 반환 | ㆍ자료의 특정 값(키 값)에 대한 저장위치를 반환해주는 해시 함수를 사용 |
toString() | 객체의 문자열 표현을 반환 | ㆍ인스턴스에 대한 정보를 문자열로 제공할 목적으로 정의되어 있는 것 ㆍ오버라이딩을 통해 내용을 변경할 수 있다. |
clone() | 객체의 원본을 복제하는데 사용하는 메서드 | ㆍ오버라이딩을 통해 접근제어자를 public으로 바꿔줘야 한다. |
Object클래스에서 빈번하게 쓰이는 메서드는 equals(), hashCode(), toString, clone() 이렇게 4가지가 빈번하게 쓰인다.
특히 equals() / hashCode() 메서드를 같이 오버라이딩 해야 하는 이유
1. 해시 기반 컬렉션에서 정상적으로 동작하기 위해서
ㆍ 객체의 hashCode()를 계산하여 버킷으로 결정한다.
ㆍ 같은 해시코드의 객체가 여러 개 존재할 수 있으므로, 해당 버킷 내부에서 equls()를 사용하여 객체를 비교한다.
>> equals() 오버라이딩하고 hashCode()를 오버라이딩하지 않으면, 해시 기반 컬렉션에서 정상적으로 동작하지 않는다.
2. hashCode()를 오버라이딩하지 않으면 발생하는 문제
ㆍ 동일한 논리적 객체인데도 중복으로 저장됨
3. equals()와 hashCode()를 오버라이딩하기
ㆍ 같은 객체라면 equals() == true, hashCode() 값도 같아야 한다.
ㆍ 다른 객체라면 equals() == false, hashCode() 값이 가을 수도 있지만 가능하면 다르게 설정하는 것이 좋다.
ㆍ hashCode()가 같은 객체끼리만 equals를 비교하도록 설계해야 한다.
결론
ㆍ equals()만 오버라이딩하면 해시 기반 컬렉션에서 객체가 중복 저장될 가능성이 있다.
ㆍ hashCode()만 오버라이딩하면 논리적으로 다른 객체가 같은 해시코드를 가질 수 있어 충돌이 발생할 수 있다.
ㆍ 두 메서드를 함께 오버라이딩하는 것이 바람직하다.