16. 상속

Isaiah IM·2023년 7월 18일
0

java basic

목록 보기
18/38
post-thumbnail

1. 상속

1.1 상속이란?

상속이란 기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것이다.

상속은 기존 클래스를 재사용 하는 것으로, 클래스를 상속하면 상속하는 클래스의 기능들을 전부 사용할 수 있다.

예를 들어보자.
Car라는 클래스가 있다 가정하자. 이 Car라는 클래스는 실제로 자동차의 시동을 걸어주는 startUp(), 자동차를 움직이는 drive(), 시동을 끄는 stop(), 경적을 울리는 horn()이라는 메소드가 있다.
이때, 만약 수동 기어변속, 터보모드 등을 추가한 SuperCar 클래스를 만들고 싶다면 두 가지 방법이 있을 것이다.

  • 처음부터 SuperCar를 정의해서 메소드를 넣기
  • 이미 있는 Car클래스를 이용해서 SuperCar클래스 추기하기

상속은 이 두번째 방법을 이용한 것이다.
이미 Car클래스 안에 자동차의 기본기능은 들어가 있으니 거기에다 몇가지 기능을 추가해 원하는 SuperCar클래스를 정의하면 코드를 작성하는 양을 줄일 수 있다.
또한, 이러한 방법이 상속이다. 이때, 이용하려고 하는 Car클래스를 부모 클래스, 새로 만들려고 하는 SuperCar클래스를 자식 클래스라고 한다.
즉, 상속은 부모클래스의 인스턴스(메소드)를 그대로 물려받는다.

1.2 상속의 정의

상속은 자식_클래스 extends 부모_클래스{} 형식으로 작성한다.

상속은 extends키워드를 사용해 자식_클래스 extends 부모_클래스{}형식으로 작성한다.

앞서 설명한 Car클래스를 이용해 코드로 한번 알아보자.
앞서 설명한 바와 같이 Car클래스를 상속해 SuperCar클래스를 만든다고 하면 다음과 같이 코드를 작성할 수 있다.

Car클래스

public class Car {
	boolean startupState;
	float speed;
	
	{// 초기화 블럭
		this.startupState=false;
		this.speed=0.0f;
	}
	
	void startUp() {// 시동걸기
		this.startupState=true;
		System.out.println("시동걸림.");
	}
	
	void drive(float speed) {// 이동
		this.speed=speed;
		System.out.println("속도: "+this.speed+"km");
	}
	
	void stop() {// 브레이크
		this.speed=0.0f;
		this.startupState=false;
		System.out.println("시동끔.");
	}
	
	void horn() {
		System.out.println("빵빵!! 피자빵!! 초코빵!! 크림빵!!");
	}
}

SuperCar클래스

public class SuperCar extends Car {// Car 클래스 상속
	int gearStage;
	int mode;
	
	void manualGearShift(int stage) {
		this.gearStage=stage;
		System.out.println("기어 단수: "+ this.gearStage);
	}
	
	void driveMode(int mode) {
		this.mode=mode;
		
		switch(mode) {
		case 1:
			System.out.println("운전모드: 스포츠");
			break;
			
		case 2:
			System.out.println("운전모드: 컴포트");
			break;
			
		default:
			System.out.println("운전모드: "+ this.mode);
			break;
		}
		
	}
}

이렇게 하면 SuperCar클래스 내에서도 Car클래스의 인스턴스가 상속이 되면서 Car클래스의 메소드를 그대로 사용할 수 있다.

main메소드

public class Main {
	public static void main(String[] args) {
		
		SuperCar lamborghini = new SuperCar();// 람보르기니 ★겟☆또♧다♣제★
		
		lamborghini.startUp();// 부모클래스인 Car클래스 메소드
		lamborghini.drive(100);// 부모클래스인 Car클래스 메소드
		
		lamborghini.horn();// 부모클래스인 Car클래스 메소드
		lamborghini.driveMode(1);// 자식클래스인 SuperCar 클래스 메소드
		lamborghini.manualGearShift(3);// 자식클래스인 SuperCar 클래스 메소드
		
		lamborghini.driveMode(2);// 자식클래스인 SuperCar 클래스 메소드
		lamborghini.stop();// 부모클래스인 Car클래스 메소드
	}
}

output

시동걸림.
속도: 100.0km
빵빵!! 피자빵!! 초코빵!! 크림빵!!
운전모드: 스포츠
기어 단수: 3
운전모드: 컴포트
시동끔.

이러한 관계를 상속 관계도로 나타내면 다음과 같다.

이를 벤다이어그램으로 나타내면 다음과 같이 나타낼 수 있다.

2. 관계 결정

2.1 포함관계

포함관계란 클래스 내부에 다른 클래스를 작성할때 나타나는 관계이다.

만약 원에 대한 정보를 담는 클래스 Circle를 만든다고 가정하면 다음과 같이 작성할 수 있을 것이다.
1. Circle클래스 내에 좌표(x, y)와 반지름 r 변수 선언
2. 좌표(x,y)를 나타내는 클래스를 상속 후 반지름 r 변수 추가

혹은 이와 같은 방법 역시 있다.
3. 좌표(x,y)를 나타내는 클래스를 Circle클래스 내에 선언 후 반지름 r 변수 추가

각 방법을 코드로 나타내면 다음과 같다.

1번 방법

public class Circle {
	int x;
	int y;
	int r;
}

2번 방법

public class Circle extends Point{
	int r;
}
public class Point {
	int x;
	int y;
}

3번 방법

public class Circle{
	Point p = new Point();
	int r;
}
public class Point {
	int x;
	int y;
}

이 세가지 방법은 전부 똑같이 x, y, r을 갖고 있다.
이때, 3번 방법을 Circle 클래스는 Point 클래스를 포함한다 라고 하며, 이를 포함관계라고 부른다.

2.2 상속관계 vs 포함관계

위 글에서 보면 2번인 상속관계와 3번인 포함관계의 차이가 거의 없는것 같아 보일 수 있다. 클래스들의 관계를 설정할때 이렇게 비슷한 상속관계와 포함관계중 선택할 수 있는 방법은 is ahas a라는 방법을 사용할 수 있다.

위의 원을 예를 들면 다음과 같다.

  • is a: 원은 점 좌표이다.
  • has a원은 점 좌표를 갖고(포함하고) 있다.
    둘 중에서 has a가 더 자연스러운 것을 알 수 있다. 이럴때는 포함관계를 설정하면 된다.
    즉, Circle클래스는 Point클래스를 포함하도록(3번방법) 설계하면 된다.

다른 예로 위에서 본 자동차의 예를 들어보도록 하자.

  • is a: 슈퍼카는 자동차다
  • has a슈퍼카는 자동차를 갖고(포함하고) 있다.
    이 문장에서는 is a가 더 자연수러운 것을 알 수 있다. 이럴때는 상속관계를 설정하면 된다.
    즉, SuperCar클래스는 Car클래스를 상속하도록 설계하면 된다.
profile
나는 생각한다. 고로 나는 코딩한다.

3개의 댓글

comment-user-thumbnail
2023년 7월 18일

좋은 글 잘 읽었습니다, 감사합니다.

답글 달기
comment-user-thumbnail
2023년 7월 18일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기
comment-user-thumbnail
2023년 7월 18일

글이 많은 도움이 되었습니다, 감사합니다.

답글 달기