[2025백엔드] 헤드퍼스트자바 독서 #4 - 8장. 심각한 다형성

2025. 7. 26. 04:03·언어공부/Java | Kotlin

ㅎㅇ

이딴게.. 개발블로그.....? 그래도

랍스터

윤마치

를사랑

하세요

 

암튼 오늘은 7장에 이어 8장을 읽을 예정이다.

인터페이스와 추상클래스에 대해 알아보자!


추상클래스

상속과 다형성을 위해서 한 상위클래스가 필요한 경우가 있다고 치자. (상위클래스에서 여러 개의 하위클래스가 분리해나오는 등..) 그런데 구체적인 기능들은 모두 하위클래스에 가있고, 상위클래스에는 별다른 기능이 없는경우엔? 그 때 필요한게 추상클래스다.

 

하위클래스를 위한 프로토콜 제공

 

만드는 법은 간단하게 그냥 클래스 만들 때 맨 앞에 abstract만 붙이면 된다.

 

추상클래스는 새로운 인스턴스를 만들 수 없는 클래스이다. 즉, new 를 통해 불러올 수 없다. 왜냐하면 '별다른 기능이 없는 상위클래스'이기 때문에 기능이 제대로 구현되지 않은, 그냥 뼈대이기 때문에 컴파일에러가 생긴다.

다만 배열에는 가능하다. 배열에는 클래스의 인스턴스변수가 들어가는게 아니라 클래스 type의 객체를 저장할 수 있는 공간을 만드는 것이기 때문. 물론 배열에 추상클래스의 인스턴스변수가 들어가면 오류

 

따라서 추상클래스는 확장이 필수적이다.

구분할 필요 없이 모두 같은 도메인에서는 구상, 상세하게 구분이 들어가야할 경우 (하위메서드가 필요할 경우) 추상? 뭐 이런식으로 하면 되나?


추상메서드

역시 확장에서 필요한 기능일 뿐 뼈대만 제공하기 때문에 별다른 로직이 없이 선언하고 바로 ; 으로 끝내도 된다.

public abstract void eat(); 뭐 이런 식으로..

 

추상클래스가 아닌 클래스에 추상메서드를 넣을 순 없으나 추상클래스 내에 추상메서드와 구상메서드를 넣는 것은 가능하다.

추상클래스를 상속받은 구상클래스는 추상클래스 내의 추상메서드를 모두 구현해야한다. 다만 상위-하위-하위하위 이런 구조에서는 하위클래스를 추상메서드로 구현할 수 있다.


Object

모든 클래스의 상위클래스라고 할 수 있는 클래스. 모든 클래스는 Object 클래스를 확장한다. 컴파일러에서 자동으로 확장해줌

대표적인 메서드로는 .eauals .getClass (누구의 클래스인지 호출) .hashCode(객체의 해시코드 출력) .toString 등이 있다.

 

주로 다형적 리턴타입이나 모든 객체에서 필요한 메서드 코드를 제공하기 위해 쓰인다.

즉 Object로 return 타입을 정하면 내가 String으로 반환하던 JSON으로 반환하던 상관없다는 얘기. 다만 자바의 중요 매커니즘인 타입안정성을 해치는 행위이면서..

Dog myDog = new Dog();
Dog objectDog = getObject(myDog);

실제로는 Dog 객체에 Object 객체를 집어넣을 수 없다. 컴파일러는 getObject에서 나온 객체를 Object 타입으로 인식하고, 다른 타입이라고 인식할 수 없기 때문에 오류가 생긴다. return (ArrayList나 배열에서 빼온다던지..) 이 아니라 Object 로 객체를 선언해도 같은 일이 일어난다.

Dog myDog = new Dog();
Object objectDog = getObject(myDog);

Object는 Object로만 받을 수 있다.


Dog myDog = new Dog();
Object objectDog = getObject(myDog);

objectDog.bark();

 

안된다. Object 클래스에서는 bark 메서드가 없다. (다른말로하면 Object 클래스 내에 있는 .equals 등의 메서드는 사용가능하다)

 

즉, 컴파일러에서는 실제 객체 타입이 아니라 레퍼런스 타입을 기준으로 메서드를 불러올 수 있는지 정한다.


ArrayList<Object>

 

이러면 ArrayList에 있는 모든 객체가 Object 타입으로 인식된다. 대참사 


Object에서 원래타입으로 불러오기

전에 배운 캐스트를 사용하면 된다.

Object objectDog = getObject(myDog);

뭐 이랬다면,

Dog d = (Dog) objectDog;

이런식으로..

 

다만 엉뚱한 타입으로 캐스팅을 시키면 오류가 나므로

if (objectDog instanceof Dog) {
	//로직
}

이런식으로 instanceof 연산자를 사용하면 된다. 좌항을 우항과 비교해서 같은 type의 객체면 true를, 아니면 false를 반환한다.


컴파일러야고마워

ArrayList<객체>

이렇게 선언된 ArrayList는 컴파일러에서 자동으로 캐스팅해준다고한다.  


다중상속?

헤드퍼스트자바 8장 262페이지에 나온 문제로, 상위-하위-하위하위 뭐 이런 구조로 이루어진 구조에서, 일부 하위하위클래스에서만 따로 필요한 메서드가 있을 때, 어떻게 구현할 것인가에 대한 문제였다. 책에서는

 

- 상위클래스에 필요한 메서드를 모두 집어넣는다. ('일부'라는 조건을 취하기 어렵다)

- 상위클래스에 필요한 메서드를 추상메서드로 집어넣는다. ('일부'라는 조건을 취할 수 있으나 모든 구상클래스에서 추상메서드를 구현해야하며, 결국에는 있다/없다가 아니라 구현됐다/안됐다고 구분해야한다. (하마다 befriendly 메서드를 가지는데 호출하면 아무일도 안일어남)

- 필요한 메서드를 그 메서드가 필요한 클래스에만 넣기 (상위클래스를 사용할 개발자도 하위클래스에만 들어가는 메서드를 파악하고 있어야하며 하위클래스의 메서드만 호출해도 상위클래스의 메서드를 가져올 수 있다는 상속과 다형성의 이점이 사라진다.)

 

그러면 '일부' 클래스에서만 적용시킬 새 상위클래스를 만드는 것은 어떠냐? 즉 다중상속, 이중상속을 시키는 것은 어떠냐? 라는 말이 나올 수 밖에 없다. 문제는..

 

'죽음의 다이아몬드'로도 알려져있는 다중상속 문제다. (죽음의 다이아몬드를 줄이면 DDD란다. 내가 아는 DDD는 이게 아닌데?)

ComboDrive 클래스에서는 인스턴스 변수 i를 호출했을 때 CDBurner의 i인지, DVDBurner의 i인지 알 수 없다.

 

따라서 자바는 다중상속을 허용하지 않는다.

 

참고로 파이썬은 다중상속을 허용하는데, 파이썬은 MRO를 통해 이를 방지한다.

자세한 내용은 https://xo.dev/articles/python-method-resolution-order 글 참고


다중상속이 안될땐? 인터페이스!

인터페이스는 내가 웹개발하면서 자주 썼던터라.. 크게 구체적으로 다루지는 않고 그냥 훑고만 넘어갈 생각이다.

 

- 내가 웹개발을 하면서 인터페이스를 만들고 서비스 계층에 적용시키다가 서비스계층에서 수정사항이 생기면 인터페이스까지 수정해야해서 인터페이스를 그냥 안썼다. 하지만 TDD를 도입시킨다면 인터페이스를 적용시키는 것이 훨씬 더 나을 것이다.

 

인터페이스는 여러 개를 사용할 수 있다. 확장과는 다르다.

public class Dog extends Animal implements Pet, Saveable, Paintable {
	//로직
}

 

이런식으로..


클래스? 추상클래스? 인터페이스?

1. is-a 관계 -> 'A는 B다' 테스트를 통과하지 않으면 새 클래스 만들기

2. 통과하거나, 구체적인 버전을 만들거나, 오버라이드하거나, 추가하거나 -> 클래스 확장

3. 하위클래스들에서 사용할 틀을 만들고 하위클래스에서 구현할 코드가 있음 -> 추상클래스

4. 상속트리에서 위치에 상관없이 클래스의 역할을 정의하고 싶다 -> 인터페이스

 

지금 새벽 4시.. 너무 피곤해서 내용이 잘 안 들어온다

꾸역꾸역 8장을 다 읽긴했는데 내일 한 번 더 읽어봐야겠다. 어우 피곤해

 

이런 정신상태에서 고찰을 해야 더욱 잘되는거~ 고찰거리가 있어서 고찰하러 갑니다

 

7월 26일 16시 수정

'A는 B다' 테스트를 통과할 경우,

어떤 클래스를 오버라이드하거나 새로운 코드를 추가하고 싶을 경우 하위클래스를 만들어 확장하고,

하위클래스들에서 사용할 일련의 틀을 제작하고 싶다면 추상클래스를 사용한다.

 

상속트리에 있는지 여부에 상관없이 클래스의 역할을 정의하고 싶다면 인터페이스를 이용하면 된다.

'언어공부 > Java | Kotlin' 카테고리의 다른 글

[2025백엔드] 헤드퍼스트자바 독서 #6 - 10장. 숫자는 정말 중요합니다  (5) 2025.08.03
[2025백엔드] 헤드퍼스트자바 독서 #5 - 9장. 객체의 삶과 죽음  (3) 2025.07.27
[2025백엔드] 헤드퍼스트자바 독서 #3. - 7장. 객체 마을에서의 더 나은 삶  (1) 2025.07.26
[2025백엔드] 헤드퍼스트자바 독서 #2 - 6장. 자바 라이브러리 사용하기  (3) 2025.07.24
[2025 백엔드] 헤드퍼스트자바 독서 #1 - 5장. 메서드를 더 강력하게  (2) 2025.07.23
'언어공부/Java | Kotlin' 카테고리의 다른 글
  • [2025백엔드] 헤드퍼스트자바 독서 #6 - 10장. 숫자는 정말 중요합니다
  • [2025백엔드] 헤드퍼스트자바 독서 #5 - 9장. 객체의 삶과 죽음
  • [2025백엔드] 헤드퍼스트자바 독서 #3. - 7장. 객체 마을에서의 더 나은 삶
  • [2025백엔드] 헤드퍼스트자바 독서 #2 - 6장. 자바 라이브러리 사용하기
윤마치
윤마치
개발을 합니다.
  • 윤마치
    윤마치
    윤마치
  • 전체
    오늘
    어제
    • 분류 전체보기 (211)
      • 신년사 (3)
        • 2025년 (2)
        • 2026년 (1)
      • CS (59)
        • JVM (12)
        • 백엔드 (20)
        • 언어구현 (1)
        • 객체지향 (1)
        • 논리회로 (5)
        • 컴퓨터구조 (9)
        • 데이터베이스 (1)
        • 컴퓨터 네트워크 (10)
      • 언어공부 (64)
        • Java | Kotlin (48)
        • JavaScript | TypeScript (9)
        • C | C++ (6)
      • 개인 프로젝트 (11)
        • [2025] Happy2SendingMails (3)
        • [2026] 골든리포트! (8)
        • [2026] 순수자바로 개발하기 (0)
        • 기타 이것저것 (0)
      • 팀 프로젝트 (29)
        • [2025][GDG]홍대 맛집 아카이빙 프로젝트 (29)
      • 알고리즘 (13)
        • 백준풀이기록 (11)
      • 놀이터 (0)
      • 에러 수정일지 (2)
      • 고찰 (24)
        • CEOS 23기 회고록 (2)
  • 블로그 메뉴

    • 링크

      • 컬러잇 개발블로그
    • 공지사항

    • 인기 글

    • 태그

      144
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.5
    윤마치
    [2025백엔드] 헤드퍼스트자바 독서 #4 - 8장. 심각한 다형성
    상단으로

    티스토리툴바