β˜• μžλ°” : JAVA

[Java] 상속(Inheritance) μ‚¬μš©λ²•κ³Ό 상속을 μ‚¬μš©ν•˜λŠ” 이유

개발자 HOON 2022. 12. 6. 00:06

🧐 1. 상속이 뭐죠?

ν˜„μ‹€μ„Έκ³„μ—μ„œμ˜ 상속은, λΆ€λͺ¨κ°€ μžμ‹μ—κ²Œ μž¬μ‚°μ„ λ¬Όλ €μ£ΌλŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. μžμ‹μ€ 상속을 λ°›μœΌλ©΄ λΆ€λͺ¨κ°€ 가지고 있던 μžμ›μ„ κ·ΈλŒ€λ‘œ μ–»κ²Œ λ©λ‹ˆλ‹€. 상속을 ν•΄μ£Όλ©΄ ν˜„μ‹€μ„Έκ³„μ˜ λΆ€λͺ¨λŠ” μž¬μ‚°μ„ 물렀쀬기 λ•Œλ¬Έμ— λ‚¨λŠ” μž¬μ‚°μ΄ μ—†μ§€λ§Œ, μžλ°”μ˜ 상속은 그렇지 μ•ŠμŠ΅λ‹ˆλ‹€.

 

μžλ°”μ—μ„œμ˜ 상속(Inheritance)은, λΆ€λͺ¨ 클래슀의 ν•„λ“œμ™€ λ©”μ„œλ“œλ₯Ό λ¬Όλ €λ°›μŠ΅λ‹ˆλ‹€.

class Parent{
    // ν•„λ“œ
    public String value1;

    // λ©”μ†Œλ“œ
    public String getValue1(){
        return this.value1;
    }
}

 

즉, Parent 클래슀λ₯Ό μƒμ†λ°›λŠ” Childκ°€ μžˆλ‹€λ©΄, ν•΄λ‹Ή Child ν΄λž˜μŠ€λŠ” λΆ€λͺ¨μ˜ value1 ν•„λ“œμ™€, getValue1 λ©”μ†Œλ“œ λͺ¨λ‘ κ°–κ²Œ λ©λ‹ˆλ‹€.

κ·Έλ ‡λ‹€κ³  상속을 ν•΄μ€€ ParentλŠ” 아무것도 남지 μ•ŠλŠ” 것이 μ•„λ‹ˆλΌ, Parent 클래슀 κ·ΈλŒ€λ‘œλ„ μ‚¬μš©μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€.

ν˜„μ‹€μ„Έκ³„μ™€ 쑰금 더 λ‹€λ₯Έ 점은, μžμ‹ ν΄λž˜μŠ€κ°€ 상속받고 싢은 λΆ€λͺ¨ 클래슀λ₯Ό μ„ νƒν•΄μ„œ λ¬Όλ €λ°›λŠ”λ‹€λŠ” 점이 쑰금 λ‹€λ₯΄κ² λ„€μš”.

 

κ·Έλ ‡λ‹€λ©΄ μ „ μž¬μ‚°μ„ λ¬Όλ €μ£ΌλŠ” 것이 μ•„λ‹ˆλΌ μΌλΆ€λ§Œ λ¬Όλ €μ£ΌλŠ” κ²½μš°λŠ” μ—†μ„κΉŒμš”?

λ¬Όλ‘  μžˆμŠ΅λ‹ˆλ‹€.

class Parent{
    // ν•„λ“œ
    public String value1;
    private String value2;

    // λ©”μ†Œλ“œ
    public String getValue1(){
        return this.value1;
    }

}

 

μƒμ†ν•˜κ³  싢지 μ•Šμ€ ν•„λ“œμ—λŠ” μ ‘κ·Όμ œμ–΄μž private을 뢙이면, Childμ—λŠ” μƒμ†λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. (νŒ¨ν‚€μ§€κ°€ λ‹€λ₯Έ 경우 default μ ‘κ·Όμ œμ–΄μžλ„ 상속 λΆˆκ°€.)

 

이처럼, 상속은 λΆ€λͺ¨ 클래슀의 ν•„λ“œμ™€ λ©”μ„œλ“œλ₯Ό 물렀받을 수 μžˆλŠ” 방법을 μ˜λ―Έν•©λ‹ˆλ‹€.

 

 

πŸ’‘ 2. 상속을 μ‚¬μš©ν•˜λŠ” 방법

2-1. μƒμ†μ˜ μ„ μ–Έ

 

μƒμ†μ˜ 선언은 extends ν‚€μ›Œλ“œλ₯Ό 톡해 상속 관계λ₯Ό μ„ μ–Έν•  수 μžˆμŠ΅λ‹ˆλ‹€.

class Child extends Parent{
    ... μƒλž΅
}

 

Javaμ—μ„œλŠ” 닀쀑 상속이 λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€. 즉 ν•˜λ‚˜μ˜ μžμ‹ ν΄λž˜μŠ€λŠ” 두 개 μ΄μƒμ˜ λΆ€λͺ¨ 클래슀λ₯Ό κ°€μ§ˆ 수 μ—†μŠ΅λ‹ˆλ‹€. μ˜€λ‘œμ§€ ν•œ 개의 λΆ€λͺ¨ 클래슀만 κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

 

λΆ€λͺ¨ 클래슀의 경우, μ—¬λŸ¬ μžμ‹ ν΄λž˜μŠ€μ—κ²Œ 상속이 κ°€λŠ₯ν•˜κ³  λΆ€λͺ¨ 클래슀 μ—­μ‹œ μ‘°λΆ€λͺ¨ ν΄λž˜μŠ€μ—κ²Œ 상속을 받을 수 μžˆμŠ΅λ‹ˆλ‹€.

class Son extends Parent{
    // κ°€λŠ₯
}

class Daughter extends Parent{
    // κ°€λŠ₯
}

class Parent extends GrandParent{
    // κ°€λŠ₯
}

class Dumb extends Parent, OtherParent{
    // λΆˆκ°€λŠ₯!!!
}

 

 

2-2. λΆ€λͺ¨ μƒμ„±μžμ˜ 호좜 : super()

 

μžλ°”μ—μ„œ μžμ‹ 객체λ₯Ό μƒμ„±ν•˜λ©΄ λΆ€λͺ¨ 객체λ₯Ό λ¨Όμ € μƒμ„±ν•œ ν›„, μžμ‹ 객체가 λ‚˜μ€‘μ— μƒμ„±λ©λ‹ˆλ‹€.

λ§Œμ•½ μ½”λ“œ μƒμ—μ„œ λΆ€λͺ¨ 객체λ₯Ό μƒμ„±ν•˜λŠ” 과정이 없더라도, λ‚΄λΆ€μ μœΌλ‘œ λΆ€λͺ¨ 객체λ₯Ό μƒμ„±ν•œ ν›„, μžμ‹ 객체가 μƒμ„±λ©λ‹ˆλ‹€.

객체가 생성될 λ•Œ, 객체의 μƒμ„±μžκ°€ μžλ™μœΌλ‘œ ν˜ΈμΆœλ©λ‹ˆλ‹€. λ”°λΌμ„œ μžμ‹ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜λ©΄, μš°μ„ μ μœΌλ‘œ λΆ€λͺ¨ 클래슀의 μƒμ„±μžκ°€ ν˜ΈμΆœλ©λ‹ˆλ‹€.

 

λ§Œμ•½, λΆ€λͺ¨ ν΄λž˜μŠ€μ— μƒμ„±μžλ₯Ό λ”°λ‘œ λͺ…μ‹œν•˜μ§€ μ•ŠμœΌλ©΄, λΆ€λͺ¨ ν΄λž˜μŠ€λŠ” κΈ°λ³Έ μƒμ„±μž(νŒŒλΌλ―Έν„°κ°€ ν•˜λ‚˜λ„ μ—†λŠ”)λ₯Ό κ°–κ²Œ 되고 이λ₯Ό μ»΄νŒŒμΌλŸ¬κ°€ μ•Œμ•„μ„œ ν˜ΈμΆœν•˜κ²Œ λ©λ‹ˆλ‹€.

μžμ‹ ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•˜λ―€λ‘œ, λ‚΄λΆ€μ μœΌλ‘œ super();λ₯Ό ν˜ΈμΆœν•˜κ²Œ λ©λ‹ˆλ‹€.

 

λ°˜λ©΄μ—, λΆ€λͺ¨ ν΄λž˜μŠ€μ— μƒμ„±μžκ°€ λͺ…μ‹œλ˜μ–΄μžˆλ‹€λ©΄, μžμ‹ ν΄λž˜μŠ€λŠ” ν•΄λ‹Ή λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν†΅ν•΄μ„œ λΆ€λͺ¨ 클래슀λ₯Ό μš°μ„  λ§Œλ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€.

μ΄λ•Œ μžμ‹ 클래슀 내뢀에 직접 super(xx, xx ...); 둜 선언을 ν•΄μ£Όμ–΄μ•Ό ν•©λ‹ˆλ‹€. (μ»΄νŒŒμΌλŸ¬κ°€ μ•Œμ•„μ„œ 호좜 κ°€λŠ₯ν•œ μ˜μ—­μ€ κΈ°λ³Έ μƒμ„±μžλΏμž…λ‹ˆλ‹€.)

 

class NoConstructorParent{
    String v1;
    String v2;
}

class ConstructorParent{
    String v1;
    String v2;
    ConstructorParent(String _v1, String _v2){
        this.v1 = _v1;
        this.v2 = _v2;
    }
}

class Child1 extends NoConstructorParent{
    public Child1(String _v1, String _v2){
        // super(); μžλ™ 호좜
        this.v1 = _v1;
        this.v2 = _v2;
    }
}

class Child2 extends ConstructorParent{
    public Child2(String _v1, String _v2){
        super(_v1, _v2); // λ°˜λ“œμ‹œ κ°œλ°œμžκ°€ 호좜
    }
}

 

 

2-3. 상속 κ΄€κ³„μ—μ„œ Lombok의 @Builder μ‚¬μš©

 

Lombok λΌμ΄λΈŒλŸ¬λ¦¬μ—λŠ” @Builderκ°€ μžˆμŠ΅λ‹ˆλ‹€.

이 @Builder μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λ©΄ νŒŒλΌλ―Έν„°λ₯Ό ν™œμš©ν•΄ λΉŒλ” νŒ¨ν„΄μ„ μžλ™μœΌλ‘œ μƒμ„±ν•΄μ€λ‹ˆλ‹€.

 

이 λ•Œ λΆ€λͺ¨μ™€ μžμ‹ 클래슀 λͺ¨λ‘ @Builder μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•˜λ©΄, 컴파일 μ—λŸ¬κ°€ λ°œμƒν•©λ‹ˆλ‹€!

이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œλŠ”, Lombokμ—μ„œ μ œκ³΅ν•˜λŠ” @SuperBuilder μ–΄λ…Έν…Œμ΄μ…˜μ„ μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.

μžμ‹ 클래슀 μΈμŠ€ν„΄μŠ€λ₯Ό Lombok 라이브러리λ₯Ό ν™œμš©ν•΄ λΉŒλ” νŒ¨ν„΄μœΌλ‘œ μƒμ„±ν•˜κ³  μ‹Άλ‹€λ©΄, μžμ‹κ³Ό λΆ€λͺ¨ 클래슀 λͺ¨λ‘ @SuperBuilder μ–΄λ…Έν…Œμ΄μ…˜μ„ λΆ™μ—¬μ£Όλ©΄ λ©λ‹ˆλ‹€.

@SuperBuilder
class Child extends Parent{
    ... μƒλž΅
}

@SuperBuilder
class Parent{
    ... μƒλž΅
}

// Child.builder()λ₯Ό 톡해 λΆ€λͺ¨ 클래슀의 ν•„λ“œλ„ λΉŒλ” νŒ¨ν„΄μœΌλ‘œ 생성 κ°€λŠ₯!

μžμ„Έν•œ λ‚΄μš©μ€ λ‹€λ₯Έ κΈ€λ‘œ ν¬μŠ€νŒ…ν•˜λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

 

2-4. λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©κ³Ό @Override

 

λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©μ€ μžμ‹ ν΄λž˜μŠ€κ°€ λΆ€λͺ¨ ν΄λž˜μŠ€μ— μ‘΄μž¬ν•˜λŠ” λ©”μ†Œλ“œμ™€ λ™μΌν•œ νŒŒλΌλ―Έν„°λ₯Ό κ°–λŠ” λ©”μ†Œλ“œλ₯Ό μž¬μ •μ˜ν•΄μ„œ λΆ€λͺ¨ 클래슀의 λ©”μ†Œλ“œλ₯Ό κ°μΆ”λŠ” κΈ°μˆ μž…λ‹ˆλ‹€.

 

λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©κ³Ό μ˜€λ²„λ‘œλ”©μ΄ μžλ°”μ—μ„œ μ–΄λ–€ μ‹μœΌλ‘œ μ΄λ€„μ§€λŠ”μ§€ 잘 λ‚˜νƒ€λ‚Έ 글이 μžˆμœΌλ‹ˆ, μ°Έκ³ ν•˜μ‹œλ©΄ λ§Žμ€ 도움을 μ–»μœΌμ‹€ κ²λ‹ˆλ‹€.

 

[Java] λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©/ λ©”μ†Œλ“œ μ˜€λ²„λ‘œλ”©μ„ ν†΅ν•œ 상속 λ‹€ν˜•μ„±μ— λŒ€ν•œ 이해와 Self μ°Έμ‘°

μ•„λž˜μ˜ λ‚΄μš©μ€ 였브젝트(Object)λ₯Ό μ½μœΌλ©΄μ„œ μ •λ¦¬ν•œ λ‚΄μš©μž…λ‹ˆλ‹€. Java에 ν•œμ •λ˜λŠ” μ΄μ•ΌκΈ°μ΄λ―€λ‘œ λ‹€λ₯Έ μ–Έμ–΄μ—λŠ” μ μš©λ˜μ§€ μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€. 1. 상속을 μ΄μš©ν•œ λ‹€ν˜•μ„±κ³Ό λ©”μ†Œλ“œ μ˜€λ²„λΌμ΄λ”©/ λ©”μ†Œλ“œ

mangkyu.tistory.com

 

μ˜€λ²„λΌμ΄λ”©μ€ λ‹¨μˆœνžˆ μžμ‹ ν΄λž˜μŠ€μ—μ„œ λΆ€λͺ¨ ν΄λž˜μŠ€κ°€ 가지고 μžˆλŠ” λ©”μ†Œλ“œμ™€ 같은 ν˜•μ‹(리턴 νƒ€μž…, λ©”μ†Œλ“œ λͺ…, νŒŒλΌλ―Έν„°)으둜 μž‘μ„±ν•˜λ©΄ μžλ™μœΌλ‘œ μ˜€λ²„λΌμ΄λ”© 적용이 λ©λ‹ˆλ‹€.

 

@Override μ–΄λ…Έν…Œμ΄μ…˜μ€, μ‹€μ œλ‘œ ν•΄λ‹Ή μ–΄λ…Έν…Œμ΄μ…˜μ„ 달아야 μ˜€λ²„λΌμ΄λ”©μ΄ λ˜λŠ” 것이 μ•„λ‹ˆλΌ ν•΄λ‹Ή λ©”μ†Œλ“œκ°€ μ˜€λ²„λΌμ΄λ“œ ν–ˆλ‹€λŠ” 것을 λͺ…μ‹œν•΄μ£ΌλŠ” μ–΄λ…Έν…Œμ΄μ…˜μ΄κ³  μ»΄νŒŒμΌλŸ¬μ—κ²Œ 문법체크λ₯Ό μœ λ„ν•˜λŠ” κΈ°λŠ₯을 κ°–μŠ΅λ‹ˆλ‹€. (λΆ€λͺ¨μ— μ—†λŠ” ν˜•μ‹μ˜ λ©”μ†Œλ“œλ₯Ό μžμ‹ 클래슀의 λ©”μ†Œλ“œ μœ„μ— @Overrideλ₯Ό 달면 컴파일 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.)

 

class Parent{
    public void greet(){
        System.out.println("μ•ˆλ…•ν•˜μ„Έμš”");
    }
}

class Child extends Parent{
    @Override
    public void greet(){
        System.out.println("μ•ˆλ…•?");    
    }
}
Child child = new Child();
child.greet() // "μ•ˆλ…•?"

 

 

2-5. 상속과 λ‹€ν˜•μ„±(polymorphism)

 

λ‹€ν˜•μ„±μ€, ν•˜λ‚˜μ˜ 객체가 μ—¬λŸ¬κ°€μ§€ νƒ€μž…μ„ κ°€μ§ˆ 수 μžˆλŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€.

μžλ°”μ—μ„œλŠ” λΆ€λͺ¨ 클래슀 νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ‘œ μžμ‹ 클래슀 νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•  수 μžˆλ„λ‘ ν•΄ λ‹€ν˜•μ„±μ„ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ½”λ“œλ‘œ 보면 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

class Parent {...}
class Child extends Parent {...}

// λ‹Ήμ—°νžˆ ν—ˆμš©
Parent pa = new Parent(); 
Child ch = new Child();

// ν—ˆμš© (λΆ€λͺ¨ 클래슀 νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜ pc둜 μžμ‹ 클래슀 νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€ new Child()λ₯Ό μ°Έμ‘°ν•˜λ„λ‘ 함.)
Parent pc = new Child();

// 였λ₯˜ λ°œμƒ.
Child cp = new Parent();

 

 

2-6. 상속과 instanceof

 

λ‹€ν˜•μ„±μœΌλ‘œ 인해, λŸ°νƒ€μž„ 쀑에 μ°Έμ‘° λ³€μˆ˜κ°€ μ‹€μ œλ‘œ μ°Έμ‘°ν•˜κ³  μžˆλŠ” μΈμŠ€ν„΄μŠ€μ˜ νƒ€μž…μ„ 확인할 ν•„μš”μ„±μ΄ μžˆμŠ΅λ‹ˆλ‹€.

μ΄λ•Œ, instanceof μ—°μ‚°μžλ₯Ό ν†΅ν•΄μ„œ μΈμŠ€ν„΄μŠ€μ˜ μ‹€μ œ νƒ€μž…μ„ ν™•μΈν•˜λ„λ‘ λ„μ™€μ€λ‹ˆλ‹€.

class Parent{...}
class Child extends Parent{...}

Parent p = new Parent();
p instanceof Parent; // true
p instanceof Child; // false

 

 

🧐 3. ν”νžˆ μ•Œλ €μ§„ 상속을 ν•˜λŠ” 이유

 

상속을 ν•˜λ©΄, 곡톡적인 뢀뢄을 가지고 μžˆλŠ” μƒμœ„ 클래슀λ₯Ό ν™œμš©ν•˜λ©΄μ„œλ„, ν•˜μœ„ ν΄λž˜μŠ€λŠ” 본인 고유의 μƒνƒœμ™€ 행동을 μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ 상속을 ν†΅ν•΄μ„œ 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ°μ˜ νŠΉμ§•μΈ λ‹€ν˜•μ„±μ„ λ§Œμ‘±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ½”λ“œμ˜ ν™•μž₯μ„±, μž¬μ‚¬μš©μ„±μ΄ μš©μ΄ν•˜κ³  μ€‘λ³΅λœ μ½”λ“œλ₯Ό μƒμœ„ 클래슀둜 λͺ°μ•„ 넣을 수 μžˆμœΌλ―€λ‘œ μ½”λ“œκ°€ κ°„κ²°ν•΄μ§‘λ‹ˆλ‹€. κ²°κ³Όμ μœΌλ‘œλŠ” μœ μ§€λ³΄μˆ˜μ˜ μš©μ΄μ„±μ„ μœ„ν•΄μ„œ νƒ„μƒν•œ 것이 λ°”λ‘œ 상속이죠.

 

κ·Έλ ‡μ§€λ§Œ 상속은 μž₯점만 μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

상속을 μ‚¬μš©ν–ˆμ„ λ•Œμ˜ 단점이 치λͺ…적일 수 있기 λ•Œλ¬Έμ—, κΌ­ μ‚¬μš©ν•΄μ•Ό ν•˜λŠ” 것인지 꼼꼼히 λ”°μ Έκ°€λ©° μ‚¬μš©ν•΄μ•Όν•©λ‹ˆλ‹€.

μƒμ†μ˜ μž₯단점과, 그럼 μ–΄λ–€ κ²½μš°μ— 상속을 μ‚¬μš©ν•΄μ•Ό ν•˜λŠ”μ§€ λ‹€μŒ κΈ€μ—μ„œ 따져보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

 

 

[Java] μƒμ†μ˜ μž₯단점, 상속은 μ–Έμ œ 써야 ν•˜λŠ”κ°€?

🧐 1. 상속이 뭐죠? [Java] 상속(Inheritance) μ‚¬μš©λ²•κ³Ό 상속을 μ‚¬μš©ν•˜λŠ” 이유 🧐 1. 상속이 뭐죠? ν˜„μ‹€μ„Έκ³„μ—μ„œμ˜ 상속은, λΆ€λͺ¨κ°€ μžμ‹μ—κ²Œ μž¬μ‚°μ„ λ¬Όλ €μ£ΌλŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. μžμ‹μ€ 상속을 λ°›μœΌλ©΄

hoons-dev.tistory.com

 

 

🌎 좜처/인용

https://blog.naver.com/PostView.nhn?blogId=heartflow89&logNo=220960019390
https://chanhuiseok.github.io/posts/java-1/
https://mangkyu.tistory.com/193
https://velog.io/@pearl0725/Override-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98%EC%9D%98-%EC%9D%98%EB%AF%B8%EC%99%80-%EC%82%AC%EC%9A%A9-%EC%9D%B4%EC%9C%A0%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C
http://www.tcpschool.com/java/java\_polymorphism\_concept