코드 그라데이션

230324 상속 개념 정리 본문

Java, SpringBoot 추가 공부

230324 상속 개념 정리

완벽한 장면 2023. 4. 4. 12:17

상속

  • 상속은 두 클래스 간의 관계를 의미한다
  • 자식 클래스가 부모 클래스를 상속한다(extends)
  • 자식 클래스는 부모 클래스의 필드와 메서드를 상속받는다
  • 자식 클래스는 단 하나의 부모 클래스만을 가질 수 있다
  • 자식 클래스 내에서 부모의 객체에 접근할 때는 super 키워드를 사용한다
  • 자식 생성자에서는 반드시 부모 생성자를 먼저 호출해야 한다
  • 자식 생성자에서 this()나 super() 를 호출하지 않으면 컴파일러가 super() 를 첫 줄에 삽입한다

 

** 자바는 다중 상속이 안 됨(하나만 가능)

-> 이 때 대안이 없을까?

==> 있다. 인터페이스

 

** 인터페이스는 다중 상속에 대한 제약조건이 따로 없다.

 

다음을 잘 살펴보면,

interface Parent{
  void m2();
}
interface  GrandParent{
  void m1();
}
class MyService implements Comment{
  // 얘가 구현해야 하는 메서드의 수는? 총 5개!
}

public interface Comment extends Parent, GrandParent{
  void createComent(Long boardId);
  void updateComent(Long boardId, Long commentId);
  void deleteComent(Long commentId);
  

}

 

다른 예시

class Circle {
    public static final double PI = 3.14159;
    protected double r;

    public Circle(double r) {
        this.r = r;
    }

    public double circumference() {
        return 2 * PI * r;
    }
    public double area() {
        return PI * r * r;
    }
    public double radius() {
        return r;
    }
}

class PlaneCircle extends Circle {
		// 새로운 필드만 추가한다
    private final double cx, cy;

    public PlaneCircle(double r, double x, double y) {
        super(r);
        this.cx = x;
        this.cy = y;
    }

    public double getCentreX() {
        return cx;
    }

    public double getCentreY() {
        return cy;
    }

    // Note that it uses the inherited instance field r
    public boolean isInside(double x, double y) {
        double dx = x - cx, dy = y - cy; // Distance from center
        double distance = Math.sqrt(dx * dx + dy * dy);
        return (distance < r);
    }
}

 

 

오버라이드

- 부모 메서드에 그대로 올라타니까, 부모 메서드가 가려지는 것

- 재정의

예시

class A {
    int i = 1;
    int f() {
		return i; // 의미상으로 hide됨
		}
		static char g() {
				return 'A';
		}
}

class B extends A {
    int i = 2;
    int f() { // override (메서드 세상에서는 덮어써짐 => 신규값)
		return -i;
		}
		static char g() {
		return 'B';
		}
}

public class OverrideTest {
    public static void main(String args[]) {
        B b = new B(); // Creates a new object of type B
        System.out.println(b.i); // Refers to B.i; prints 2
        System.out.println(b.f()); // Refers to B.f(); prints -2
        System.out.println(b.g()); // Refers to B.g(); prints B
        System.out.println(B.g()); // A better way to invoke B.g()
        A a = (A) b; // Casts b to an instance of class A
        
        // 다형성(*객체지향의 핵심)
        부모타입.obj = 자식객체;
        obj.메서드(); // 자식의 메서드가 불린다.

        System.out.println(a.i); // Now refers to A.i; prints 1 (필드는 가려져 있던 것이지 사라진 게 아니므로)
        System.out.println(a.f()); // Still refers to B.f(); prints -2 (덮어써진 것이기 때문에 타입을 아무리 A로 바꿔도 B에 오버라이드된 함수가 불린다)
        System.out.println(a.g()); // Refers to A.g(); prints A
        System.out.println(A.g()); // A better way to invoke A.g()
    }
}

 

원래 static은 

class.____ 이렇게 부르는 게 맞는데

객체에 . 찍고 불러도 된다.

 

여기서 B는 A의 자식이죠.

자식은 부모의 모든 걸 다 가지고 있죠.

자식은 부모의 흉내를 낼 수 있다.

 

자식을 강제로 부모의 형태로 바꿔서 부모에다 넣어도 된다는 말(다형성)

A a = (A) b; // Casts b to an instance of class A

 

고성능 세탁기의 엔진은 그대로 있는데, 껍데기만 갈아 끼웠다고 생각하면 된다.

 

참고(의존성 주입 /45)

 

@override 어노테이션을 붙여서 가독성을 높여주기도 한다.

 

상속을 막는 방법

  • final 클래스
  • private 생성자 사용

<여기서 알아둬야 하는 기본적인 자바의 규칙>

* private는 클래스 자기 자신 안에서만 쓸 수 있게 하는 접근제어자다.

* 자식은 반드시 부모 생성자를 불러야만 한다.

- 부모 생성자를 부모 내부에서만 볼 수 있게 하면 자식이 볼 수 없으니까 자식 클래스가 만들어질 수 없게 되는 것.

 

오브젝트 52

 

 

 

728x90
Comments