Java 기반 클라우드 융합 개발자 과정 - KH 정보교육원/4월

22. 04. 26 - 상속(super, override), 다형성, 바인딩

giggs 2022. 4. 29. 10:17

 

 

상속 ( super, override ) 

 

 

 

상속이란?

  • - 부모 클래스의 data, method, 받아오는 것.  constructor는 아님

 

 

 

 

 

>새로 생기는 클래스마다 같은 내용의 코드 작성 번거롭다.

>공통된 데이터 / 공통된 기능을 부모에게 몰아넣고 자식들은 상속받아서 사용하도록!

 

 

 

 

 


 

 

 

상속 관계에서 super 와 override

 

 

 

super

  • this 는 자기 자신을 가리킨다.
  • 상속관계에서 super 는 그 객체의 부모를 가리킨다는 것 체크

 

 

 

상속관계에서 super 는 그 객체의 부모를 가리킨다는 것 체크

 

 

용어 체크 ~!

 

 

 

 


 

 

override

  • override : 부모의 함수를 재정의해서 사용하는 것

 

 

 

 

 

 

  • 자식 클래스인 - 피카츄 클래스 안에 - attack() 메소드 없어도 - 부모 클래스인 포켓몬에는 attack() 존재한다.
  • 자식 클래스인 - 피카츄 클래스는 - 포켓몬 클래스 상속받았으므로 attack() 함수 사용 가능
  • 그럼 자식 클래스 피카츄 클래스 안에서 attack() 함수를 똑같이 만들면?
  • 사용 가능!
  • 이렇게 메소드를 다시 정의해서 사용하는 것이 오버라이드~!

 

 

왜 이렇게 사용하는가?

  • 메소드의 head와 body 중 body의 내용이 달라서

 

 

피카츄 객체에서

  • > this.attack() 하면 - 피카츄 어택 호출
  • > super.attack() 하면 - 포켓몬 어택 호출

 

 

이론 끝

 

 

 

 


 

 

 

 

 

상속 ( super, override ) 실습 Start 

 

 

 

 

Super 실습 - 스타트

 

 

 

1. 기본 세팅 - com.kh.car 패키지 - Car 클래스와 Main 클래스 생성

 


 

2. Car 클래스에 모든 자동차가 가지는 특성과 메소드 작성하기

 

 

 

모든 자동차가 가지고있어야할 데이터와 메소드를 만들어 준다.

 

 


 

 

 

3. new Class 생성 RedCar, GreenCar,WhatCar 클래스 생성

 

 


 

 

 

4. Car ( 부모 클래스 ) 의 내용받아오도록 연결시켜준다 extends 키워드로 진행

 

 

extends Car

 

 

+ GreenCar와 + WhatCar에도 진행 -

 

 

 


 

 

 

5. 부모의 메소드 사용 가능한지 테스트 ( 자식 클래스에는 아무 내용도 없는 상태에서 )

 

 

RedCar타입 rc 객체를 생성 후 - > rc . strat( ); . 메서드 호출

 

 

 

  • 레드카를 만들어서 메소드를 실행하였지만
  • 실제로는 부모의 start(); 함수를 호출해서 사용한 것이다.

 

 

 


 

 

 

6. 홍차 고유의 데이터, 메소드 작성

 

메소드 이름은 동사형태로 만들어 준다.

 

 

 

6-1. 메인에서 RedCar 객체에게 메소드 실행 테스트

 

 

 

 

  • RedCar 타입 rc 객체는 start() 메서드와 sayRed() 메서드 둘 다 사용 가능
  • RedCar 클래스에는 - sayRed() 메소드밖에 없지만. 부모의 메소드 start( )도 사용 가능!
  • 부모의 함수 사용 시 실제로 호출되는 것은 super.start() 부모의 메소드이다.

 

 

 

 

 


 

 

 

 

오버 라이딩 실습 - 스타트

 

 

1. RedCar 클래스에 부모의 메소드 start() 와 똑같은 메소드 만들어 준다

 

 

 


 

 

 

2. 이 메소드는 부모의 메소드 재정의한 것이라고 표시가 필요하다.

 

 

@Override 체크!

 

 

 

 

@Override 있어도 - 없어도 에러는 안 난다..

  • 그럼 왜 작성할까요? - [ 1. 사용자에게 ] , [ 2. 컴퓨터에게 ] 알려주려고. 작성한다.
  • 협업자나 다른 사람, 나에게 알려주려고,
  • 컴퓨터한테 에러 판단해달라고 
  • @Override 해준 상태로 부모에게 없는 메소드를 재정의 한다고 사용하면 에러 난다
  • 오버라이드 한다더니 부모 클래스에 그런 메서드 없다고 에러난다

 

 

 

오버라이드 한다더니 - 부모 클래스에는 이런 함수 없는데? 에러남

 

 

 

 


 

 

 

 

3. 메인 메소드에서 RedCar 객체로 start() 호출하면 - 누구의 start() 호출되는지 테스트

 

 

오버라이딩한 함수 start() 호출 테스트!

 

 

  • 오버 라이딩 전에는 부모의 start()가 호출되었는데
  • 오버 라이딩을 해준 후에는 자신의 start()가 호출됨을 확인

 

 

 

상속( super, override ) 끝!

 

 

 

 

 


 

 

 

 

 

다음 진도 시작 

 

 

다형성 ( polymorphism )

  • 용어를 정의하려고 신경 쓰지 말고 코드를 이렇게 짜면 이렇게 되는구나 이해~
  • 부모 클래스가 자식 클래스 받아주는 거라고 이해

 

 

 

 

 

 

 

 


 

 

 

 

 

다형성 실습 - 스타트

 

 

 

1. 메인클래스에서 RedCar를 그냥 Car Car로 변경해보기

 

 

변경 전 - RedCar rc

 


 

변경 후 - Car rc

 

 

  • Car 타입으로 변경해주었는데 에러 안 나고 처리된다.
  • 부모는 자식의 데이터 타입이 와도 너도 나지 라고 처리해준다.

 

 

 


 

 

 

 

2. Car 타입의 rc 객체로 start(); / sayRed(); 출력해보기

 

  • 11번 Line – start(); 자식 클래스의 start 출력됨
  • 12번 Line – 자식 클래스만의 함수 sayRed(); 는 사용 불가능 - ( 현재 Car 타입에 담아주었기 때문에 ) 

 

 

 

 

 

> 정적 바인딩이라고 한다.

  • 실행하기 전에는 정적 바인딩 따라간다(부모 클래스의 start()로 연결된다.) (ctrl 누르고 클릭)
  • 실행되기 전 바인딩

 

> 동적 바인딩이라고 한다.

  • 실행하고 나니 RedCar()에 있는 것이 실행된다 ( RedCar()의 start() 작동된다)
  • 실제 런타임에서의 바인딩

 

 

 

 

 

 

용어에 집중 X / 패스해도된다패스해도 된다. / 어떻게 작동되는지를 이해하는 것을 중점으로 체크!

run타임 시에실제로 호출되는 메소드가 누구의 것인지 알 수 있으면 된다..

 

 

 

 

 


 

 

 

 

 

진도 나가자~

 

Super( ) 생성자와 Object Class 오브젝트 클래스

 

 

 

 

super( ) 생성자

 

 

1. Car 클래스에서 생성자 추가

 

 

 

 

  • 이렇게 해주면 자동차는 태어나는 순간에 3개의 데이터를 받아야 태어날 수 있다.
  • 앞으로 태어나는 모든 Car 들은 데이터를 가지고 태어난다.

 

 


 

 

 

2. 자식 클래스에서 에러 났다..

 

 

 

 

  • 생성자 추가하라고 에러 났다. add constructor 클릭

 

 

 

 

 

 

  • 3개의 입력받은 매개변수를 가지고 - super () 부모 클래스의 생성자를 호출!
  • 7번 Line 이 왜 필요한가? -
  • 부모님 없이 내가 존재할 수 있나? - 없다. -> 객체도 똑같다.
  • 내가 RedCar라는 객체를 만들기 위해서는 그 상위에 부모인 Car객체가 있어야 만들 수 있다.
  • super = Car라고 생각

 

 

 


 

 

 

Object Class

 

 

이런식으로 부모의 데이터에도 접근가능하다

 

이 객체  (RedCar) 의 기본생성자도  this()  이런 식으로 호출 가능

 

기본생성자도 사실은 이런식으로 부모클래스를 생성한 뒤 생긴 것이다 .

 

 

 


 

 

 

부모인 Car 클래스는 상속받은 적이 없는데 부모 클래스가 있나요??

-> 모든 클래스는 - Object 클래스의  자손 클래스이다.

 

 

 

 

Object 클래스를 상속받아 만들어진 Person 클래스

 

 

 

  • 우리가 직접 상속한 적은 없다.
  • java에서는 모든 클래스 파일들은 Object 클래스의 자손 클래스이다.
  • Object 클래스는 모든 클래스 파일들의 조상이다!

 

 

 

 

 

 

 

  • object 클래스를 상속받은 Car 클래스 존재 – Car클래스를 상속받은 RedCar
  • 부모의 데이터/기능들 다 사용할 수 있다.
  • Object 클래스를 상속받은 Car클래스는 Object 메소드 사용할 수 있고,
  • Car 클래스를 상속받은 RedCar 클래스도 Object 메소드 사용할 수 있다.
  •  
  • 부모 자식 관계는 많이 맺을 수 있다.
  • Object 는 모든 클래스의 부모이다.
  • 여러 명의 부모를 가질 수 있다? - NO! (extends 로는 불가능 – interface로 대체는 가능)

 

 

 

 

+@ 여러 가지 사례 체크

 

 

 

 

  • 부모의 기본 생성자가 있다면 이렇게도 만들어진다.
  • 부모의 기본 생성자를 호출하는 것이다.
  • 대신 입력받은 인자 값을 가지고 태어나지는 않는다. 

 

 

 


 

 

 

 

게터 세터와 함께 지금까지 만든 거 실행해보자 - 총정리 -

 

 

 

1. 부모 Car 클래스에 기본 생성자 만들어 주기.

 

 

 

 

 


 

 

 

2. 레드카 클래스처럼 – 그린카/왓카에도 – 상속처리해주고, 생성자 만들기

 

 


 

 

3. 그린카에게도 그린카만의 특별한 기능 추가해주자.

 

4. 왓카에도 특별한 기능 추가

 

 

그린카, 왓카에 - 각자의 기능 추가

 

 


 

 

 

5. 메인 클래스에서 객체 생성 후 메소드 호출 테스트

 

 

startCar( ) 함수를 재정의한 RedCar만 자신의 것으로 출력됨을 확인

 

 

 

  • 메소드 오버라이딩한 홍차의 경우에만 자신의 메소드가 호출되어서 출력
  • 메소드 오버 라이딩하지 않은 그린카/왓카의 경우에는 부모의 메소드 호출되어서 출력

 

 

 


 

 

 

6. 그린카 / 왓카에도 startCar() 함수 - @Override 해주자

 

 

메소드 오버라이딩

 

 


 

 

 

 

7. 메인에서 다시 출력 테스트~

 

부모의 메소드가 아닌 오버로딩한 자신만의 메소드로 호출됨을 확인

 

 

 

 


 

 

 

8. 각각의 차들의 데이터들도 확인해보자

  • private라서 get/set 메소드를 만들어 준 뒤 사용해야 한다.
  • Car 클래스에서 겟셋해주자

 

 

부모 Car 클래스에서 getter / setter 만들어 준다.

 

 

 


 

 

 

 

9. -셋 해준 걸로 메인에서 출력 테스트

 

9-1 생성자가 없다고 - 자식 클래스 에러 발생 - 생성자 만들어주어서 해결 -

 

 

자식인 RedCar 객체를 만들기 위해선 부모인 Car 객체가 먼저 생성되어야한다.

 

 

 

>RedCar 객체를 만드려고 했더니 부모의 생성자 만들어야 한다부모의 생성자를 호출해야 한다..

>부모의 인자를 받는 생성자에 RedCar만들 때 받은 인자 값을 전달해서

>이 값들로 세팅된 Car객체가 태어난 것이고 ( color / speed / price를 가지고 있는 객체)

>Car 객체를 확장하는 의미 - extends ( 상속하는 의미! )

 

 

 

 

Car rc = new RedCar() 부분 체크

 

 

 

 

> Car 타입으로 만들어줬는데도 RedCar의 startCar() 메소드 출력됨을 확인!

 

 

 

Car 타입에 넣어준 rc 를 이용해서 startCar() 함수를 호출 - 결과 체크

 

 

 

> RedCar 객체가 생성되어서 들어가는 것이 아니라

> Car객체를 생성하고 RedCar객체를 확장(생성)하는 것이었구나.

 

 

 

 

 

 

 

 


 

 

 

## 여기서부터는 추가 설명 부분 

 

 

> 상속관계에서의 자식 객체 생성되는 방식

 

 

1. super 클래스인 Car 객체를 먼저 생성

 

 

new RedCar() 객체 생성했을 때의 상황 체크

 

 

 

 

 

  • Car 클래스 상속받은 RedCar extends Car
  • new RedCar() 하면 - 인자 값없는 RedCar 생성자가 호출되는 것인데
  • 그동안 우리 눈에 보이진 않았지만 Car() 생성자를 호출하는 과정이 있었다.
  • why? 부모가 있어야 자식이 있다.
  • Car가 생기고 RedCar가 생기는 것이다.

 

 

 


 

 

 

2. extends 확장하다

 

 

 

먼저 만든 Car 객체를 바탕으로 RedCar 객체로 확장해 주는 것이다!

 

 

 

 

 

+@ 그럼 부모 클래스인 Car 객체는 어떻게 생기는 건가요?

  • Car 객체가 생기는 것은 object객체를 확장한 것!

 

 

 

 

>내 이해

 

  • new RedCar(String color, int speed, int price){
  • super(color, speed, price; }
  •  
  • 하면은
  • Car객체를 만들고 그것을 상속받는 [ 객체 생성 – 상속 ]의 작업이라고 이해했었는데 - X
  • Car객체를 만들고 / Car 객체를 확장해서 RedCar객체를 만든다.
  • [ 객체생성 – 객체생성 ]의 작업이 이루어지는 거라고 이해 

 

 

 

 


 

 

 

바인딩

 

  • 동적 바인딩(Dynamic) vs 정적 바인딩(Static)
  • 디지몬 게임에서 - static int getRandom(..); 이런 친구들은 정적 바인딩
  • 상속 관계에 놓인 객체 -> 그 객체를 이용해서 메소드 호출 -> 결과가 A클래스 메소드 호출되어야 할 것 같은데
  • -> B클래스 메소드가 호출되는 관계 -> runTime시에 달라지는 것 동적 바인딩

 

 

 

 

 


 

 

 

## 총정리

 

 

1. 상속

  • 정의: 부모 클래스의 data, method, constructor 받아옴 (생성자는 안 받아오는 것으로 수정)
  • //부모 객체가 존재해야 자식 객체도 존재할 수 있음
  • 사용법 : extends
  • * 모든 클래스의 제일 위의 부모는 Object 클래스이다.

 

2. 오버라이드

  • 정의 : 부모 클래스의 메소드 재정의(==메소드의 바디 부분을 다시 작성하는것)
  • 작성법 : 오버라이드 하려는 메소드 위에다가 @Override 라고 적기

 

3. 다형성

  • * 부모 클래스 타입으로 자식 클래스 타입의 객체를 받을 수 있다.
  • ex) Car c = new RedCar();

 

4. 바인딩 (뭔지 몰라도 됨. 이런저런 용어가 있구나 하고 넘기면 됨)

  • 정적 바인딩
  • 동적 바인딩

 

5. super

  • super는 부모를 가리키는 키워드
  • (this 는 자기 자신을 가리키는 키워드)

 

6. getter/setter

  • priavate 필드 (==전역변수 == 인스턴스 변수 == 객체 변수 == 멤버 변수 == 클래스 변수)
  • 접근 제한자가 private 인 애들을 편법으로 사용하기 위해서 만드는 메소드

 

 

 

 


 

 

 



review


실습 부분에서 신기했던 부분이 있어서
실습 부분도 다 정리하려다 보니
글이 너무 길어졌다. ㅎㅎ

오늘 배운 내용은 마지막 총 정리 부분을 보고
정리하면 될 듯하다 :)

실습 부분에서 Car타입으로 담아둔
RedCar() 타입 rc 객체를 이용해서
rc.startCar() 메소드를 호출해보았는데
내 예상과는 다르게 RedCar의 함수가 호출되었다.
신기했다.
sub 클래스에서 오버 로딩한 함수는
sub class의 함수가 호출되는 듯!

그리고 C++ 과는 다르게 
sub -> super 클래스로 갔다가 다시 sub클래스로 형 변환해줘도
에러가 안나는 것을 확인하였다. 
java에서는 sub -> super 클래스로 형 변환 시
데이터 유실이 안 되는 듯

super의 활용과 의미에 대해서도 더 자세히
알 수 있어서 좋았다.