[JAVA] ν—·κ°ˆλ¦¬λŠ” 상속 정리

1. κ°œμš”

JAVA λ₯Ό κ³΅λΆ€ν•˜λ©΄ κ°€μž₯ μ²˜μŒμ— λ“£κ³ , 자주 λ“€μœΌλ©°, JAVA κ΄€λ ¨ ν¬μ§€μ…˜μœΌλ‘œ 지원 μ‹œ λ§Žμ€ λ©΄μ ‘μ—μ„œλ„ λ‹¨κ³¨λ‘œ λ“±μž₯ν•˜λŠ” λ‚΄μš©λ“€μ΄ μžˆλ‹€. 상속에 κ΄€ν•œ λ‚΄μš©λ“€μΈλ°, λΆ€λ„λŸ½μ§€λ§Œ 기초적인 λ‚΄μš©μ΄λΌκ³  μƒκ°ν•˜κ³  κ΄„μ‹œν•˜κ³  μžˆλ‹€κ°€ 싀무λ₯Ό ν•˜λ©΄μ„œλ„ ν—·κ°ˆλ¦¬λŠ” μˆœκ°„μ΄ μ œλ²• μžˆμ—ˆλ‹€. 마침 학ꡐ μˆ˜μ—…μœΌλ‘œ μžλ°” κ³Όλͺ©μ„ λ“£λ˜ 쀑, μ •λ¦¬ν•˜κΈ°μ— 쒋은 κΈ°νšŒκ°€ 생겨 ν•œλ²ˆ 정리해두렀고 ν•œλ‹€.

2. μ ‘κ·Όμ œμ–΄μž

ν‚€μ›Œλ“œ μ‚¬μš© λ²”μœ„ ν΄λž˜μŠ€μ— μ‚¬μš©ν•  μ‹œ
public μ „ λ²”μœ„ - 클래슀λͺ…κ³Ό μ†ŒμŠ€νŒŒμΌλͺ… 일치 
- ν•œ μ†ŒμŠ€νŒŒμΌ 내에 ν•˜λ‚˜λ§Œ 쑴재 κ°€λŠ₯
default (μƒλž΅) 같은 νŒ¨ν‚€μ§€ λ‚΄  
private ν•΄λ‹Ή 클래슀 λ‚΄λΆ€ InnerClass λ₯Ό μ •μ˜ν•  μ‹œμ—λ§Œ μ‚¬μš©
protected ν•΄λ‹Ή 클래슀 및 μƒμ†ν΄λž˜μŠ€ λ‚΄λΆ€ InnerClass λ₯Ό μ •μ˜ν•  μ‹œμ—λ§Œ μ‚¬μš©

3. final ν‚€μ›Œλ“œ

  • ν•„λ“œ
    • μ„ μ–Έ ν›„ μ΄ˆκΈ°ν™”κ°€ 이루어지면 μ ˆλŒ€λ‘œ 값을 λ³€κ²½ν•  수 μ—†λŠ” μƒμˆ˜κ°€ λœλ‹€.
  • λ©”μ†Œλ“œ
    • μ˜€λ²„λΌμ΄λ”©μ΄ λΆˆκ°€λŠ₯해진닀.
  • 클래슀
    • ν•΄λ‹Ή 클래슀λ₯Ό μƒμ†λ°›λŠ” μ„œλΈŒ 클래슀λ₯Ό μ •μ˜ν•  수 μ—†λ‹€.

4. static ν‚€μ›Œλ“œ

  • ν•„λ“œ
    • νŠΉμ • 객체에 static ν•„λ“œκ°€ μ‘΄μž¬ν•˜λ©΄ λ‹€λ₯Έ 참쑰값을 κ°€μ§€λŠ” 객체가 아무리 λ§Žμ•„λ„ 같은 값을 κ³΅μœ ν•œλ‹€.
  • λ©”μ†Œλ“œ
    • 객체의 μΈμŠ€ν„΄μŠ€μ™€ λ¬΄κ΄€ν•˜κ²Œ μ–΄λ””μ„œλ“  호좜이 κ°€λŠ₯ν•˜λ―€λ‘œ non-static ν•„λ“œλ‚˜ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  수 μ—†λ‹€.
  • 클래슀
    • static ν‚€μ›Œλ“œλŠ” μ›λž˜ ν΄λž˜μŠ€μ—λŠ” 뢙일 수 μ—†μœΌλ‚˜, μ˜ˆμ™Έμ μœΌλ‘œ 쀑첩 클래슀(inner class) λ₯Ό μ„ μ–Έν•  λ•Œμ— μ‚¬μš©ν•  수 μžˆλ‹€.
 class Scratch {

    public static void main(String[] args) throws IOException {

        // Static 쀑첩 ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ 클래슀 μΈμŠ€ν„΄μŠ€κ°€ 없어도 생성할 수 있음
        OuterClass.NestedStaticClass nsc = new OuterClass.NestedStaticClass();
        nsc.printStaticMsg();

        // 일반 쀑첩 ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ 클래슀 μΈμŠ€ν„΄μŠ€κ°€ μ„ μ–Έλ˜μ–΄μ•Όμ§€λ§Œ 생성할 수 있음
        OuterClass outer = new OuterClass();
        OuterClass.InnerClass inner = outer.new InnerClass();
        inner.printMsg();

        // μ•„λž˜μ™€ 같은 ν˜•νƒœλ‘œλ„ μ„ μ–Έ κ°€λŠ₯
        OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();

        innerObject.printStaticMsg();

    }
}

class OuterClass {

    private static String msg = "정적 λ©”μ‹œμ§€";
    private String msg2 = "일반 λ©”μ‹œμ§€";

    public static class NestedStaticClass {
        public void printStaticMsg() {
            System.out.println("[Static 쀑첩 ν΄λž˜μŠ€μ—μ„œ 호좜 됨] : " + msg);
        }
        // ERROR -> Static 쀑첩 ν΄λž˜μŠ€μ—μ„œλŠ” Non-Static ν•„λ“œλ₯Ό ν˜ΈμΆœν•  수 μ—†μŒ
//        public void printMsg() {
//            System.out.println("[Static 쀑첩 ν΄λž˜μŠ€μ—μ„œ 호좜 됨] : " + msg2);
//        }
    }

    public class InnerClass {
        public void printStaticMsg() {
            System.out.println("[INNER ν΄λž˜μŠ€μ—μ„œ 호좜 됨]" + msg);
        }
        public void printMsg() {
            System.out.println("[INNER ν΄λž˜μŠ€μ—μ„œ 호좜 됨]" + msg2);
        }
    }
}

μ‹€ν–‰ κ²°κ³Ό

5. μΊ‘μŠν™”

클래슀 λ‚΄μ˜ ν•„λ“œλ₯Ό private μ ‘κ·Όμ œμ–΄μžλ‘œ μ„ μ–Έν•˜μ—¬ μ™ΈλΆ€μ—μ„œ μ‰½κ²Œ μ œμ–΄ν•˜μ§€ λͺ»ν•˜λ„둝 ν•˜κ³ , λͺ…μ‹œμ μΈ public λ©”μ†Œλ“œλ₯Ό 톡해 값을 μ œμ–΄ν•œλ‹€.

6. μ˜€λ²„λ‘œλ”©κ³Ό μ˜€λ²„λΌμ΄λ”©

  • μ˜€λ²„λ‘œλ”©
    • λ©”μ†Œλ“œ μž¬μ •μ˜ - 이름은 λ™μΌν•˜λ‚˜ λ§€κ°œλ³€μˆ˜κ°€ λ‹€λ₯Έ λ©”μ†Œλ“œλ₯Ό μ •μ˜ν•˜λŠ” 것
  • μ˜€λ²„λΌμ΄λ”©
    • μ ‘κ·Όμ œμ–΄μžλŠ” λ²”μœ„κ°€ λ„“μ–΄μ§€λŠ” μͺ½μœΌλ‘œ μž¬μ„€μ • ν•  수 μžˆλ‹€.
    • λ©”μ†Œλ“œ 상속 μž¬μ •μ˜ - λΆ€λͺ¨μ˜ λ©”μ†Œλ“œλ₯Ό μƒμ†λ°›μœΌλ©° λ°˜ν™˜ν˜•, λ§€κ°œλ³€μˆ˜ λͺ©λ‘, λ©”μ†Œλ“œ 이름은 κ·ΈλŒ€λ‘œ 두고 λͺΈμ²΄μ˜ μ •μ˜λ₯Ό μƒˆλ‘œ ν•˜λŠ” 것

λ©”μ†Œλ“œμ˜ 이름과 λ§€κ°œλ³€μˆ˜λ₯Ό λ¬Άμ–΄ λ©”μ†Œλ“œμ˜ μ„œλͺ…(signature) 이라고 ν•œλ‹€. ν•œ 클래슀 내에 μ„œλͺ…이 λ™μΌν•œ λ‘κ°œ μ΄μƒμ˜ λ©”μ†Œλ“œκ°€ μ‘΄μž¬ν•  수 μ—†λ‹€.

7. 상속과 μƒμ„±μž

  • 상속 받은 클래슀λ₯Ό 컴파일 ν•  λ•Œ λΆ€λͺ¨ 클래슀의 κΈ°λ³Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•œλ‹€.
  • κΈ°λ³Έ μƒμ„±μžκ°€ μ •μ˜λ˜μ–΄ μžˆμ§€ μ•Šμ„ μ‹œ μ»΄νŒŒμΌλŸ¬κ°€ μƒμ„±ν•œλ‹€.
  • κ²°κ΅­ λͺ¨λ“  κ°μ²΄λŠ” Object 객체λ₯Ό 상속 λ°›μœΌλ―€λ‘œ Object 의 κΈ°λ³Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•œλ‹€.
 class ParentClass { // extends Object
    public ParentClass() {
        // super(); -> 컴파일 μ‹œμ μ— Object 의 κΈ°λ³Έ μƒμ„±μžλ₯Ό 호좜 ν•œλ‹€.;
        System.out.println("[PARENT] μΈμžμ—†λŠ” λΆ€λͺ¨ 클래슀 ν˜ΈμΆœμž…λ‹ˆλ‹€.");
    }
    public ParentClass(int a) {
        System.out.println("[PARENT, PARAM] μΈμžμžˆλŠ” λΆ€λͺ¨ 클래슀 ν˜ΈμΆœμž…λ‹ˆλ‹€.");
    }
}

class ChildClass extends ParentClass {
    public ChildClass() {
        // super(); -> 컴파일 μ‹œμ μ— λΆ€λͺ¨ 클래슀의 κΈ°λ³Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•œλ‹€.
        System.out.println("[CHILD] μΈμžμ—†λŠ” μžμ‹ 클래슀 ν˜ΈμΆœμž…λ‹ˆλ‹€.");
    }
    public ChildClass(int a) {
        System.out.println("[CHILD, PARAM] μΈμžμžˆλŠ” μžμ‹ 클래슀 ν˜ΈμΆœμž…λ‹ˆλ‹€.");
    }
}

class InheritanceConstructor {
    public static void main(String[] args) {
        ChildClass childClassA = new ChildClass();
        ChildClass childClassB = new ChildClass(10);
    }
}

μ‹€ν–‰κ²°κ³Ό