07-1 / 상속

부모 클래스(상위클래스)의 멤버를 자식 클래스(하위클래스, 파생클래스)에게 물려주는 것을 상속이라고 한다. 상속을 이용하면 부모 클래스의 수정으로 모든 자식 클래스를 수정되는 효과도 있어 유지보수 시간을 최소화 할 수 있다.

 


클래스 상속) 

자식 클래스에서 클래스를 선언할 때 어떤 부모 클래스로 부터 상속 받을 것인지 선택한다.

선택된 부모 클래스는 extends 와 함께 선언된다.

class 자식클래스명 extends 부모클래스명 {
}

 

자바 상속의 특징

- 다중 상속할 수 없다. 부모 클래스는 단 하나.

- 부모 클래스에서 private의 필드와 메소드는 상속 대상에서 제외.

- 부모와 자식이 다른 패키지에 존재한다면 default 접근 제하 멤버도 상속 대상에서 제외.

 

 


부모 생성자 호출) 

상속을 한 객체를 생성하면 부모 객체가 먼저 생성되고 그다음에 자식 객체가 생성된다

부모객체 생성자는 자식 생성자의 맨 첫 줄에서 호출 된다.

자식 생성자가 명시적으로 선언하지 않았다해도 컴파일러는 상속된 관계를 알게되면 자식 클래스 생성자 첫줄에 super()를 추가하게 된다. 이는 부모의 기본 생성자를 호출하는 메소드. 만약 직접 선언하고 싶다면 자식 클래스 생성자 첫줄에 명시적으로 선언하면 된다.

class 자식클래스 extends 부모클래스 {
    public 자식클래스 (){
    	super(); 
    }
}

직접 호출시 매개값을 주어 호출할 수도 있는데 매개값 타입과 일치하는 부모 생성자를 호출한다.

 

자식 클래스에서 super을 명시하지 않으면 자동으로 부모의 "기본" 생성자를 호출해야 하기 때문에 부모는 꼭 기본 생성자가 존재해야 한다. 자동으로 생성되는 super에서는 매개값이 있는 생성자를 호출하지 않는다. 

 

 


메소드 재정의 : 오버라이딩(Overiding) ) 

상속된 일부 메소드를 자식 클래스에서 다시 수정해서 사용하는 기능

 

  • 오버라이딩 방법

* 규칙

- 부모의 메소드와 동일한 시그너처(리턴타입, 메소드 이름, 매개 변수 목록)를 가져야 한다.

- 접근 제한을 더 강하게 재정의 할 수 없다. (반대로 자식이 더 약한 접근제한을 갖는 것은 가능하다.) 

- 새로운 예외(Exception)을 throw할 수 없다.

 

메소드가 재정의 즉 오버라이딩 되었다면 부모의 메소드는 숨겨서 메소드 호출시 오버라이딩된 자식 메소드가 호출된다.

오버라이딩 된 메소드위에 @Override 어노테이션을 쓰면 메소드가 재정의 된 것인지 컴파일러가 확인 해주어 개발자의 실 수를 줄일 수 있다.

 

@Override
부모보다약한접근제한자 부모와같은리턴타입 부모와같은이름 부모와같은매개값 {
	재정의
}

 


부모 메소드 호출) 

메소드를 오버라이딩하여 부모 메소드가 숨겨졌는데 부모 메소드를 호출해야하는 경우에는 super키워드를 사용하여 호출할 수 있다. 

super.부모메소드();

 


final 클래스와 final 메소드) 

final 키워드는 클래스, 필드, 메소드를 선언할 때 사용할 수 있는데, 해당 선언이 최종 상태이고 결코 수정될 수 없다는 의미이다.

 

상속할 수 없는 final 클래스

final은 최종 클래스이기 때문에 상속이 불가능해 부모클래스가 될 수 없다.

 

재정의 할 수 없는 final 메소드

메소드 역시 final키워드가 붙으면 최종 메소드이기 때문에 재정의 할 수 없다. 따라서 자식 클래스에서 오버라이딩이 불가능 하다. 

 

? final 필드는 어떨까
final 필드 경우는 final 클래스의 멤버가 아니라면 또는 접근 제한자 적 제한이 없다면 호출은 가능하지만 final속성에 맞게 새로운 값을 줄 수는 없다

protected 접근 제한자) 

protected는 public과 default 접근 제한의 중간에 해당 하는데, 같은 패키지의 경우에는 제한 제한이 없지만,

다른 패키지에서는 자식 클래스만 protected에 접근할 수 있다. 

자식 클래스라면 부모인 protected 필드, 생성자, 메소드에 접근이 가능하다.

단, new 연산자를 사용해서 생성자를 직접 호출 할 수는 없고, 자식 생성자에서 super()로 생성자를 호출해 사용할 수 있다.

 

 

 

+ Recent posts