상속

이동영·2024년 3월 11일

자바 개념정리

목록 보기
17/21

상속관계

  • 자식은 부모에 대해 알고 있지만 부모는 누가 내 코드를 상속받을지 모른다. 화살표는 누군지를 안다는 표현이기에 자식이 부모를 향해 화살표가 그려진다.
  • 부모는 자식에 접근할 수 없으며 누군지 모른다.

단일 상속

  • 하나의 자식이 두개의 부모를 갖는것은 안된다.
  • 다중상속을 할 경우 두개의 부모중 같은 메소드가 있다면 문제가 발생할 수 있다. 그렇기에 다중상속을 사용할 경우 모호한 문제가 생기기에 자바에서는 다중 상속을 금지한다.
  • 다중상속시 클래스 계층 구조가 복잡해지기 때문에 클래스의 다중 상속을 허용하지 않는다.

상속과 메모리 구조

  • new ElectricCar()를 호출하게 되면 ElectricCar와 Car까지 인스턴스를 생성하게 된다. 즉 본인고 부모가 동시에 생성이 된다.
  • 부모의 필드와 메서드만 몰려받는게 아닌 인스턴스 안에 본인과 부모 둘다 생성이 된다.
  • 참조값은 힙 메모리에 하나만 생성되지만 그 안에 부모와 자식이 공존하게 된다.
  • 외부에서는 하나의 인스턴스를 생성하는것 같지만 실제로는 부모와 자식 둘다 생성되고 공간도 구분이 된다.
  • 상속받은 객체는 메모리 안에 부모와 자식이 공존하게 된다. 그런데 메소드를 호출하게 되면 부모타입의 메소드를 호출할 지 자식 타입의 메소드로 호출할 지 선택을 해야하는데 이때 호출하는 변수의 타입을 기준으로 선택한다. 자식 타입으로 선언한 변수는 자식타입의 메소드가 선택이 된다.

정리 : 상속 받은 클래스로 인스턴스를 생성하면 자식으로 생성되지만 실제로는 메모리 공간안에는 부모와 자식 둘다 생성이 된다. 부모와 자식 둘다 있기에 어떤 메소드를 호출할지는 변수의 타입을 기준으로 해서 선택한다.

  • 상속 관계에서는 자식 타입에 해당 메소드가 없다면 부모로 올라가서 찾는다.
  • 만약 부모로 가서도 메소드가 없으면 더 상위로 가서 찾지만 더더 상위로 가도 없다면 컴파일 오류가 발생한다.

핵심

  • 상속관계로 객체를 생성하면 메모리 하나에 자식과 부모가 둘다 생성된다.
  • 상속관계의 객체를 호출할 때 타입을 정해야 한다. 이때 호출자의 타입을 기준으로 메소드를 호출한다.
  • 상위로 갔는데 메소드가 없다면 더 상위로 가서 찾는다. 하지만 그 위로도 갔는데 없다면 컴파일 오류가 발생한다.’’

이것만 머릿속에 집어넣으면 된다.

상속과 메서드 오버라이딩

  • 부모로 부터 상속 받은 기능을 자식에게 맞춰서 재정의 하는것을 의미한다.
  • 애너테이션은 주석이긴 하지만 프로그램이 읽을 수 있는 주석이라고 보면 된다.
  • 애너테이션이 없어도 정상적으로 동작된다. 하지만 개발자들은 무조건 오버라이딩을 할 때 애너테이션을 붙인다.
  • 애너테이션을 붙이면 부모의 기능을 몰려 받는다는 표식을 남긴다.
  • 컴파일러는 이 애너테이션을 보고 정확히 오버라이딩이 되었는지 확인을 한다. 만약 정확하지 않으면 컴파일 오류가 발생한다.

오버라이딩과 메모리 구조

  • 자신한테 메소드가 있으면 자신의 메소드를 사용하고 그것이 아니면 부모로 올라가서 호출한다.

오버로딩

  • 메서드 이름은 같지만 매개변수가 다른 메서드를 여러개 생성하는것을 의미함

오버라이딩

  • 하위클래스의 메소드가 상위클래스의 메소드를 덮어버리는것을 의미한다.

오버라이딩의 조건

  • 부모클래스의 메서드와 같은 메소드를 오버라이딩을 할 수 있다.
  • 접근제어자같은 경우는 상위 클래스 보다 더 제한적이여서는 안된다. 부모가 public인데 자식 메소드는 private이여서는 안된다는 것이다.
  • 부모보다 더 많은 예외를 선언할 수 없다.
  • static final private 키워드가 붙은 메소드는 오버라이딩을 할 수 없다.
  • 메서드에서 final이 붙으면 이 메서드는 못 고친다는 의미이다.
  • private는 클래스 내부에서만 접근가능한데 이것이 붙으면 하위 클래스에서 오버라이딩이 불가능하다.
  • 인스턴스 레벨에서 작동되는 오버라이딩은 클래스에서 작동되는 static에서는 오버라이딩을 할 수 없다.

상속과 접근 제어

protected

  • 패키지가 다르더라도 상속관계에 속한다면 호출이 가능하다.

접근 제어와 메모리 구조

  • 생성되는 객체는 하나이지만 상속관계의 부모와 자식은 내부에서 둘로 나뉘어져 있다. 자식에서 메소드를 호출했는데 호출한 메소드가 자기 자신에게 없고 부모에게 있다면 이때 접근제어자의 영향을 받게 된다. 겉으로 보기에는 하나이지만 내부적으로 보면 둘로 나뉘어져 있으며 부모 입장에서 메소드가 외부에서 호출된것이기 때문에 접근제어자의 영향을 받는다.
  • 자식에서 부모의 값을 변경한다면 부모의 벨류를 바꾼것이 된다.
  • 상속을 받으면 자식에서 부모의 필드와 메서드를 사용할 수 있다. 그런데 자식 클래스에서 부모의 필드값을 설정하면 객체를 호출 할때 부모의 필드값이 자식클래스에서 설정한 값으로 나오게 된다.
  • 자식이 부모에 접근하여 필드값을 바꾼것이다로 정리할 수 있다.

super - 부모참조, 생성자

  • 자식클래스에서 이미 재정의를 하였거나 필드를 부모와 동일한 이름으로 선언한 경우 자식클래스에서 부모클래스의 필드와 메소드를 사용할 수 없다. 하지만 super키워드를 사용하면 부모를 참조할 수 있다.
  • 메소드에서 this를 생략하면 우선 자신 클래스의 필드를 찾지만 없으면 한단계 위로 올라가서 부모를 참조하게 된다.

정리

  • 필드와 메서드의 이름은 같지만 super를 사용하면 부모클래스의 메서드 필드를 사용할 수 있다.

생성자

  • 상속받은 클래스로 인스턴스를 생성하면 참조값은 하나지만 내부적으로 보면 부모와 자식이 둘다 생성이 된다. 그렇기 때문에 부모와 자식 각각 모두의 생성자가 호출이 되어야 한다.
  • 자식 클래스의 생성자에서 부모 클래스의 생성자를 호출해줘야 한다.
  • 상속 관계에서는 부모 생성자를 호출하려면 super를 사용해야 하며 super()키워드는 생성자 첫줄에 와야 한다.
  • 매개변수가 없는 생성자는 super()키워드를 붙이지 않아도 자바가 알아서 만들어 준다.
  • super를 생성자에서 생략이 가능한 경우는 부모클래스가 기본 생성자 인경우만 생략이 가능하다. 매개변수가 있는 생성자의 경우 super에 직접 인자값을 전달하여 직접 정의해줘야 한다.
  • ABC클래스 순으로 클래스가 있을 때 생성자는 최상위인 A클래스 생성자 부터 실행이 된다. super키워드가 생성자의 맨 첫번재줄에 있기에 타고타고 가면 결국 최상위인 A클래스의 생성자부터 호출이 되며 먼저 A클래스의 객체부터 생성이 되는것이다

정리

  • 상속 관계의 생성자 호출은 부모에서 자식순으로 부모의 객체를 먼저 생성하고 자식의 객체를 순차적으로 생성한다.
  • 상속관계에서 생성자 첫줄에는 super()를 맨 첫줄에 선언해야 하며 부모 생성자가 기본 매개변수가 없는 생성자인경우 호출을 생략할 수 있다.
  • 상속관계에서도 첫줄에 this()키워드를 선언하여 같은 클래스 내 다른 생성자를 호출을 할 수 있다. 상속관계에서 첫줄에 super키워드를 적지 않더라도 결국 언젠간 super()를 호출해야 한다. 즉 super키워드가 첫줄에 있는 생성자를 자기자신이 호출할 때까지는this()로 자기자신의 다른 생성자를 호출할 수 있다는 것이다.
profile
가치를 제공하는 개발자

0개의 댓글