상속이란 기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것이다.
상속은 기존 클래스를 재사용 하는 것으로, 클래스를 상속하면 상속하는 클래스의 기능들을 전부 사용할 수 있다.
예를 들어보자.
Car
라는 클래스가 있다 가정하자. 이 Car
라는 클래스는 실제로 자동차의 시동을 걸어주는 startUp()
, 자동차를 움직이는 drive()
, 시동을 끄는 stop()
, 경적을 울리는 horn()
이라는 메소드가 있다.
이때, 만약 수동 기어변속, 터보모드 등을 추가한 SuperCar
클래스를 만들고 싶다면 두 가지 방법이 있을 것이다.
SuperCar
를 정의해서 메소드를 넣기Car
클래스를 이용해서 SuperCar
클래스 추기하기상속은 이 두번째 방법을 이용한 것이다.
이미 Car
클래스 안에 자동차의 기본기능은 들어가 있으니 거기에다 몇가지 기능을 추가해 원하는 SuperCar
클래스를 정의하면 코드를 작성하는 양을 줄일 수 있다.
또한, 이러한 방법이 상속이다. 이때, 이용하려고 하는 Car
클래스를 부모 클래스
, 새로 만들려고 하는 SuperCar
클래스를 자식 클래스
라고 한다.
즉, 상속은 부모클래스의 인스턴스(메소드)를 그대로 물려받는다.
상속은 자식_클래스 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
운전모드: 컴포트
시동끔.
이러한 관계를 상속 관계도로 나타내면 다음과 같다.
이를 벤다이어그램으로 나타내면 다음과 같이 나타낼 수 있다.
포함관계란 클래스 내부에 다른 클래스를 작성할때 나타나는 관계이다.
만약 원에 대한 정보를 담는 클래스 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번인 상속관계와 3번인 포함관계의 차이가 거의 없는것 같아 보일 수 있다. 클래스들의 관계를 설정할때 이렇게 비슷한 상속관계와 포함관계중 선택할 수 있는 방법은 is a
와 has a
라는 방법을 사용할 수 있다.
위의 원을 예를 들면 다음과 같다.
is a
: 원은 점 좌표이다.has a
원은 점 좌표를 갖고(포함하고) 있다.has a
가 더 자연스러운 것을 알 수 있다. 이럴때는 포함관계를 설정하면 된다.Circle
클래스는 Point
클래스를 포함하도록(3번방법) 설계하면 된다.다른 예로 위에서 본 자동차의 예를 들어보도록 하자.
is a
: 슈퍼카는 자동차다has a
슈퍼카는 자동차를 갖고(포함하고) 있다.is a
가 더 자연수러운 것을 알 수 있다. 이럴때는 상속관계를 설정하면 된다.SuperCar
클래스는 Car
클래스를 상속하도록 설계하면 된다.
좋은 글 잘 읽었습니다, 감사합니다.