자바의 상속에 대해서 알아보자!

학습목표 : 자바의 상속에 대해서 이해해보자!

상속(inheritance)

상속이란?

기존의 클래스를 재사용하고 확장하여 새로운 클래스를 작성하는 것이다.

상속의 장점

  • 상속을 통해 클래스를 작성하면 적은 양의 코드로 새로운 클래스 작성이 가능하다.
  • 코드를 공통적으로 관리할 수 있어서 코드의 추가 및 변경이 더 쉽다.
  • 코드의 중복을 제거해서 재사용성을 높이고 프로그램의 생산성과 유지보수에 크게 기여한다.

상속 구현하는 방법

새로 작성하려고하는 클래스 이름 뒤에 ‘extends’키워드와 상속 받고자하는 클래스 이름을 적어준다.

상속해주는 클래스를 ‘부모 클래스(super 클래스)’, 상속 받는 클래스는 ‘자식 클래스(sub 클래스)’라고 한다.

class Child extends Parents{
	//...
}

Untitled%20dbe0ea5ce57b4a85b12af66360c0f6d5/Untitled.png

  • 생성자와 초기화 블럭은 상속되지 않는다. 맴버(변수,메서드)만 상속된다.
  • 자식 클래스의 맴버 개수는 부모 클래스보다 항상 같거나 많다.
  • 부모 클래스가 변경되면 자식 클래스에 자동적으로 적용되지만, 자식클래스의 변경사항은 부모 클래스에 아무런 영향을 주지 않는다.

자바 상속의 특징

  1. 단일 상속

    객체지향언어 C++과는 다르게 자바는 하나의 클래스만을 상속받을 수 있기 때문에 신중하게 상속받아야한다.

    다중상속을 허용하면 클래스간의 관계가 복잡해지고 서로 다른 클래스로부터 상속받은 맴버간의 이름이 같은 경우 어떤 것을 사용해야 할지 구별할 수 있는 방법이 없다. (아래의 맨 오른쪽 그림과 같이)

    이러한 문제 때문에 자바는 다중 상속을 지원하지 않는다.

    Untitled%20dbe0ea5ce57b4a85b12af66360c0f6d5/Untitled%201.png

  2. 부모 클래스를 가진 자식클래스도 다른 클래스의 부모 클래스가 될 수 있다.

    Untitled%20dbe0ea5ce57b4a85b12af66360c0f6d5/Untitled%202.png

  3. 모든 클래스의 가장 위에 있는 부모 클래스는 Object이므로 모든 클래스는 직,간접적으로 Object클래스를 상속받고 있다.

    Untitled%20dbe0ea5ce57b4a85b12af66360c0f6d5/Untitled%203.png


Object 클래스

모든 클래스 상속계층도의 최상위에 있는 조상 클래스이다. 컴파일러가 다른 클래스로부터 상속 받지 않는 클래스에 자동으로 ‘extends Object’를 추가하여 Object클래스를 상속받도록 한다. 이렇게 함으로써 모든 클래스의 조상이 ‘Object’가 되도록 한다.

즉, 모든 클래스는 Object 클래스에 정의 된 모든 멤버(변수, 메소드)를 자유롭게 사용할 수 있음을 의미한다.

다형성(Polymorphism)이란?

여러 형태를 받아들일 수 있는 성질이다. 즉, 다형성이란 하나의 타입에 여러 객체를 대입할 수 있는 성질이다.

  • 다형성을 활용하는 이유는?

다형성을 활용하면 기능을 확장하거나, 객체를 변경해야할 때 타입 변경 없이 객체 주입만으로 수정 할 수 있다. 그리고 상속으로 중복되는 코드까지 제거할 수 있으므로 더 객체 지향적으로 설계할 수 있다.

즉, 코드의 중복을 줄이면서 변경과 확장에 유연한 객체 지향적인 코드를 작성하기 위해서 사용한다.

  • 다형성을 구현하려면?

여러 객체들의 공통 특성을 추출해 타입으로 추상화하고 그것을 상속(인터페이스라면 구현)해야한다.


Method Dispatch

메소드 디스패치란 어떤 메소드를 호출할지 결정하여 해당 메서드를 실행시키는 과정을 말한다.

크게 2가지 타입이 있다.

time

1. 정적 (Static)

‘컴파일 시점’에 호출 할 메서드를 알 수 있으면 정적이라고 한다.

2. 동적 (Dynamic)

Dynamic Method Dispatch

‘런타임 시점’에 호출 할 메서드를 알 수 있으면 동적이라고 한다.

즉,컴파일 타임이 아닌 런타임시점에 어떤 객체의 메소드를 사용할지 결정하는 것을 뜻한다.

주로 다형적인 코드를 작성할 때 발생한다.


메서드 오버라이딩(Overriding)

오버라이딩이란?

자식 클래스가 부모 클래스에서 상속받은 메서드의 내용(구현부)을 변경하는 것이다.

오버라이딩의 조건

  • 상속 관계에서 성립한다.
  • static 키워드로 선언된 메소드의 경우 static 메모리에서 관리하기 때문에 상속이 불가능 하므로 오버라이딩 되지 않는다.
  • final 키워드로 선언된 메소드의 경우 오버라이딩이 불가능하다.
  • 선언부(반환타입, 메서드 이름, 매개변수)가 부모 메서드와 일치해야 한다.

    다만, 접근 제어자(access modifier)와 예외(Exception)는 아래와 같은 조건 하에서 변경할 수 있다.

    1. 접근 제어자는 부모 클래스의 메서드보다 좁은 범위로 변경할 수 없다.

      public > protected > default > private

    2. 부모 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.

      [주의!] - throws Exception은 모든 예외의 최고 조상이므로 가장 많은 개수의 예외를 선언하는 것이다.

    3. 인스턴스 메서드를 static 메서드로 or 그 반대로 변경할 수 없다.

오버로딩 vs 오버라이딩

  • 오버로딩

매개변수의 타입 or 개수가 다른 동일한 이름의 새로운 메서드를 정의하는 것이다. (new)

  • 오버라이딩

상속받은 클래스의 메서드의 내용을 변경하는 것이다. (change)


super 키워드란?

  • super - ‘참조변수’

상속 관계에서 부모 클래스를 가리키는 ‘참조변수’이며, 부모 클래스의 멤버(멤버변수,메서드)에 접근하기 위해서 사용한다.

상속받은 멤버와 자신의 클래스에 정의된 멤버의 이름이 같을 때 super를 붙여서 구별해 줄 수 있다.

static메서드(클래스 메서드)는 인스턴스와 관련이 없다. 그래서 this와 마찬가지로 super역시 static에서는 사용할 수 없고 인스턴스메서드에서만 사용할 수 있다.

  • super() - ‘부모 클래스의 생성자’

부모 클래스의 생성자를 호출하기 위해 사용된다.

자식 클래스는 부모 클래스를 포함하고 있기 때문에 자식 클래스의 인스턴스를 생성할 때 부모 클래스의 생성자도 호출하여 부모 클래스의 멤버를 초기화해야한다.

그래서 자바에서는 어떤 인스턴스를 생성하면, 그 인스턴스가 포함하고 있는 부모 클래스의 기본 생성자(super())를 자동으로 실행하도록 되어 있다.

this()와 마찬가지로 매개변수를 넣어주면 해당하는 매개변수를 갖고있는 부모 클래스의 생성자가 호출 된다.


추상 클래스(abstract class)

추상 클래스란?

연관된 클래스들 간의 공통점을 추출해서 만든 클래스이며 추상 메서드를 가진 클래스를 뜻한다.

클래스 앞에 ‘abstract’키워드를 붙여 추상 클래스임을 나타낸다.

추상 클래스의 특징

  • 미완성 메서드가 존재하기 때문에 객체를 생성할 수 없다.
  • 상속을 통해 자식 클래스에서 모든 추상메서드를 구현해줘야 완성될 수 있다.

추상 클래스를 사용하는 이유

  1. 공통된 메소드와 필드를 통일하여 유지보수 용이 및 통일성이 유지된다.
  2. 추상 클래스를 가지고 구체 클래스를 구현만 하면 되기 때문에 확장성이 용이하다.

추상 메서드란?

메서드의 선언부만 작성하고 구현부{}는 작성하지 않은 메서드이다.

메서드 앞에 ‘abstract’키워드를 붙이고, 구현부{}가 없으므로 ‘;’로 마친다.

//추상 클래스
abstract class Player{
	//추상 메서드 선언
	abstract void play(int pos); 
	abstract void stop();
}

class AudioPlayer extends Player{
	//추상 메서드 구현
	void play(int pos){ /* 내용 생략 */ }
	void stop(){ /* 내용 생략 */ }
}

final 키워드

‘마지막’ or ‘변경될 수 없는’이라는 뜻으로 이 키워드를 사용하면 변경하지 못하도록 막아준다.

  • 변수(멤버변수, 지역변수) → 값 변경할 수 없는 상수가 된다.
  • 메서드 → 오버라이딩을 통해 재정의 될 수 없게 된다.
  • 클래스 → 확장될 수 없는 클래스가 된다. 즉, 자식 클래스를 정의할 수 없게 된다.

Categories:

Updated:

Leave a comment