공부/JAVA

[JAVA] 상속

Dr.thousand 2022. 10. 25. 22:17
728x90
  • 자바 상속의 특징
  • super 키워드
  • 메소드 오버라이딩
  • 다이나믹 메소드 디스패치 (Dynamic Method Dispatch)
  • 추상 클래스
  • final 키워드
  • Object 클래스

자바 상속의 특징

상속이란 어느 클래스가 가진 변수 , 메소드 등을 포함하여 확장하는 용도로 사용된다.


상속이란, 기존의 클래스를 재사용하여 새로운 클래스를 작성하는것이다.

자바의정석_남궁민


public class Parent {
    public String name;
    public int age;
}
public class Child extends Parent {
}
public static void main(String[] args) {
    Child child = new Child();
    child.name = "자식";
}

위 클래스에서 Child 클래스는 name이라는 변수를 정의해주지 않았지만,  Parent를 상속받았기때문에 따로 변수를 선언하지 않아도 name변수를 가지게된다.

 

상속 다이어그램

해당 다이어그램 처럼 상속받은 자손 클래스는 조상 클래스의 내용을 포함한다.


자손 클래스는 여러 조상클래스를 가질수없다. 단 하나의 조상 클래스만 가질 수 있다.

public class Child2 extends Parent , Animal{
}

위의 코드같이 여러명의 조상클래스를 가질 수 없다.


Object - 모든 클래스의 조상

Object클래스는 모든 클래스 상속계층도의 최상위에 있는 조상클래스이다. 다른 클래스로 부터 상속을 받지 않는 클래스들은 자동적으로 Object클래스를 상속받게 한다.


Super키워드

this()와 마찬가지로 super()역시 생성자이다. this()는 같은 클래스의 다른 생성자를 호출하는데 사용되지만, super()는 조상 클래스의 생성자를 호출하는데 사용된다. 자손 클래스 인스턴스를 생성하면, 자손의 멤버와 조상의 멤버가 모두 합쳐진 하나의 인스턴스가 생성된다. 위에서 말했듯이 Object클래스는 모든 클래스의 조상 클래스이다. 그렇기 때문에 Object클래스의 생성자가 호출될 때 까지 조상 클래스의 생성자가 호출된다.


오버라이딩(overriding)

조상 클래스로부터 상속받은 메소드의 내용을 변경하는것을 오버라이딩이라고 한다. 나는 편히 덮어쓰기라는 의미로 받아들이고 사용중이다. 상속받은 메소드를 그대로 사용하기도 하지만 ,자손클래스에 맞게 변경해야하는 경우에 같은 이름의 메소드를 자손클래스에 맞는기능을 하도록 재정의 할 수 있도록 하는 기능이다.

public class Parent {
    public String name;
    public int age;

    public void say(){
        System.out.println("PARENT : I'm parent!");
    }
}
public class Child extends Parent {
    public void say(){
        System.out.println("CHILD : I'm Child!");
    }
}
@Test
void inheritanceTest(){
    Parent parent = new Parent();
    Child child = new Child();
    
    parent.say();
    child.say();
}


다이나믹 메소드 디스패치

컴파일러가 컴파일단계에서 어느 메소드를 호출할지 결정하지 못하고 , 런타임 단계에서 어느 메소드를 결정할지 컴파일러가 알게된다.

 

public class DynamicMethod {

    public static void main(String[] args) {
        Top subClass = null;
        String type = "sub2";

        switch (type) {
            case "sub" ->{
                subClass = new Sub();
            }
            case "sub2" -> {
                subClass = new Sub2();
            }
        }

        subClass.print();
    }

}

abstract class Top{
    void print(){}
}

class Sub extends  Top{
    @Override
    void print() {
        System.out.println("SUB");
    }
}

class Sub2 extends Top{
    @Override
    void print() {
        System.out.println("SUB2");
    }
}

다이나믹메소드의 바이트코드

// class version 61.0 (61)
// access flags 0x21
public class com/study/whiteship_study_cyh/DynamicMethod {

  // compiled from: DynamicMethod.java

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 3 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
   L1
    LOCALVARIABLE this Lcom/study/whiteship_study_cyh/DynamicMethod; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x9
  public static main([Ljava/lang/String;)V
    // parameter  args
   L0
    LINENUMBER 6 L0
    ACONST_NULL
    ASTORE 1
   L1
    LINENUMBER 7 L1
    LDC "sub2"
    ASTORE 2
   L2
    LINENUMBER 9 L2
    ALOAD 2
    ASTORE 3
    ICONST_M1
    ISTORE 4
    ALOAD 3
    INVOKEVIRTUAL java/lang/String.hashCode ()I
    LOOKUPSWITCH
      114240: L3
      3541490: L4
      default: L5
   L3
   FRAME FULL [[Ljava/lang/String; com/study/whiteship_study_cyh/Top java/lang/String java/lang/String I] []
    ALOAD 3
    LDC "sub"
    INVOKEVIRTUAL java/lang/String.equals (Ljava/lang/Object;)Z
    IFEQ L5
    ICONST_0
    ISTORE 4
    GOTO L5
   L4
   FRAME SAME
    ALOAD 3
    LDC "sub2"
    INVOKEVIRTUAL java/lang/String.equals (Ljava/lang/Object;)Z
    IFEQ L5
    ICONST_1
    ISTORE 4
   L5
   FRAME SAME
    ILOAD 4
    LOOKUPSWITCH
      0: L6
      1: L7
      default: L8
   L6
    LINENUMBER 11 L6
   FRAME SAME
    NEW com/study/whiteship_study_cyh/Sub
    DUP
    INVOKESPECIAL com/study/whiteship_study_cyh/Sub.<init> ()V
    ASTORE 1
   L9
    LINENUMBER 12 L9
    GOTO L8
   L7
    LINENUMBER 14 L7
   FRAME SAME
    NEW com/study/whiteship_study_cyh/Sub2
    DUP
    INVOKESPECIAL com/study/whiteship_study_cyh/Sub2.<init> ()V
    ASTORE 1
   L8
    LINENUMBER 18 L8
   FRAME CHOP 2
    ALOAD 1
    INVOKEVIRTUAL com/study/whiteship_study_cyh/Top.print ()V
   L10
    LINENUMBER 19 L10
    RETURN
   L11
    LOCALVARIABLE args [Ljava/lang/String; L0 L11 0
    LOCALVARIABLE subClass Lcom/study/whiteship_study_cyh/Top; L1 L11 1
    LOCALVARIABLE type Ljava/lang/String; L2 L11 2
    MAXSTACK = 2
    MAXLOCALS = 5
}

참조 : https://riptutorial.com/java/example/28573/dynamic-method-dispatch---example-code

 

Java Language Tutorial => Dynamic Method Dispatch - Example Code

Learn Java Language - Dynamic Method Dispatch - Example Code

riptutorial.com

참조2 : https://ko.wikipedia.org/wiki/가상_메소드_테이블

 

가상 메소드 테이블 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 가상 메소드 테이블({{{2}}}, 디스패치 테이블, vtable, 또는 vftable)은 동적 디스패치(또는 런타임 메소드 바인딩)를 지원하기 위해 프로그래밍 언어에서 사용되는

ko.wikipedia.org



추상클래스

추상클래스는 말그대로 구현체가아닌 추상적인 클래스이다. 변수 , 메소드를 가질수 있지만 추상클래스는 인스턴스를 생성할 수 없다. 그렇기 때문에 자손클래스 구현체를 구현하여 인스턴스로 활용하여야한다. 보통 선언부를 작성하는 의미로 사용되어진다.(인터페이스와 비슷)


final 키워드

  • final은 클래스, 메소드 , 변수에 선언할 수 있다.

Class에 final을 선언할때

  • 클래스를 상속을 해줄 수 없다
  • 이 클래스를 상속 받아서 내용을 변경 못하게 한다

Method에 final을 선언하는 이유

  • 더이상 Overring을 할 수 없다

변수에 final을 선언할때

  • 값이 변하지 않게 상수값을 지정
  • 인스턴스 변수나 static으로 선언된 클래스 변수는 선언과 함게 값을 지정해야만한다
  • 초기화를 무조건 해줘야한다
728x90
반응형

'공부 > JAVA' 카테고리의 다른 글

[Java] 클래스  (0) 2022.09.27
[JAVA]제어문  (2) 2022.09.20
[Java] 연산자  (0) 2022.09.14
자바 데이터 타입, 변수 그리고 배열  (0) 2022.09.06
[JAVA] JVM 이란 무엇이며 자바코드는 어떻게 실행되는가  (0) 2022.08.30