[21.07.16] 상속

yed·2021년 7월 16일
0

대부분의 기능은 효율적인 유지보수를 위함이다.


상속

한식이라는 상위개념의 하위개념은 된장찌개, 김치찌개, 기타등등이 존재하죠? 이처럼 클래스에서도 상위클래스와 하위클래스를 만들 수 있어요. 이것을 상속이라고 해요!

  • super class == 상위 클래스 == 부모(parent) 클래스
  • sub class == 하위 클래스 == 자식(child) 클래스

public class 자식클래스이름 extends 부모클래스이름{}

자식 클래스에는 부모클래스를 상속받았다는 의미로 extends로 명시해줘야 해요. 자식 클래스는 부모 클래스의 메소드와 멤버변수를 사용할 수 있으나 부모 클래스는 자식 클래스의 메소드를 사용할 수 없어요! 그리고 부모 클래스로 생성된 배열에 자식 클래스의 객체도 값으로 들어갈 수 있다는 점~!

또한 개발자가 만든 클래스들끼리만 상속이 가능한 것이 아니라 자바에 만들어져 있는 기존 클래스도 상속받아 사용할 수 있어요

부모 클래스와 자식 클래스의 관계는 1:N 관계입니다. 하나의 부모 클래스의 자식 클래스는 여러개 존재할 수 있어요. 하지만 하나의 자식클래스에는 부모 클래스는 하나만 존재합니다. 대신 부모의 부모의 부모의 부모~~ 처럼 부모 클래스가 상속받은 부모클래스의 기능까지 쓸 수 있답니다.

super()

자식 클래스를 사용하기 위해선 부모클래스의 생성자가 그 어떤 코드보다 먼저 호출되어야합니다. 이 때 부모 클래스의 생성자를 호출하기 위하여 super()를 사용합니다!
super()부모클래스의 기본 생성자 호출하는 역할인데요 자식 클래스의 생성자에서 생략하더라도 자동으로 생성됩니다

하지만 매개변수가 있는 생성자는 자동으로 호출되지 않아서 super(매개변수)로 명시해주어야 해요!

그리고 자바 컴파일러는 생성자를 하나라도 정의되어 있는 경우 기본 생성자를 만들어주지 않는데요, 만약 기본 생성자는 생략하고 매개변수가 있는 생성자만 가진 부모 클래스를 자식 클래스에서 extends 한다면 오류가 발생합니다.

Implicit super constructor 부모클래스 is undefined for default constructor. Must define an explicit constructor

  • 부모 클래스에 기본생성자가 없으니 다른 생성자를 명시하세요!

이 때는 자식 클래스의 모든 생성자에서 부모클래스의 매개변수가 있는 생성자를 호출하는 super(매개변수)를 꼭 명시해줘야 합니다.

Override

"재정의하다" 라는 뜻을 가진 오버라이드는 부모 클래스의 메소드를 자식 클래스에서 내용만 재정의하여 사용하는 것을 말해요. 메소드의 리턴 타입, 이름, 매개변수는 전부 동일해야합니다! 부모 클래스에서 틀을 만들고 자식 클래스에서 틀을 사용해 기능을 만드는 거라고 보시면 돼요~

오버라이드 사용 시 생기는 @Override

  • annotation : 특정 변수나 함수에 상태를 표시함

java.lang.Object 클래스

자바의 모든 클래스에는 기본적으로 상속받고 있는 최상위 클래스가 존재하는데요. 바로 java.lang.Object 클래스입니다! Object 클래스는 모든 클래스의 부모가 되는거예요. Object 클래스의 public 메소드들을 상속받아서 우리가 사용할 수 있는겁니다

toString() 메소드

Object 클래스의 메소드 중 하나로 원래는 패키지이름.클래스이름@참조값(주소값)을 리턴하는 메소드입니다. 그런데 이 toString()을 오버라이드해서 문자열을 반환하도록 만들 수 있어요.

@Override
public String toString() {
	return super.toString();
}

초기상태. 주소값을 반환함

@Override 
public String toString() {
	return "안녕하세요"; 
}

문자열 반환으로 수정함

이렇게 toString을 수정한 클래스 타입의 인스턴스는
변수명.toString()==변수명 서로 같은 문자열을 출력합니다.

다형성 (Polymorphism)

다형성은 객체를 여러가지 타입으로 호출할 수 있는 것입니다. 참조 변수를 선언할 때 생성된 인스턴스의 클래스 타입으로 변수 선언하거나 그 부모의 타입으로 변수를 선언할 수 있어요. 무슨말이냐면

ChildClass 변수명 = new ChildClass(); < 일반적인 인스턴스 생성 형태죠?

ParentClass 변수명 = new ChildClass();
타입과 생성자가 다르네요? 그러나 이것도 정상적으로 작동합니다. 이 형태를 다형성이라고 해요~

ChildClass 변수명 = new ParentClass(); //오류!
하지만 자식 타입의 부모 생성자는 할 수 없어요!

다형성의 장점
1. 배열이나 컬렉션을 사용할 때 부모 타입으로만 선언해도 배열에 부모부터 자식 타입까지 저장할 수 있음
2. 메소드를 정의할 때 메소드의 매개변수나 리턴타입으로 부모 클래스 타입만 사용해도 부모와 자식 타입 모두 매개변수나 리턴값으로 사용가능.

그러나 다형성 인스턴스는 ParentClass 타입으로 선언해서 ChildClass에서 자체적으로 정의한 메소드는 바로 사용할 수 없어요. ChildClass의 메소드를 사용하기 위해서는 강제 형변환(casting)을 해야만 쓸 수 있답니다.
오버라이드 메소드의 경우 원형이 ParentClass에 있어서 가능하지만요! 대신 값은 child()의 메소드가 실행되어 나와요.

instanceof 키워드

참조변수 instanceof 클래스이름

강제 형변환을 하기 전에 이 인스턴스가 형변환을 하면 올바르게 메소드를 사용할 수 있을지 판단할 수 있는 키워드가 됩니다. 명시된 클래스 타입과 인스턴스가 같은 타입이면 true를 아니면 false를 반환해줘요!

ParentClass test = new ChildClass();

test는 ParentClass 타입의 객체로 생성되어 있죠? 그럼 test는 ParentClass의 객체일까요?

System.out.println(test instanceof ChildClass); //true

아닙니다! test는 다형성 인스턴스라 내부적으로 자식 클래스의 인스턴스가 맞아요 다만 컴퓨터가 인식하지 못해서 강제형변환을 통해 자신의 메소드들을 사용할 수 있습니다.


점점 어려워지고 있고요.. 하지만 지금의 수준은 내가 넘어야 할 산의 입구에도 가지 못했다는 것을 다시 한번 상기시킵니다. 힘👊👊

profile
6개월 국비과정 기록하기

0개의 댓글

관련 채용 정보