Notice
Recent Posts
Recent Comments
Link
passion and relax
[JAVA] 08. 심각한 다형성 (추상 클래스와 인터페이스) 본문
다형성
. 융통성과 확장성을 얻을 수 있다.
. 다형성을 제대로 쓰려면, interface가 필요하다.
. interface : 추상 클래스로서, 인스턴스를 만들 수 없는 클래스
추상 클래스
Hippo hippo = new Hippo(); //OK
Animal hippo = new Hippo(); //OK
Animal animal = new Animal(); //OK이지만, Animal이 무슨 동물?
. 이런 경우 때문에, Animal 클래스는 abstract로 만들어야 한다.
. 클래스 중에 인스턴스를 만들면 안되는 경우, abstract로 만들어야 한다.
. 즉, new 키워드를 쓸 수 없게 만든다.
abstract public class Canine extends Animal {
public void roam() { ~~ }
}
Canine c = new Dog(); //OK. 하위클래스의 레퍼런스를 담을 수 있다.
Canine c = new Canine(); //X. new 자체를 쓸 수 없다.
. 확장하지 않으면, 추상 클래스는 아무 의미가 없다. (static 멤버 제외..)
. 실제 실행되는 것은 추상 클래스의 하위 클래스의 인스턴스이다.
. 반드시 extends 해야 하는 클래스
추상 메소드
. 반드시 override 해야 하는 클래스.
. 몸통이 없으니, override 해야할 수 밖에..
. public abstract void eat();
. 하나라도 추상 메소드가 있다면, 그 클래스는 추상 클래스여야 한다.
. 하위 클래스를 위한 규약의 일부를 정의할 때 사용한다.
추상 클래스의 상속
. 추상 > 구상 : 구상에서 추상 메소드 구현
. 추상1 > 추상2 > 구상
=> 추상1은 추상2 또는 구상에서 모두 구현해야 함.
=> 추상2는 구상에서 모두 구현해야 함.
Object 클래스
Class getClass() : 그 객체의 실제 클래스 유형 리턴 (class Cat)
boolean equals() : 한 객체가 다른 객체와 같은지 여부를 리턴
int hashCode() : 객체를 hash table에 넣을 때, 필요한 객체의 hash code 리턴 (8202111)
String toString() : 객체의 내용을 String으로 반환 (cat@7d277f)
Object 유형의 다형적 레퍼런스 사용
. 고유의 성질을 잃는다.
. instanceOf와 cast를 이용해 고유의 성질을 되찾아 줘야 한다.
Object o = getObject(index);
if (o instanceOf Dog) {
Dog d = (Dog) o;
}
interface 상속 트리 예
Animal > Feline(고양이과) > Cat <= implements Pet
Animal > Feline(고양이과) > Lion
Animal > Hippo
Animal > Canine(개과) > Wolf
Animal > Canine(개과) > Dog <= implements Pet
Robot > RobotDog <= implements Pet
//interface는 자동 public, abstract 이므로 안써도 된다. 여긴 썻지만
public interface Pet {
public abstract void beFriendly(); //interface 안의 메소드는 무조건 추상
public abstract void play(); //interface 안의 메소드는 무조건 추상
}
public class Dog extends Canine implements Pet {
//Pet의 추상 메소드 구현
}
. Pet의 성질을 Animal에 넣지 않고, interface로 따로 정의한다.
=> 왜? Lion, Hippo, Wolf는 Pet의 성질이 없기 때문이다.
. Pet의 성질을 Animal에 추상 메소드로 들지 않고, interface로 따로 정의한다.
=> 왜? Lion, Hippo, Wolf 는 불필요하게 빈 뼈대를 만들어야 한다.
=> 왜? 아무 작동하지 않는, 메서드가 존재하는 것은 불합리하다.
. Cat과 Dog에만 Pet의 기능을 넣지 않고, interface로 따로 정의한다.
=> 왜? 개발자가 beFriendly(), play()의 기능을 같은 이름으로 다 구현하지 않을 수도 있다.
=> 왜? 메서드명/매개변수/리턴값 등이 다를 수 있다.
한 클래스에서 여러 interface 구현하기
. 내가 만든 이 클래스가 저장을 해야 한다면, Serializable 인터페이스 구현.
. 내가 만든 이 클래스가 멀티 스래드를 해야 한다면, Runable 인터페이스 구현.
public class Dog extends Animal implements Pet, Serializable {
...
}
그냥 클래스 VS 상위/하위 클래스 VS 추상 클래스 VS 인터페이스
. 그냥 클래스
새로운 클래스가 다른 어떤 클래스에도 'A는 B다" 의 관계가 없을 때..
. 상위/하위 클래스
'A는 B다' 가 성립
더 구체화가 되어야 할 때..
오버라이드 하거나 새로운 메서드를 추가해야 할 때..
. 추상 클래스
하위 클래스에서 사용할 틀을 정의해야 할 때..
모든 하위 클래스에서 구현할 메소드가 있을 때..
이 클래스의 객체를 만들지 못하게 해야할 때..
. 인터페이스
상속과 무관하게 어떤 클래스들에서 여러번 사용될 역할을 정의하고 싶을 때..
정리
. 클래스를 만들 때, 인스턴스를 만들 수 없게 하고 싶다면 abstract 사용.
. 추상 클래스에는 추상 메소드와 일반 메소드를 넣을 수 있다.
. 추상 메소드가 하나라도 있다면, 그 클래스는 추상 클래스가 되어야 한다.
. 추상 메소드는 몸체가 없으며, 선언 부분이 세미콜론으로 끝난다. 중괄호도 없다.
. 상속 트리에서 처음 나오는 구상 클래스는 모든 추상 메소드를 구현해야 한다.
. 자바의 모든 클래스는 모두 Object의 하위 클래스이다.
. 메소드를 선언할 때, 인자, 리턴 유형을 Object 로 지정해도 된다.
. 오버라이드할 때, 상위를 확장하려 한다면, super.haha()를 먼저 호출한다.
'프로그래밍' 카테고리의 다른 글
[JAVA] 10. 숫자는 정말 중요합니다 (수학, 포매팅, 래퍼, 통계) (0) | 2024.05.24 |
---|---|
[JAVA] 09. 객체의 삶과 죽음 (생성자와 메모리 관리) (0) | 2024.05.23 |
[JAVA] 07. 객체마을에서의 더 나은 삶 (미래를 준비합시다) (0) | 2024.05.21 |
[JAVA] 06. 자바 라이브러리 (전부 다 직접 만들어서 쓸 필요는 없습니다) (0) | 2024.05.20 |
[JAVA] 05. 메소드를 더 강력하게 (흐름 제어, 연산 등) (0) | 2024.05.20 |