상속

이유빈
이유빈 |
상속

상속의 형식

class ElectricCar extends Car {
	...
	public void charge(int amount) {
		...
	}
}
  • 상속을 정의하려면 자식 클래스 이름 뒤에 extends를 쓰고 부모 클래스 이름을 적으면 됨
  • extends는 확장(또는 파생)한다는 의미이다
  • 즉, 부모 클래스를 확장하여서 자식 클래스를 작성한다는 의미

왜 상속을 사용하는가

  • 원하는 코드를 가진 클래스가 이미 존재한다면 이 클래스를 상속받아 이미 존재하는 클래스의 필드와 메소드를 재사용할 수 있음
  • 상속을 사용하면 중복되는 코드를 줄일 수 있음

자바 상속의 특징

  • 다중 상속(여러 개의 클래스로부터 상속 받는 것)을 지원하지 않는다
  • 상속의 횟수에는 제한이 없다 (부모 → 자식 → 자식의 자식 → …)
  • 상속 계층 구조의 최상위에는 java.lang.Object 클래스가 있다

상속과 접근 지정자

  • 자식 클래스는 부모 클래스의 public 멤버, protected 멤버, 디폴트 멤버(같은 패키지 일때)를 상속 받음
  • private 멤버는 상속되지 않음
  • protected는 자식 클래스만 접근이 가능

상속과 생성자

  • 자식 클래스의 객체가 생성될 때, 자식 클래스와 부모 클래스의 생성자 모두 호출됨
  • 부모 클래스의 생성자 → 자식 클래스의 생성자 순으로 호출됨
  • 명시적인 생성자 호출
    • 자식 클래스의 생성자에 super(); 작성
  • 묵시적인 생성자 호출
    • 컴파일러는 부모 클래스의 기본 생성자가 자동으로 호출되도록 함
    • 묵시적인 부모 클래스 생성자 호출을 사용하려면 부모 클래스에 기본 생성자(매개 변수가 없는 생성자가)가 반드시 정의되어 있어야 함
    • 인수의 형태에 따라 적절한 생성자가 선택됨
      • super(x, y) ⇒ 부모 클래스의 x, y 인자가 있는 생성자 호출

메소드 오버라이딩

  • 자식 클래스가 부모 클래스의 메소드를 자신의 필요에 맞추어서 재정의 하는 것
  • 메소드의 이름이나 매개 변수, 반환형은 동일해야 함

      class A {
      	int test() { return 1; }
      }
        
      class B extends A {
      	int test(int a) { return 2; }
      }
        
      public class TestClass {
      	public static void main(String[] args) {
      		B test = new B();
      		System.out.println(test.test()); //A의 test()실행됨
      	}
      }  //1 출력
    
    • 철자를 잘못 쓰는 경우, 새로운 메소드 이름으로 인식하여 메소드 오버라이드가 일어나지 않음
      • 방지를 위해 @Override 어노테이션을 붙이는 것이 좋음
      • 부모 클래스에 그런 이름의 메소드가 없다면 컴파일러에 오류 발생
  • 자식 클래스가 부모 클래스의 정적 메소드와 동일한 정적 메소드를 정의하는 경우 어떤 참조 변수를 통하여 호출되는지에 따라 실행되는 메소드가 달리짐
    • 하나는 정적 메소드이고, 다른 하나가 일반 메소드일 경우 오류 발생

키워드 super를 사용하여 부모 클래스 멤버 접근

  • super는 상속 관계에서 부모 클래스의 메소드나 필드를 명시적으로 참조하기 위해 사용됨
    • 만약 부모 클래스의 메소드를 오버라이딩한 경우에 super를 사용하면 부모 클래스의 메소드를 호출할 수 있음
    • 예) super.draw → 부모 클래스의 draw() 호출

오버라이딩과 오버로딩

  • 오버로딩이란 같은 메소드명을 가진 여러 개의 메소드를 작성하는 것
  • 오버라이딩은 부모 클래스의 메소드를 자식 클래스가 다시 정의 하는 것
  • 다형성
    • 이들은 모두 다형성과 관련이 있음
    • 이름을 재사용한다는 것이 같음
    • 오버로딩은 컴파일 시간에서의 다형성을 지원함
    • 메소드 오버라이딩은 실행 시간에서의 다형성을 지원함

다형성

  • 객체들의 타입이 다르면 똑같은 메시지가 전달되더라도 서로 다른 동작을 하는 것
  • 예) 다양한 타입의 도형 객체들이 있을 때 draw 메시지를 보내면, 각 도형의 모습을 화면에 그려냄. 즉, 도형의 타입을 고려하지 않고 draw 메시지를 보내면 됨

업캐스팅

  • 부모 클래스 변수로 자식 클래스 객체를 참조할 수 있음
  • 이것을 업캐스팅이라고 함

Untitled

Shape s1, s2;

s1 = new Shape(); //가능
s2 = new Rectangle(); //가능. 업캐스팅
/* s2.width
s2.height 접근 불가능 */

자식 클래스와 부모 클래스의 포함 관계

Untitled

업캐스팅과 다운캐스팅

public class PhoneTest {

	public static void main(String[] args) {
		Phone[] phones = {
				new Phone("황진이"), 
				new AnsweringPhone("길동이", "내일"),         //업캐스팅
				new SmartPhone("민국이", "저녁때", "갤러그")  //업캐스팅
				};
		
		phones[0].talk();
		((AnsweringPhone)phones[1]).autoAnswering();  //다운캐스팅
		((SmartPhone)phones[2]).playGame();           //다운캐스팅
	}
}
  • 업캐스팅: 자식 객체를 부모 참조 변수로 참조하는 것
    • 업캐스팅은 묵시적으로 수행될 수 있음
    • 부모 클래스의 멤버 접근 가능
    • 자식 클래스의 멤버 접근 불가능
  • 다운캐스팅: 부모 객체를 자식 참조 변수로 참조하는 것
    • 묵시적으로 수행 불가
    • 명시적으로만 가능

동적 바인딩

  • 여러 가지 타입의 객체를 하나의 자료 구조 안에 모아서 처리하려는 경우에 필요
  • 업캐스팅의 활용
    • 메소드의 매개 변수를 부모 타입으로 선언하면 훨씬 넓은 범위의 객체를 받을 수 있음
      public static void printLocation(Shape s) {
      	System.out.println("x=" + s.x + "y=" + s.y);
      }
    

instanceof 연산자

  • 변수가 가리키는 객체의 실제 타입을 알고 싶으면 instanceof 연산자를 사용하면 됨
if (obj instanceof Rectangle)
	System.out.println("실제 타입은 Rectangle");

종단 클래스와 종단 메소드

  • 종단 클래스
    • 상속을 시킬 수 없는 클래스
    • 보안상의 이유로 사용
  • 종단 메소드
    • 서브 클래스에서 재정의할 수 없는 메소드
    • 부모 클래스의 final 메소드는 불러올 수 있음
      class A {
      	final int test() { return 1; }
      }
        
      class B extends A { }
        
      public class TestClass {
      	public static void main(String[] args) {
      		B test = new B();
      		System.out.println(test.test());
      	}
      } //1출력
    

상속과 구성

Untitled

  • 구성은 “클래스가 다른 클래스의 인스턴스”를 클래스의 필드로 가지는 디자인 기법
  • 상속은 한 객체가 클래스를 상속받아서 부모 객체릐 속성과 동작을 획득할 수 있는 기법
  • 상속과 구성은 모두 클래스를 연결하여 코드 재사용성을 제공함
  • 상속과 구성은 객체 지향 개발자가 사용하는 두 가지의 중요한 프로그래밍 기술
  • 상속은 한 클래스를 다른 클래스에서 파생시키는 반면, 구성은 하나의 클래스를 다른 클래스의 합으로 정의함

is-a 관계 “A는 B의 일종이다”

Untitled

has-a관계 “~은 ~을 가지고 있다”

  • 구성 관계 또는 집합 관계를 나타냄

Untitled

  • 구성관계
    • House에는 하나 이상의 Room이 있다. 이것은 구성이다. Room은 House 없이는 존재하지 않으므로 Room의 수명은 House에 의해 제어된다.
  • 집합관계
    • Block을 모아서 ToyHouse를 만들 수 있다. 이것은 집합이다. ToyHouse가 분해되더라도 Block들은 남는다.
      public class A {
      	private B b;
        
      	public A(B b) { this.b = b }
      }
    
이유빈

이유빈

국민대학교 소프트웨어융합대학 소프트웨어학부 이유빈입니다. 링크 아이콘을 클릭해 Github 페이지로 이동할 수 있습니다.

댓글

comments powered by Disqus