Live-Study

[6주차] 상속

youn12 2021. 2. 19. 16:10
✏️ Info.

- Java 상속 학습

📋 List.

1. 자바 상속의 특징
2. super 키워드
3. 메서드 오버 라이딩
4. 다이내믹 메서드 디스패치 (Dynamic Method Dispatch)
5. 추상 클래스
6. final 키워드
7. Object 클래스

✔️ Content.

 

1. 자바 상속의 특징

 

* 상속 : 자식이 부모로부터 무언가 물려받는 것

  • Java 상속 : 자식 클래스가 기존의 부모 클래스로부터 기능을 물려받아 자식의 클래스에 기능을 추가하거나, 나 재정의하여 새로운 클래스를 정의하는 것.

 

장점

  • 클래스, 멤버 재활용
  • 클래스 간의 계층 관계 구성으로 다형성 토대 마련

 

특징

  •  하나의 클래스만 상속 - 다중 상속 불가능
  •  부모 클래스의 멤버와 메서드만이 상속되며, 생성자와 초기화 블록은 상속되지 않는다.
  •  부모 클래스의 접근제어가 private 또는 default로 설정된 멤버는 자식 클래스가 상속받지만 접근할 수 없다. 
  •  기본적으로 클래스는 Object 클래스를 상속받는다.

 

사용

  • 사용하고자 하는 클래스 뒤에 'extends'와 함께 상속받고자 하는 클래스를 작성해 주면 된다.
// 부모 클래스
class parentClass{}

// 자식 클래스 
class childClass extends parentClass{}

 

부모 클래스 : parentClass

자식 클래스 : childClass

 

* 실습 과정에서 캐스팅에서 오류를 발견했다.

 

public static void main(String[] args) {

        parentClass parentClass = new parentClass();
        parentClass childClass = new childClass();
        childClass childClass1 = new childClass();
        childClass childClass2 = (childClass) new parentClass(); //부모 객체에 자식 인스턴스 생성 가능 하지만, 자식 객체에 부모 인스턴스는 불가능
     
    }

 

위의 3개의 인스턴스 생성에서는 문제가 없지만

자식 클래스 객체에 부모 인스턴스 생성은 불가능했다.

  • 인스턴스 생성에는 클래스가 필요로 하는 정보를 채워줘야 한다.
  • childClass chidClass2는 childClass 클래스가 필요로 하는 정보를 채워줘야 하는데 parentClass 클래스는 childClass 클래스 필요 정보를 가지고 있지 않기 때문에 채워 넣을 수 없다.
  • 또한 위의 코드에서 (childClass)로 캐스팅할 경우 Compile Error는 나지 않지만 RunTime Error가 발생한다.
    • Compile은 캐스팅을 했기 때문에 데이터 주입이 가능하다 판단하고 Error를 발생하지 않는다
    • RunTime은 JVM이 런타임 과정에서 실제로 데이터 주입하면서 필요로 하는 데이터를 찾지 못하기 때문에 Casting Error를 발생시킨다.

 

2. super 키워드

 

 

* 상속받은 부모 클래스의 멤버, 메서드를 불러올 때 사용

 

사용

  • super.said() : parentClass의 said() 함수 호출
  • super.name : parentClass의 name 멤버 호출
class parentClass{

        String name = "Mom";

        void said(){
            System.out.println("HI, " + this.getClass().getSimpleName());
        }
    }

class childClass extends parentClass{

        private void child(){
            super.said();
            System.out.println(super.name);            
        }
    }

 


 

3. 메서드 오버 라이딩

 

 

* 상속받은 부모 클래스의 메서드를 재정의 할 때 사용

 

사용

  • childClass의 said() : parentClass의 said() 함수를 재정의해서 사용
class parentClass{
    
        void said(){
            System.out.println("HI, " + this.getClass().getSimpleName());
        }    
}

class childClass extends parentClass{

        @Override
        void said() {
            System.out.println("NO, HI");
        }      
}

 

4. 다이내믹 메서드 디스패치 (Dynamic Method Dispatch)

 

 

* Method Dispatch : 어떤 메서드를 호출할지 결정하여 실제로 실행시키는 과정

 

1. Static Dispatch

  • Compile 시점에서 이미 컴파일러가 특정 메소드를 호출할 것을 명확하게 알고 있는 경우
  • Compile 시 생성된 Byte Code에도 이 정보가 그대로 남아있다.
  • ex) 객체의 변수 타입과 인스턴스의 타입이 같을 경우
public static void main(String[] args) {

        parentClass parentClass = new parentClass();
        childClass childClass1 = new childClass();
     
    }

2. Dynamic Dispatch

  • Interface(인터페이스) or Abstract Class(추상화 클래스)에서 정의된 abstract method를 호출하는 경우에 해당
  • 아래의 예를 보면 main에서는 childClass가 new childClass();에 의해 인스턴스가 생성됨을 알 수 있지만, 실제로 Dispatcher 내부에서는 파라미터로 받은 childClass의 객체에 바인딩된 클래스는 compile단계에서 알 수 없으며 Runtime 단계에서 결정되므로  Dynamic Dispatch에 해당한다.
  • ex)
public static void main(String[] args) {

        parentClass childClass = new childClass();
     	
        new Dispatcher().doAction(childClass)
    }
    

class Dispatcher{
	public void doAction(parentClass childClass){
    	childClass.doAction();
    }
}

 

! 추가 공부 사항 - Double Dispatch


 

5. 추상 클래스

 

 

 * 객체 지향 프로그래밍에서 중요한 특징인 다형성을 가지는 메서드의 집합을 정의

  • 즉, 반드시 사용되어야 하는 메서드를 추상 클래스에 추상 메소드로 선언해 놓으면, 이 클래스를 상속받는 모든 클래스에서는 이 추상 메소드를 반드시 재정의 해야 한다.
  • 하나 이상의 추상 메소드를 포함하는 클래스
  • 추상 메소드를 포함하는 것을 제외하면 일반 클래스와 모든 점이 같다.
  • 추상 클래스는 인스턴스를 생성할 수 없다

 

사용

abstract class ClassName{
 	abstract void methodName();
 }

 

6. final 키워드

 

 

* 마지막, 변경될 수 없는 의미를 가진다.

  • final 클래스 : 변경될 수 없는 클래스, 확장될 수 없는 클래스
  • final 메소드 : 변경될 수 없는 메서드, overriding 불가
  • final 변수 : 값을 변경할 수 없는 상수가 된다.
public final class Fclass{
	
    final int fVal = 0;
    
    public final void fMethod(){
    	System.out.println("fMethod");
    }
}

 

7. Object 클래스

 

 

* 모든 클래스의 부모가 되는 클래스, extends  가 없는 클래스에 컴파일러는 자동으로 Object클래스를 상속한다.

 

 

메서드 설명
protected Object clone() 해당 객체를 복제하여 새로운 인스턴스를 생성해 반환한다.
필드의 값만을 복사하므로, 필드 값이 배열, 인스턴스면 제대로 복제될 수 없다.
필요시 재정의해서 구현
public boolean equals(Object obj) 객체 자신과 입력받은 객체 obj가 같은 객체인지 반환
protected void finalize() 객체가 소멸될 때 가비지 컬렉터에 의해 자동적으로 호출한다.
public Class getClass() 객체 자신의 클래스 정보를 담고 있는 인스턴스를 반환한다.
public int hashCode() 객체 자신의 해시코드를 반환한다.
public String toString() 객체 자신의 정보를 문자열로 반환한다.
이때 반환 되는 문자열은 클래스 이름과 함께 구분자로 '@'가 사용되며, 그뒤로 16진수 해쉬코드(hash code)(인스턴스 주소 값)가 추가 된다.
public void notify() 객체 자신을 사용하려고 기다리고 있는 쓰레드 하나만 깨워준다.
public void notifyAll() 객체 자신을 사용하려고 기다리고 있는 쓰레드를 모두 깨워준다.
public void wait()
public void wait(long timeout)
public void wait(long timeout, int nanos)
다른 쓰레드가 notify() 또는 notifyAll()을 호출할 떄까지 현재 쓰레드를 무한히 또는 지정된 시간 동안 기다리게 한다.

❗️ Refer.

- 상속
https://wikidocs.net/280
http://www.tcpschool.com/java/java_inheritance_concept
(다운 캐스팅) https://mommoo.tistory.com/51

- 다이내믹 메서드 디스패치 (Dynamic Method Dispatch)
https://defacto-standard.tistory.com/413

-Object
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html
http://www.tcpschool.com/java/java_api_object

'Live-Study' 카테고리의 다른 글

[8주차] 인터페이스  (0) 2021.02.19
[7주차] 패키지  (0) 2021.02.19
[5주차] 클래스  (0) 2021.01.04
[4주차] 제어문  (0) 2020.12.31
[3주차] 연산자  (0) 2020.11.23