JAVA

[ java ] 객체 상속

Adose 2024. 12. 10. 11:27

📌 상속이란?


✏️ 상속의 흐름

  • 설계를 하며 여러가지의 공통된 개념(또는 기능)들을 하나(상위 클래스)로 일반화할 수 있다. → 이것을 추상화 또는 일반화라고 한다.
  • 이러한 상위 클래스의 기능을 기반으로 새로운 특성을 추가하거나, 오버라이딩 하는 과정을 할 수 있다 → 이것을 확장이라고 한다

—> 이러한 과정을 상속이라고 한다.

  • 아래 사진처럼 다중 상속 불가능
  • java는 단일상속이 가능하지만, 다중 상속이 불가능하다.
  • A, B 부모 객체가 있을때 C 자녀는 두개의 부모 객체를 가질 수 없다.

  • 하지만 직계 상속은 가능하다
    • A의 부모가 B일때, C는 B를 조상으로 가질 수 있다 = (직계)
    • C는 B의 기능도 사용이 가능하다.

 

📌 상속의 특징


🔥 용어 정리

  • 업캐스팅: 부모 타입으로 변환(자동,암묵적)
  • 다운캐스팅: 자식 타입으로 변환(수동, 명시적)
  • instanceof를 통해 객체가 특정 클래스인지 확인하는 것이 좋음

 

📌 부모(조상)는 자식(자손)을 담을(가리킬) 수 있다.

class Child extends Parent{
    int age = 0;
}
public class Parent {
    private int age;
    
    public static void main(String[] args) {
        //부모는 자식을 가리킬 수 있다. 
        Parent parent = null; 
        Child child = null;

        
        //부모는 자식을 담을 수 있다. 
        //**묵시적 형변환**이 일어난다. 
        parent = new Child(); 
        //Parent type으로 child를 가리킬 수 있다.
        
    }
}

  • 묵시적 형변환을 통해서 부모는 자식을 담을(카리킬) 수 있다.
    • 묵시적 형변환 ( = 업캐스팅 )
    • parent = new Child()
  • 묵시적 형변환 예시
    • long에는 int를 담을 수 있다.
    • int 에는 long을 담을 수 없다.

 

 

📌 자식 객체는 부모 객체를 담을(가리킬)수 없을까 ?


  • 명시적 형변환을 통해서 담을(가리킬) 수있다.
    • 객체가 실제로 자식 타입의 인스턴스여야만 형변환이 가능하다. -> 안전성 확인으로 intanceof 사용 
    • 부모 타입에 자식 객체 생성하는 것이다.
  • But 예외 발생을 주의해야 한다!!! (아래에 설명해둠)
class Child extends Parent{
    public void 자식메서드(){
        System.out.println("자식임");
    }
}

public class Parent {
    public void 부모메서드(){
        System.out.println("부모임");
    }
    
    public static void main(String[] args) {
        Parent parent = new Child;
        Child child = new Child();

        child = (Child)parent;
    }
  • 코드 설명
    • Parent 객체를 생성할때, 생성자를 Child()로 해주어서, Parent가 Child를 담을 수 있게 한다.
      • Parent parent = new Child;
    • 명시적 형변화인 (child)parent 를 사용하여 다운 캐스팅이 가능하다.
      • child = (Child)parent;

 

 

(🔥 예외발생 주의) 자식 객체는 부모 객체를 담을(가리킬)수 없을까 ?


  • ㄴㄴ 가능, 위에 봤듯이 명시적 형변환을 통해서 가능하다.
    • 객체가 실제로 자식 타입의 인스턴스여야만 형변환이 가능하다.
    • 부모 타입에 자식 객체 생성하는 것이다.
  • 생성된 부모 객체를, 자식 객체에 담을 순 없다.

예시코드 (이코드는 예외 발생)

Parent parent = null;
Child child = null;

p = new parent() //부모 생성자 생성 

child = (child)parent;  //부모 생성자를, 자식 생성자로 다운캐스팅
 
  • 코드 설명
    • 위 코드는 **new Parent()**로 부모 생성자를 생성한 것을 알 수 있다.
      • p = new parent()
    • 생성된 부모 객체를, child 객체의 다운캐스팅(명시적 형변환) 하려는 경우이다.
      • child = (child)parent;
    • 문법 오류는 발생하지 않는 것을 확인할 수 있다.
    • 하지만 실행(런타임 시점)이 된다면 예외가 발생한다

 

⚠️ 예외 발생 ⚠️

  • 컴파일시에는 변수의 타입으로 상속, 형변환 가능 유무를 판단 하여 진짜 객체를 확인하지 못해서 문법 오류가 발생하지 않는다
  • 하지만 런타임 시점에는 적절하지 않는 문법이라고 판단하여 ClassCastException 예외가 발생한다.
    • 객체를 확인하고 오류 발생 !
  • ClassCastEsceptoon 발생 이유 ?
    • child는 Parent를 상속받고 있고, child는 Parent 타입보다 작기 때문에 형변환을 시도 할 수 없어서 오류가 발생한다.

 

🔥 그냥 메모

📌 상속 형변환의 확인 ? - instanceof


class Teacher extends Person{}
class Student extends Person{}
class Dog extends Animal{}

pulic class Person(){
	Person person = new Teacher();
	Teacher teacher= null;
	

if (tesacher instanceof Person){ //조건을 걸어서 해당 클래스의 실체 객체를 확인한다. 
		teacher = (Person)person;
}

}
  • 형변환하려는 참조 변수의 타입이 형변환을 하려는 타입이 아닐 수도 있다.
  • instanceof를 사용하여 객체의 진짜 타입을 명시하여, 실제 객체를 확인하여 안전성을 높인다.

걍 → instance of를 통해 해당 객체의 실제 객체를 확인한다. (안전한지 아닌지 확인 )

 

 

📌  Object - 모든 클래스의 최상위 상속

pulic test{

} 

// object를 객체로 가지고 있는 것이다. 그냥 생략되어져 있는거임
pulic test extends Object{

}
  • 모든 객체는 최상위 객체로 Objecet를 가지고 있다.
    • java.lang.Object
  • 아무것도 선언하지 않더라도 모든 객체는 최상위 객체로 Objecet를 가지고 있다.

 

 

📌  @Override

  • 자식이 부모의 메서드를 오버라이드 했을때, 컴파일러가 문법적으로 한번 더 체크해준다.
    • 컴파일 시점에서 부모 클래스와 자식 클래스의 메서드가 맞는지 검사하고, 잘못된 오버라이딩을 방지할 수 있다.
  • @Override는 컴파일러에게 해당 메서드가 부모 클래스의 메서드를 오버라이드하려는 의도임을 알려준다.
    •