본문 바로가기

프로그래밍 언어 기초/JAVA

Chapter 6. 상속(Inheritance)

6. 상속(Inheritance)이란?

 자바에서는 클래스간에 서로 부모-자식의 관계를 설정할 수 있습니다. 예를 들면 Fruit이라는 클래스를 만들었는데, 이 클래스를 계승하는 Apple이나 Orange 같은 클래스를 만들어서 명시적으로 이 클래스들은 부모-자식 관계라는 것을 설정할 수 있습니다. 물론 이런 관계 설정은 필수적인 것이 아닙니다. 그러나 자바에서는 만약 클래스에 부모-자식 관계를 설정하지 않으면 Object라는 클래스를 자동으로 상속받게 됩니다. 주로 최상위 부모 클래스에서 이 원칙이 적용되는데, 그 어떤 부모 클래스도 결국은 Object라는 클래스를 상속받은 클래스라는 것이죠. 자바에서 이런 관계를 설정한 것은 객체지향 프로그래밍과 관련이 있는데 이 부분은 나중에 객체지향 프로그래밍 챕터에서 다루도록 하겠습니다.

 

 자바에서 클래스간에 상속은 extends라는 키워드를 통해서 할 수 있습니다. 만약 Fruit이라는 부모 클래스를 만들고 Apple이라는 자식 클래스를 만들었다면 Apple extends Fruit 이런 식으로 작성할 수 있다는 것이죠.

 

 또한, 부모 클래스를 상속받은 자식 클래스의 인스턴스는 자료형을 부모 클래스로 할 수 있습니다. 그러나 그렇게 생성된 변수는 자식 클래스에서만 작성된 메서드에는 접근할 수 없는 제약사항이 있습니다.

 

자세한 문법은 아래의 코드 소스를 참고해주세요!

 

부모클래스의 생성

public class Parent { 
	// 아무것도 작성되어 있지 않지만, 이 클래스는 자동으로 Object를 상속받게 된다.
	// 따라서 이 부모 클래스도 Object 클래스의 메서드나 변수 등을 이어받아 사용할 수 있다.
	
	int id;
	int password;
		
	int plus(int value1, int value2) {
		int result = value1 + value2;
		return result;
	}
	
	// 대표적인 Object 클래스의 메서드이자
	// Overriding을 통해 재사용하는 메서드
	@Override
	public String toString() {
		return this.id+" / "+this.password;
	}
		
}

 

자식 클래스의 생성

public class Child extends Parent{ // extends를 통해 부모-자식 관계를 설정 가능하다.
	
	int age; // 자식 클래스가 갖는 별도의 필드도 선언 가능!
	
	void call() { 
		// 부모 클래스의 변수나 메서드를 호출해서 사용할 때에는 super 키워드를 사용한다.
		// 소스코드에 id나 password를 작성하지 않았는데도 부모클래스의 변수를 사용할 수 있다.
		System.out.println("ID "+super.id 
				+ ", PW : "+super.password 
				+ ", age : "+this.age);
	}
}

 

각 클래스들의 인스턴스 생성 및 테스트

public class InheritanceTest {

	public static void main(String[] args) {
		
		Parent p1 = new Parent();
		Child c1 = new Child();		
		
		p1.id = 33; 
		p1.plus(1, 2);
		// p1.call(); // 부모 클래스는 자식 클래스의 메서드를 사용할 수 없다.
		
		
		// 자식클래스에서도 부모 클래스의 필드에 접근 가능
		c1.id = 33;
		c1.plus(1, 2); // 부모 클래스의 메소드도 사용 가능
		c1.call(); // 자식 클래스에서 작성한 메서드
		
		// 자식클래는 자료형을 부모 클래스로 할 수 있다.
		Parent p2 = c1;
		// p2.call(); // 인스턴스가 자식 클래스를 통해 생성되었어도 자식클래스의 메서드를 사용할 수 없다.
		
		// 역은 성립 X
		// Child c2 = p1; // 컴파일 오류 발생!

	}

}

 

 

 자바에서 상속은 단일 상속입니다. 말 그대로 각 클래스는 하나의 클래스만 상속받을 수 있습니다. 만약 AppleFruit을 상속받았다면 다른 부모 클래스는 상속받을 수 없게 됩니다. 프로그래밍 언어에 따라서 다중상속을 지원하기도 하지만, 자바는 단일 상속으로 엄격히 제한해 두었습니다. 예시 상황을 들어 보도록 하겠습니다. 개발자가 Animal이라는 부모 클래스를 상속받는 Cat이라는 클래스를 만들었다고 합니다. 그런데 개발자가 이 Cat이라는 클래스에 정이 들어서 나의 클래스다라는 것을 확실히 하고 싶어 MyCat이라는 부모 클래스를 만들었다면, 자바에서는 이 개발자는 CatMyCatAnimal 클래스를 모두 상속받을 수 없습니다. 둘중 하나를 반드시 선택해야 하죠. 자바에서 이렇게 단일 상속만 지원하는 데에는 사실 이유가 있습니다. 이 또한 객체지향 프로그래밍 챕터에서 별도로 다뤄보도록 하겠습니다.

 

 

다른 부모 클래스

package com.tstory.chap6;

// 다른 부모 클래스	
public class Parent2 {
	
	int PID;
	
	int getPID() {
		return PID;
	}

}

 

다중상속 시도

public class Child extends Parent, Parent2{ // 컴파일 오류 발생! 
	// extends Parent extends Parent2 등으로 바꿔도 컴파일 오류는 발생...
	
    ...(중략)
}

 

 

 자바에서 부모 클래스를 상속받는다는 것은 단순히 부모-자식 관계를 의미상으로 설정하는 것이 아니라, 부모 클래스에서 이미 작성된 메서드를 사용하면서 동시에 추가적인 기능도 같이 사용할 수 있기에 합리적입니다. 예를 들어 1+2와 같은 단순한 덧셈 기능이 필요한 클래스가 있는데, 이걸 다른 개발자가 이미 구현했다면 그것을 가져다 쓰는 것이 시간도 절약하고 다른 기능들에 집중해서 시간을 더 효율적으로 쓸 수 있겠죠. 그러므로 자바의 상속은 객체지향 프로그래밍을 실현하는 데 중요한 기술중 하나입니다.

 

public class InheritanceTest {

	public static void main(String[] args) {
		
		Parent p1 = new Parent();
		Child c1 = new Child();		
        
		c1.plus(1, 2); // 부모 클래스 메서드
		c1.call(); // 자식 클래스에서 작성한 메서드
        
        // 자식 클래스에서 plus라는 메서드가 필요하다면,
        // 자식 클래스에 또 작성할 필요 없이 부모 클래스의 메서드를 사용하면 됨!
		
	}
}