• 카테고리

    질문 & 답변
  • 세부 분야

    프로그래밍 언어

  • 해결 여부

    해결됨

객체 생성 및 생성자 질문드립니다.

23.05.29 19:02 작성 23.05.29 19:02 수정 조회수 336

1

안녕하세요 나도코딩님

선생님의 강의를 들으면서 모르는것들을 하나하나 곁가지 치듯이 검색하면서 알아보던 도중에

CHAT GPT에 인터페이스 관련으로 질문하면서 공부하다가 아래의 코드를 보게되었습니다.

// 인터페이스 정의

public interface Drawable {

void draw(); // 추상 메서드 선언

}

// 인터페이스 구현

public class Circle implements Drawable {

@Override

public void draw() {

System.out.println("원을 그립니다.");

}

}

public class Rectangle implements Drawable {

@Override

public void draw() {

System.out.println("사각형을 그립니다.");

}

}

// 사용 예시

public class Main {

public static void main(String[] args) {

Drawable circle = new Circle();

circle.draw(); // "원을 그립니다."

Drawable rectangle = new Rectangle();

rectangle.draw(); // "사각형을 그립니다."

}

}

여기서 제가 이해가 되지 않는 부분이

Drawable circle = new Circle();

위의 부분인데요

객체를 생성할때에는

A a = new A();

이처럼 작성하는걸로 알고있는데

왜 저기에서는 B a = new A();

이런식으로 되어있는지 궁금합니다.

구글에 검색을 많이 해봤는데 이해가 안되더라구요

ㅠㅠ

답변 부탁드립니다!!

답변 1

답변을 작성해보세요.

1

안녕하세요?

먼저 chatGPT 의 답변을 한 번 들어볼까요? 😉

chatGPT 답변 내용

이 코드에서 Drawable circle = new Circle();은 다형성의 개념을 활용한 것입니다.

인터페이스인 Drawable은 draw()라는 추상 메서드를 가지고 있습니다. 이 인터페이스를 구현한 클래스인 Circle과 Rectangle은 draw() 메서드를 구현해야 합니다.

다형성을 이용하면 인터페이스 타입으로 선언된 변수에 해당 인터페이스를 구현한 클래스의 객체를 할당할 수 있습니다.

Drawable circle = new Circle(); 코드에서 Drawable은 인터페이스 타입이며, circle 변수는 Drawable 인터페이스 타입으로 선언되었습니다. 그리고 new Circle()는 Circle 클래스의 객체를 생성하는 것입니다.

자바에서는 인터페이스 타입의 변수에 해당 인터페이스를 구현한 클래스의 객체를 할당하는 것이 가능합니다. 이렇게 하면 인터페이스의 메서드를 호출할 수 있고, 실제로는 해당 클래스의 구현된 메서드가 실행됩니다.

따라서 Drawable circle = new Circle();에서 circle 변수는 Drawable 인터페이스 타입으로 선언되었지만, 실제로는 Circle 클래스의 객체를 참조하고 있으므로 circle.draw()를 호출하면 "원을 그립니다."라는 출력이 나옵니다.


와, 역시 설명이 훌륭하네요!

간단한 코드이긴 하지만 모든 내용을 이해하고 질문도 제대로 파악하여 좋은 답변을 1초만에 보여주네요.
질문자분께서는 chatGPT 를 정말 잘 활용하고 계십니다 👍

우선 다형성에 대해서 이해가 필요합니다. 강의에서도 다뤘지만 객체 지향 프로그래밍 언어를 처음 공부하게 되면 누구나 헷갈리는 개념이에요. 다형성이란 말 그대로 다양한 형태를 띄는 것인데요.

예를 들어서 추운 겨울에는 강아지들도 산책을 할 때 바닥이 너무 차가워서 신발을 신는 경우가 있습니다. 강아지를 100 마리나 키우는 어떤 주인이 산책을 가기 위해 강아지들에게 신발을 신긴다고 가정해볼게요.

이 분은 이제 신발 신기기에는 도가 터서 눈을 감고도 할 수 있습니다.
1번 강아지, 2번 강아지, ... 101번 강아지.

어?

분명 산책을 나갈 강아지는 100 마리인데 신발을 다 신기고 보니까 101번을 신겼던 거에요. 알고 보니까 집 밖에 있던 고양이가 한마리 들어와서 강아지들 속에 껴 있었던 겁니다. (물론 이럴 일은 일어나지 않을 겁니다 🤣) 이 주인은 강아지 신발 신기기의 대명사인데 중간에 고양이가 한마리 껴도 아무런 문제 없이 신발을 신겼습니다

어떻게 이게 가능했을까요?

정답은 바로 다리에 있습니다.
개와 고양이는 모두 다리가 4개라서 주인은 아무런 의심 없이 신발을 신겼던 거죠.

 

며칠 뒤에는 소문이 퍼져서 온동네 주민들이 다 몰려듭니다.

"우리 토끼도 신발 좀 신겨줘요"
"우리 여우도 신발이 필요해요"
"우리 늑대도 가능할까요?"
"저희 집에 호랑이가 한마리 있는데요"

너도나도 할 것 없이 모두 다리 4개인 동물들을 데리고 와서 신발을 신겨 달라고 부탁한 것이죠. 그런데 사실 아무런 문제가 없습니다. (호랑이는.. 음..) 요청받은 동물들의 다리는 모두 4개이며 위치도 모두 다 비슷하거든요.

이게 바로 다형성입니다.

처음에는 강아지 신발만 신겼지만 어느새 고양이, 토끼, 여우, 늑대, 심지어 호랑이까지. 그저 다리가 4개인 동물이다라고 하면 아무런 문제 없이 그냥 신발을 신길 수 있게 된 것입니다.

 

그러면 이 주인분에게는 강아지 신발 신기기 달인이 어울릴까요? 아니면 고양이 신발 신기기 달인 이 어울릴까요?

먼저 코드로 적어보면 이렇게 될 것 같아요.

DogShoes dogShoes = new DogShoes(); // 강아지 신발 신기기
CatShoes catShoes = new CatShoes(); // 고양이 신발 신기기

그러면 DogShoes 와 CatShoes 클래스는 각각 있어야겠네요?

public class DogShoes {
    public void wearShoes() {
        System.out.println("강아지 신발을 신겨요");
    }
}

public class CatShoes {
    public void wearShoes() {
        System.out.println("고양이 신발을 신겨요");
    }
}

그리고 강아지 10마리와 고양이 10마리의 신발을 신기려면 이렇게 해야겠습니다.
(아직 리스트를 공부하지 않으셨다면 그냥 여러 자료를 한 번에 관리하기 위한 어떤 것이라고만 이해해주세요)

ArrayList<DogShoes> dogShoesList = new ArrayList<>();
// ... 신발 신을 강아지 목록 추가 ...

ArrayList<CatShoes> catShoesList = new ArrayList<>();
// ... 신발 신을 고양이 목록 추가 ...

강아지용 리스트와 고양이용 리스트를 따로 만드는 것이죠.

만약 토끼, 여우, 늑대 등의 동물도 신발을 신겨야 한다면 각각 리스트를 또 만들어줘야 할 것입니다.

 

하지만 제가 볼 때는 앞의 별명보다는 다리 4개인 동물 신발 신기기 달인이 더 어울릴 것 같습니다. 다리가 4개인 동물이라면 종류는 상관 없이 신발을 신길 수 있으니까요.

편의상 FourLegsAnimalShoes 라는 이름의 인터페이스로 만들어볼까요?

public interface FourLegsAnimalShoes {
    void wearShoes();
}

그리고 DogShoes 와 CatShoes 는 FourLegsAnimalShoes 인터페이스를 구현하도록 합니다.

public class DogShoes implements FourLegsAnimalShoes {
    ...
}

public class CatShoes implements FourLegsAnimalShoes {
    ...
}

그럼 이제 다음과 같이 코드를 작성할 수 있게 되는 거에요. 다형성에 의해서 말이죠.

FourLegsAnimalShoes dogShoes = new DogShoes(); // 강아지 신발 신기기
FourLegsAnimalShoes catShoes = new CatShoes(); // 고양이 신발 신기기

이 방법으로 강아지 10마리와 고양이 10마리의 신발을 신기려면 어떻게 할 수 있을까요?

ArrayList<FourLegsAnimalShoes> fourLegsAnimalShoesList = new ArrayList<>();
// ... 신발 신을 강아지, 고양이 목록 추가 ...

이번에는 리스트를 하나만 만들면 됩니다. 다형성에 의해서 가능한 일이죠.

강아지, 고양이 뿐만 아니라 다리가 4개인 모든 동물을 이 리스트 하나로 관리할 수 있게 됩니다. 서로 다른 동물의 종류만큼 리스트를 관리할 필요가 없으니 엄청 편리하죠?


바로 이겁니다.

처음 질문 주셨던 Drawable 인터페이스, 그리고 이를 구현하는 Circle 과 Rectangle 은 다형성에 의해

Drawable circle = new Circle();
Drawable rectangle = new Rectangle();

와 같이 사용할 수 있게 되는 것입니다.

Circle circle = new Circle();
Rectangle rectangle = new Rectangle();

물론 이렇게 할 수도 있지만 다형성에 의해 Drawable 하나로 모두 처리가 가능해지는 것이죠.

강아지, 고양이 예제와 비슷하게 Drawable 인터페이스를 구현하는 도형의 종류가 굉장히 많고 모두 draw() 메소드를 호출해야 한다면 Circle, Rectangle 각각의 리스트로 만들기보다는 Drawable 리스트 하나로 관리하는 것이 훨씬 편리할 겁니다.

다소 설명이 길었지만 다형성의 개념, 그리고 이 문장을 어떻게 사용할 수 있게 되었는지 이해하시는 데 도움되길 바라겠습니다 😊

Drawable circle = new Circle();

 

그리고 사실 아래의 문장은

ArrayList<FourLegsAnimalShoes> fourLegsAnimalShoesList = new ArrayList<>();

다형성에 의해 이렇게 바꿀 수도 있답니다.

List<FourLegsAnimalShoes> fourLegsAnimalShoesList = new ArrayList<>();

ArrayList 가 List 인터페이스를 구현하거든요 😉
감사합니다.

SHYU님의 프로필

SHYU

질문자

2023.05.31

제가 아직 ArrayList 와 List를 배우지 못하였고 현재 기본 개념들이 혼동되는 부분들이 많이 있어 헷갈리는 개념들을 정립하고 다시 이해해보도록 노력해보겠습니다!

그리고 나서 해당 답변 해주신 부분에서 이해가 안되는 부분에 대해

답글로 또 질문 좀 드리도록 하겠습니다. (이해가 된다면 답글 안드릴게요!!) ㅠㅠ

답변해주셔서 정말 감사합니다.

 

SHYU님의 프로필

SHYU

질문자

2023.06.03

다형성 한번 개념 잡으니

이해 완료 하였습니다.

감사합니다!!