Programming/JAVA

[JAVA] 상속(Inheritance), 오버라이딩(Override), super, super()

잇나우 2020. 2. 21. 00:05
반응형

상속

우리가 현실세계에서 쓰는 상속과 비슷한 의미를 가지고 있다. 자바에서 상속은 부모 클래스의 메소드와 변수같은 멤버와 자원을 자식 클래스가 사용할 수 있다. 자바에서는 다중 상속을 지원하지 않는 대신 객체의 명확성을 높였다. 상속을 사용하면 중복된 코드를 줄이고 코드의 재사용성을 높여 유지보수가 편리하다

  • 부모클래스
    • parent 클래스, 기반(base)클래스, Super 클래스, 상위 클래스
  • 자식클래스
    • children 클래스, 후손 클래스, sub 클래스, 하위 클래스

상속을 받게 되면 부모 클래스의 필드와 메소드와 같은 멤버등을 물려받게 된다. 하지만 접근제어자가 private을 가지고 있는 멤버는 불가능하며, 부모 클래스와 패키지가 다를 경우 접근제어자가default멤버도 상속 받을 수 없다.

상속 형식

자식 클래스 뒤에 extends와 부모 클래스를 적어줘야 한다.

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

//예
class childClass extends parentsClass{

}

자바에서는 하나의 자식클래스가 여러개의 부모클래스를 만드는 다중상속이 불가능하다. 자식 클래스는 1개의 부모클래스를 가지는 단일 상속만 가능하는데, 부모 클래스는 여러개의 자식 클래스를 가지는 것은 가능하다.


오버라이딩(Override)

부모 클래스에서 정의된 메소드를 자식 클래스에서 메소드의 동작을 재정의하여 사용할 수 있는데, 이러한 기술을 오버라이딩이라 한다.

오버라이딩 규칙

  1. 오버라이딩을 하려면 부모 클래스의 메소드의 리턴타입을 동일하게 해야한다. (단, 작은타입으로 재정의도 가능하다)
  2. 메소드의 매개변수가 동일해야한다.
  3. 접근지정자는 동일하거나 더 큰 범위만 가능하다. (좁은 범위로 변경할 수 없음)
  4. 부모 클래스의 메소드보다 더 큰 범위의 예외를 선언할 수 없다.
  5. static, final, private 지정자를 가진 메소드는 오버라이딩이 불가능하다.
class SuperObj {
    public void write() {
        System.out.println("부모 클래스 메소드");
    }
}

class SubObj {
    public void read() {
        this.write()  // override가 되었기때문에 자식 클래스의 write가 호출
    }
    @Override  // 어노테이션
    public void write() {
        System.out.println("자식 클래스 메소드");
    }
}

super

부모 클래스로부터 상속받은 멤버변수나 메소드를 자식 클래스에서 참조할때 사용하는 레퍼런스(참조)변수이다. 부모 클래스와 자식 클래스의 멤버의 이름이 같을 경우 super를 사용하여 부모 클래스의 멤버에 접근할 수 있다. 인스턴스 메소드에만 사용이 가능하며 클래스 메소드에는 사용할 수 없다.
this와 super는 인스턴스 주소값을 저장하는데 static 메소드와는 상관없이 사용된다.

super()

super()는 부모 클래스의 생성자를 호출할때 사용한다. 자식 클래스의 인스턴스를 생성하면 부모 클래스의 모든 멤버까지 포함되어 있다. 자식 클래스에서 부모 클래스의 멤버를 사용하기 위해서는 부모 클래스의 멤버를 먼저 초기화 해야한다. 부모 클래스의 멤버를 초기화하기 위해서는 부모 클래스의 생성자를 자식 클래스의 생성자 첫줄에서 호출해야한다. 이러한 부모 클래스 호출은 상속관계에 따라 Object 클래스까지 거슬러 올라간다.

Object 클래스를 제외한 부모 클래스의 생성자를 명시적으로 호출하지 않으면 자식 클래스의 생성자 첫 줄에 자동으로 super()를 추가하여 실행한다. 하지만 클래스에 생성자가 하나도 정의되지 않았을때만 자동으로 디폴트 생성자를 호출한다. 디폴트 생성자 이외의 다른 생성자를 사용할 경우 디폴트 생성자도 명시적으로 정의해야 컴파일러 오류가 나지 않는다.

// 매개변수를 가지는 생성자 선언시 디폴트 생성자도 명시적으로 선언해야한다.
class Parent {
    Parent() {
        name = "기본값";
    }
    Parent(String s) {
        name = s;
    }
}

상속관계인 클래스에서 super를 이용한 예제

class Parent {
    Parent() {
        name = "기본값";
    }    
    Parent(String s) {
        name = s;
    }
}


class Child extends Parent {
    Child() {          
        super("잇나우");  // 부모 클래스 생성자 호출
    }
    Child(Stirng name) {
        super(name);
    }
}


Child ch1 = new Child(); // 부모 클래스의 디폴트 생성자를 먼저 호출한다.
Child ch2 = new Child("잇나우");
반응형

'Programming > JAVA' 카테고리의 다른 글

[JAVA] 인터페이스 (Interface)  (0) 2020.02.24
[JAVA] 다형성(Polymorphism)  (0) 2020.02.24
[JAVA] 생성자(Constructor)  (0) 2020.02.19
[JAVA] static과 static 메소드, static 변수  (0) 2020.02.18
[JAVA] 기본 배열(Array)  (0) 2020.02.18