티스토리 뷰

JAVA

[자바 스터디] 6주차 : 상속

짜비 2022. 1. 30. 10:32

자바 상속의 특징

상속

기존 클래스를 재사용해서 새로운 클래스를 작성하는 것.

  • extends : 조상 클래스를 “확장” 한다.
  • 조상 클래스가 변경되면 자손 클래스는 자동적으로 영향을 받지만 자손 클래스가 변경되는 것은 조상 클래스에 아무런 영향을 주지 못한다.
  • 생성자와 초기화 블록은 상속되지 않는다. 멤버만 상속된다.
  • C++ 와 달리, 단일 상속만 가능하다.
    • 다중 상속 시, 클래스간 관계가 매우 복잡해짐.
    • 서로 다른 클래스로부터 상속 받은 멤버의 이름이 같을 경우, 구별할 수 있는 방법이 없음.
    • 포함관계를 이용해서 다중상속과 유사한 효과를 낼 수 있음.

super 키워드

자손 클래스에서 조상 클래스로부터 상속받은 멤버를 참조할 때 사용되는 참조변수.

  • 일반적으로, 조상 클래스로부터 상속 받은 멤버 또한 자신의 멤버이므로 this로 참조가 가능.
    • 조상 클래스 멤버와 자손 클래스 멤버가 중복 정의되어 있을 때, 이를 구분할 때 super를 사용하면 된다.
public class SuperTest {


public static void main(String[] args) {
    Child c = new Child();
    c.method();
}


}

class Parent {  
int x = 10;  
}

class Child extends Parent {  
int x = 20;


void method() {
    System.out.println("x = " + x);        //20
    System.out.println("this.x = " + this.x);    //20
    System.out.println("super.x = " + super.x);    //10
}


}
class Point {
    int x;
    int y;

    String getLocation() {
        return "x : " + x + ", y :" + y;
    }

}

class Point3D extends Point {
    int z;

    //조상 클래스의 메소드를 참조할 때도 super가 사용됨
    String getLocation() {
        return super.getLocation() + ", z:" + z;
    }
}

조상 클래스의 생성자 super()

class Point {
    int x;
    int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    String getLocation() {
        return "x : " + x + ", y :" + y;
    }

}

class Point3D extends Point {
    int z;

    public Point3D(int x, int y, int z) {
        super(x, y);    //이 부분을 지우면 컴파일 에러 발생!
        this.z = z;
    }

    String getLocation() {
        return super.getLocation() + ", z:" + z;
    }
}

자손 클래스의 인스턴스를 생성하면, 자손 멤버와 조상 멤버가 모두 합쳐진 하나의 인스턴스가 생성된다. 이때 조상 멤버의 변수를 초기화하기 위해 조상 클래스의 생성자를 반드시 호출해야 한다.
자바 컴파일러는 자손 클래스의 생성자 첫줄에 super() 가 없으면 자동으로 super() 를 삽입한다. 이때, 조상 클래스에 no-arg 생성자가 없으면 컴파일 에러가 발생한다.

메소드 오버라이딩

조상 클래스로부터 상속받은 메소드의 내용을 변경하는 것.

오버라이딩 조건

  • 메소드 이름 일치
  • 매개변수 일치
  • 반환 타입 일치
  • 접근 제어자
    • 조상 클래스의 메서드보다 좁은 범위로 변경 불가
      e.g. 조상 클래스 메소드 : protected
      자손 클래스 메소드 : protected or public
    • 대부분, 같은 범위의 접근 제어자를 사용
  • 예외
    • 조상 클래스 메서드보다 많은 수의 예외 선언 불가
class Parent{  
void parentMethod() throws IOException, SQLException {  
//...  
}  
}

//가능  
class Child extends Parent {  
void parentMethod() throws IOException {  
//...  
}  
//...  
}

//불가능 : Exception은 최상위 조상이므로 던질 수 있는 예외 개수가 많음  
class Child extends Parent {  
void parentMethod() throws Exception {  
//...  
}  
//...  
}

다이나믹 메소드 디스패치 (Dynamic Method Dispatch)

Runtime polymorphism 이라고도 불린다.
Override된 method가 있을 때, 어떤 method를 호출할 것인지가 compile time이 아닌 run time에 결정되는 것을 의미.

  • 어떤 메소드를 호출할 것인지는, 해당 참조 변수가 가리키고 있는 객체의 타입을 보고 결정한다.
public class Dispatch {
    public static void main(String[] args) {
        A a = new A();
        B b = new B();
        C c = new C();

        A ref;

        ref = a;
        ref.m1();    //A.m1

        ref = b;
        ref.m1();    //B.m1

        ref = c;
        ref.m1();    //C.m1

    }
}

class A {
    void m1() {
        System.out.println("A.m1");
    }
}

class B extends A {
    void m1() {
        System.out.println("B.m1");
    }

}

class C extends A {
    void m1() {
        System.out.println("C.m1");
    }
}

(참고) Compile time polymorphism

Compile time 때 어떤 method가 호출될지 결정되는 방식.

  • method overloading이 그 대표적인 예이다.
    • 동일한 이름을 가진 method가 여러 개 정의되어 있을 때, parameter type, parameter 개수 등을 보고 어떤 메소드를 호출할 것인지 컴파일 타임에 결정할 수 있다.

추상 클래스 (Abstract class)

클래스를 설계도에 비유한다면, 추상 클래스는 미완성 설계도에 해당한다. 이는 추상 클래스가 미완성 메소드를 가지고 있음을 의미한다.

  • 추상 클래스로는 인스턴스를 생성할 수 없다.
  • 메소드 앞에 abstract 를 붙여서, 자손 클래스가 해당 메소드를 반드시 구현하도록 강제할 수 있다.
  • 추상화 : 클래스 간의 공통점을 찾아내서 공통의 조상을 만드는 작업.
  • 구체화 : 상속을 통해 클래스를 구현 및 확장하는 작업.

final 키워드

“변경할 수 없음” 을 의미한다.

  • 클래스 : 이 클래스를 상속할 수 없음.
  • 메서드 : 오버라이딩 할 수 없음.
  • 지역변수, 멤버변수 : 값을 변경할 수 없음.
    • 멤버변수의 경우, 선언할 때 이외에, 생성자를 이용해서도 값을 설정할 수 있음.

Object 클래스

모든 클래스 상속 계층도의 최상위에 있는 조상 클래스.

  • 다른 클래스로부터 상속받지 않는 모든 클래스는 자동적으로 Object 클래스를 상속받는다.
    • 컴파일러가 자동적으로 extends Object 코드를 추가
    • 만약 다른 클래스로부터 상속을 받는다면, 상속 계층도를 따라 올라가면 결국 최상위 조상은 Object 클래스가 된다.
    • toString(), equals(Object o) 와 같은 메소드를 정의하지도 않고 사용할 수 있는 것은, 이런 메소드들이 Object 클래스에 정의되어 있기 때문.

백기선님 리뷰 영상

References

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함