ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Live Study - Java 상속 (Inheritance)
    Hello, World πŸ’»/Java β˜•οΈ 2020. 12. 23. 22:15

    μ •λ¦¬ν•œ λ‚΄μš©
    - Java 의 상속과 νŠΉμ§•
    - Super
    - μ˜€λ²„λΌμ΄λ”©
    - μ œμ–΄μž
    - λ‹€ν˜•μ„±
    - Dynamic Method Dispatch
    - 좔상 클래슀
    - Object 클래슀


    Java 의 상속(Inheritance)κ³Ό νŠΉμ§•

    클래슀λ₯Ό 상속 λ°›λŠ” λ‹€λŠ” 것은 기쑴의 클래슀λ₯Ό μž¬μ‚¬μš©ν•΄μ„œ μƒˆλ‘œμš΄ 클래슀λ₯Ό μž‘μ„±ν•˜λŠ” 것이닀. 
    μƒμ†μ˜ λͺ©μ λ„ κ²°κ΅­ μ€‘λ³΅μ˜ 제거인 것 κ°™λ‹€. ν”„λ‘œκ·Έλž˜λ°μ˜ λ§Žμ€ κ°œλ…μ€ μ½”λ“œμ˜ μž¬μ‚¬μš©μ„±μ„ 높이고, 쀑볡을 μ œκ±°ν•˜κΈ° μœ„ν•΄ λ§Œλ“€μ–΄μ§€κ³  λ°œμ „λ˜λŠ” 것듀이 정말 λ§Žμ€κ²ƒ κ°™κ³ , μƒμ†μ΄λΌλŠ” κ°œλ…λ„ κ·Έ κ³Όμ • μ†μ˜ 산물이라고 μƒκ°ν•œλ‹€.

    Java μ—μ„œ 클래슀λ₯Ό 상속 λ°›κΈ° μœ„ν•΄μ„œλŠ” extends λΌλŠ” ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€.

    class Product {
        String productCode;
        String productType;
    }
    
    public class Book extends Product {
        String author;
        String title;
        // ..
    }


    상속 λ°›λŠ” Book 같은 클래슀λ₯Ό Child(μžμ‹), Sub(ν•˜μœ„), Derived(νŒŒμƒ) 클래슀 라고 많이 ν‘œν˜„ν•˜κ³ , 상속을 ν•΄μ£ΌλŠ” Product 같은 클래슀λ₯Ό Parent(λΆ€λͺ¨), Super(μƒμœ„), Base(기반) 클래슀라고 자주 ν‘œν˜„ν•œλ‹€.

    μžμ‹ ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ 클래슀의 멀버 λ³€μˆ˜, λ©”μ†Œλ“œλ“€μ„ λͺ¨λ‘ 상속 λ°›κ²Œ λœλ‹€. 이 λ•Œ μ ‘κ·Ό μ œμ–΄μžλ‘œ 상속 받지 λͺ»ν•˜λŠ” μžμ›λ“€λ„ μžˆμ§€λ§Œ, λΆ€λͺ¨ 클래슀의 μžμ›μ„ μžμ‹ ν΄λž˜μŠ€μ—μ„œ μ‚¬μš©ν•  수 μžˆλ‹€. 그리고 상속 받지 λͺ»ν•˜λŠ” 것듀도 μžˆλŠ”λ°, μƒμ„±μžμ™€ μ΄ˆκΈ°ν™” 블둝은 μƒμ†λ˜μ§€ μ•ŠλŠ”λ‹€.

    μžμ‹ ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ 클래슀의 λͺ¨λ“  멀버λ₯Ό 상속 λ°›κΈ° λ•Œλ¬Έμ— 이λ₯Ό ν™•μž₯, Extend 라고 ν‘œν˜„ν•  수 있고, κ·Έλž˜μ„œ 상속 받을 λ•Œμ˜ ν‚€μ›Œλ“œκ°€ extends 인 이유라고 ν•œλ‹€.

    class Product {
        String productCode;
        String productType;
    }
    
    class Book extends Product {
        String author;
        String title;
        
        void display() {
            System.out.printf("%s, %s, %s, %s%n", 
                    this.productCode, this.productType, this.author, this.title);
        }
    }

     

    μƒμ†μ΄λΌλŠ”κ±΄ 어쨋든 클래슀 κ°„μ˜ 관계λ₯Ό λ§Œλ“€μ–΄μ„œ 쀑볡을 쀄이고 μž¬μ‚¬μš©μ„±μ„ 높인 방법이닀.
    상속이 μ•„λ‹ˆλΌ 클래슀 κ°„μ˜ ν¬ν•¨μ΄λΌλŠ” 관계λ₯Ό λ§Ίμ–΄ 쒋은 ꡬ쑰의 μ½”λ“œλ₯Ό μž‘μ„±ν•  μˆ˜λ„ μžˆλ‹€.

    class Car {
        Wheel[] wheels = new Wheel[4];
        // ..
    }
    
    class Wheel {
        String brand;
        String type;
    }

    μœ„μ˜ ν΄λž˜μŠ€λŠ” 'μžλ™μ°¨κ°€ 바퀴λ₯Ό 가지고 μžˆλ‹€' 라고 ν‘œν˜„ν•  수 μžˆλ‹€. μžλ™μ°¨λΌλŠ” μ»€λŒ€ν•œ 클래슀λ₯Ό μž‘μ„±ν•˜λŠ” 것보닀 ꡬ성 μš”μ†Œ λ³„λ‘œ μ—¬λŸ¬κ°œμ˜ 클래슀λ₯Ό λ§Œλ“€κ³  포함 κ΄€κ³„λ‘œ μž¬μ‚¬μš©ν•˜λ©΄, 보닀 쒋은 ꡬ쑰의 ν”„λ‘œκ·Έλž¨μ„ λ§Œλ“€ 수 μžˆλŠ” 것 κ°™λ‹€.

    클래슀의 관계λ₯Ό κ²°μ •ν•  λ•Œ 'AλŠ” B이닀(is - a)', 'AλŠ” Bλ₯Ό 가지고 μžˆλ‹€(has - a)' 에 λŒ€μž…ν•΄μ„œ 생각해보면 κ°€λ‹₯을 μž‘μ„ 수 μžˆλŠ” 것 κ°™λ‹€.

    책은 μƒν’ˆμ΄λ‹€. (is - a)
    μ°¨λŠ” 바퀴듀을 가지고 μžˆλ‹€. (has - a)

     

    λ‹€μ‹œ μƒμ†μœΌλ‘œ λŒμ•„μ™€μ„œ, Java λŠ” ν•˜λ‚˜μ˜ 클래슀만 상속 받을 수 μžˆλ‹€. 단일 상속 이라고 ν‘œν˜„ν•œλ‹€. 닀쀑 상속을 ν—ˆμš©ν•˜λŠ” μ–Έμ–΄(C++, Python λ“±)도 μžˆλ‹€.

    닀쀑 상속을 ν—ˆμš©ν•˜λŠ” 경우 μ—¬λŸ¬ ν΄λž˜μŠ€μ—μ„œ 상속을 받을 수 있게 λ˜λ―€λ‘œ 볡합적인 κΈ°λŠ₯을 가진 클래슀λ₯Ό μ‰½κ²Œ μž‘μ„±ν•  수 있게 λ˜μ§€λ§Œ, 상속 λ°›λŠ” ν΄λž˜μŠ€λ“€ 쀑 같은 μ΄λ¦„μ˜ λ©”μ†Œλ“œκ°€ μžˆλŠ” 경우 κ΅¬λ³„ν•˜κΈ° μ–΄λ ΅λ‹€λŠ” 단점이 μžˆλ‹€. 

    κ·Έλž˜μ„œ νŒŒμ΄μ¬μ—μ„œλŠ” Method Resolution Order (MRO) λΌλŠ” κ°œλ…μ΄ μžˆμ–΄μ„œ μ•žμ˜ μƒν™©μ—μ„œ μ–΄λ–€ λ©”μ†Œλ“œκ°€ μ‚¬μš©λ˜λŠ”μ§€μ— λŒ€ν•œ κ·œμΉ™μ΄ μžˆλ‹€. 


    Java μ—μ„œλŠ” μœ„μ™€ 같은 이유둜 닀쀑 상속을 ν—ˆμš©ν•˜μ§€ μ•ŠλŠ”λ‹€. 클래슀 κ°„μ˜ 관계가 보닀 λͺ…ν™•ν•΄μ§€λŠ” μž₯점이 μžˆλ‹€.

     

    Super

    super λŠ” μžμ‹ ν΄λž˜μŠ€μ—μ„œ λΆ€λͺ¨ 클래슀의 μžμ›μ„ μ°Έμ‘°ν•˜λŠ”λ° μ‚¬μš©λ˜λŠ” λ³€μˆ˜λ‹€. 

    λΆ€λͺ¨ 클래슀의 μžμ›λ„ this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ μ°Έμ‘°ν•  수 있고, μžμ‹ 클래슀의 μžμ›κ³Ό λΆ€λͺ¨ 클래슀의 μžμ›μ„ κ΅¬λ³„ν•΄μ„œ μ‚¬μš©ν•΄μ•Ό ν•  λ•Œ super ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.

    class Product {
        String productCode;
        String type = "Product Type";
    
    }
    
    class Book extends Product {
        String author;
        String type = "Book Type";
    
        void displayType() {
            System.out.println(String.format("Super: %s, This: %s", super.type, this.type));
        }
    }
    
    public class SampleTest {
    
        public static void main(String[] args) {
            Book book = new Book();
            book.displayType();
        }
    
    }
    
    // 좜λ ₯κ²°κ³Ό
    // Super: Product Type, This: Book Type


    μ˜ˆμ œλŠ” λ³€μˆ˜μ— λŒ€ν•΄ super 둜 μ°Έμ‘°ν–ˆλŠ”λ°, λ©”μ†Œλ“œμ— λŒ€ν•΄μ„œλ„ super 둜 μ°Έμ‘°ν•  수 μžˆλ‹€.

    super()

    μƒμ„±μžμ—μ„œ λ‹€λ₯Έ μƒμ„±μžλ₯Ό 호좜 ν•  λ•Œ this() λ₯Ό μ‚¬μš©ν–ˆμ—ˆλ‹€. super() 도 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•  λ•Œ μ‚¬μš©ν•  수 μžˆλ‹€. λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜λŠ” 방법이닀.

    μžμ‹ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜λ©΄, λΆ€λͺ¨ + μžμ‹μ΄ 된 ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€κ°€ μƒμ„±λ˜λŠ” 것이기 λ•Œλ¬Έμ—, μžμ‹ 클래슀의 μƒμ„±μžκ°€ 호좜될 λ•Œ λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ„ ν•¨κ»˜ 호좜이 λ˜μ–΄μ•Ό ν•œλ‹€.

    μ΄λ•Œ μžμ‹ ν΄λž˜μŠ€μ—μ„œ λΆ€λͺ¨ 클래슀의 μžμ›μ„ μ‚¬μš©ν•  수 있기 λ•Œλ¬Έμ— μžμ‹ 클래슀 μƒμ„±μžμ˜ 첫 μ€„μ—μ„œλŠ” λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•œλ‹€. λ§Œμ•½ 첫 μ€„μ—μ„œ super() λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šμ•˜λ‹€λ©΄ μ»΄νŒŒμΌλŸ¬κ°€ μžλ™μœΌλ‘œ μΆ”κ°€ν•΄μ€€λ‹€.

    λ§Œμ•½ λΆ€λͺ¨ ν΄λž˜μŠ€μ— κΈ°λ³Έ μƒμ„±μžκ°€ μ—†λŠ” κ²½μš°μ— μ»΄νŒŒμΌλŸ¬κ°€ μžμ‹ μƒμ„±μžμ—μ„œ super(); λ₯Ό μΆ”κ°€ν•˜λ©΄ μ—λŸ¬κ°€ λ°œμƒν•  수 있기 λ•Œλ¬Έμ— μ£Όμ˜ν•΄μ•Ό ν•œλ‹€. μ•„λž˜μ™€ 같은 κ²½μš°μ΄λ‹€.

    class Product {
        String productCode;
        String productType;
    
        public Product(String productCode, String productType) {
            this.productCode = productCode;
            this.productType = productType;
        }
    }
    
    class Book extends Product {
        String author;
        String title;
    
        public Book(String productCode, String productType, 
                    String author, String title) {
            this.author = author;
            this.title = title;
        }
    }


    μœ„μ˜ μ½”λ“œλŠ” λΆ€λͺ¨ ν΄λž˜μŠ€μ—λŠ” κΈ°λ³Έ μƒμ„±μžκ°€ μ—†λŠ”λ°, μžμ‹ μƒμ„±μžμ—μ„œ λΆ€λͺ¨ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ§€ μ•Šμ•˜κΈ° λ•Œλ¬Έμ— μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

    class Book extends Product {
        String author;
        String title;
    
        public Book(String productCode, String productType, String author, String title) {
            super(productCode, productType); // μΆ”κ°€!
            this.author = author;
            this.title = title;
        }
    }


    λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ€˜μ•Ό 문제 없이 μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μžˆλ‹€.

     

    μ˜€λ²„λΌμ΄λ”©, Overriding

    λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ 상속받은 λ©”μ†Œλ“œλ₯Ό λ‹€μ‹œ μž‘μ„±ν•˜λŠ” 것을 μ˜€λ²„라이딩 μ΄λΌκ³  ν•œλ‹€. 

    class Product {
        String productCode;
        String productType;
    
        String getDisplayData() {
            return String.format("Product Code: %s, Product Type: %s", productCode, productType);
        }
    }
    
    class Book extends Product {
        String author;
        String title;
    
        @Override
        String getDisplayData() {
            return String.format("Product Type: %s, Book Title: %s, Book author: %s", 
                productType, title, author);
        }
    }


    Product 클래슀λ₯Ό 상속받아 getDisplayData λ©”μ†Œλ“œλ₯Ό μ˜€λ²„λΌμ΄λ”© ν–ˆλ‹€. 

    μ˜€λ²„λΌμ΄λ”©μ„ ν•œλ‹€λŠ” 것은 λ©”μ†Œλ“œμ˜ Body λΆ€λΆ„λ§Œ μž¬μž‘μ„± ν•˜λŠ” 것이기 λ•Œλ¬Έμ— μ„ μ–ΈλΆ€λŠ” μ™„μ „νžˆ 동일해야 ν•œλ‹€. λ©”μ†Œλ“œ λͺ…, λ§€κ°œλ³€μˆ˜, λ°˜ν™˜ νƒ€μž…μ΄ 동일해야 ν•œλ‹€. λŒ€λΆ€λΆ„μ˜ 경우 λΆ€λͺ¨ 클래슀의 선언뢀와 λ˜‘κ°™μ΄ μ‚¬μš©ν•˜μ§€λ§Œ μ ‘κ·Ό μ œμ–΄μžμ™€ μ˜ˆμ™ΈλŠ” 쑰건적으둜 λ³€κ²½ν•  수 μžˆλ‹€.

    λΆ€λͺ¨ 클래슀의 λ©”μ†Œλ“œλ³΄λ‹€ 넓은 λ²”μœ„μ˜ μ ‘κ·Ό μ œμ–΄μžλ‘œ λ³€κ²½ν•  수 μžˆλ‹€. μ ‘κ·Ό μ œμ–΄μžμ˜ λ²”μœ„λŠ” public -> protected -> default -> private 순으둜 μ’ν˜€μ§„λ‹€.  예λ₯Ό λ“€λ©΄ λΆ€λͺ¨ 클래슀의 λ©”μ†Œλ“œκ°€ protected μ˜€μœΌλ©΄ μžμ‹ ν΄λž˜μŠ€λŠ” λ˜‘κ°™μ΄ protected μ΄κ±°λ‚˜, public 이어야 ν•œλ‹€λŠ” 것이닀. private 둜 λ³€κ²½ν•˜λ©΄ μ»΄νŒŒμΌλŸ¬κ°€ μ—λŸ¬λ₯Ό μ•Œλ €μ€€λ‹€.

    그리고 λΆ€λͺ¨ 클래슀의 λ©”μ†Œλ“œλ³΄λ‹€ λ§Žμ€ 수의 μ˜ˆμ™Έλ₯Ό μ„ μ–Έν•  수 μ—†λ‹€. 예λ₯Ό λ“€μ–΄ λΆ€λͺ¨ λ©”μ†Œλ“œκ°€ IOException, IllegalArgumentException μ˜ˆμ™Έλ₯Ό λ˜μ§€λŠ” 경우 μžμ‹μ—μ„œλŠ” λ‘˜ 쀑 ν•˜λ‚˜μ˜ μ˜ˆμ™Έλ§Œ λ˜μ Έλ„ λœλ‹€. ν•˜μ§€λ§Œ λ‹€λ₯Έ μ˜ˆμ™Έλ₯Ό λ˜μ§€κ±°λ‚˜ ν•˜λ©΄ μ—­μ‹œ μ—λŸ¬κ°€ 생긴닀. 

     

    μ œμ–΄μž, Modifier

    μ œμ–΄μžλŠ” 클래슀, λ³€μˆ˜, λ©”μ†Œλ“œμ˜ 선언뢀에 μ‚¬μš©λ˜μ–΄ 뢀가적인 의미λ₯Ό λΆ€μ—¬ν•œλ‹€. 크게 μ ‘κ·Ό μ œμ–΄μžμ™€ μ ‘κ·Ό μ œμ–΄μžλ₯Ό μ œμ™Έν•œ μ œμ–΄μžλ“€μ΄ μžˆλ‹€.

    μ ‘κ·Ό μ œμ–΄μž: public, protected, default, private
    κ·Έ μ™Έ μ œμ–΄μž: static, final, abstract, native, transient, synchronized, volatile, strictfp

    μ ‘κ·Ό μ œμ–΄μžλŠ” ν•œ λ²ˆμ— ν•˜λ‚˜λ§Œ μ‚¬μš©ν•  수 있고, κ·Έ μ™Έμ˜ μ œμ–΄μžλ“€μ€ μ—¬λŸ¬κ°€μ§€λ₯Ό μ‘°ν•©ν•΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

    public static final int NUMBER = 10;


    μ΄λ ‡κ²Œ μ‚¬μš©ν•  μˆ˜λŠ” μžˆμ§€λ§Œ, public private static μ΄λ ‡κ²Œ public κ³Ό private 을 ν•¨κ»˜ μ‚¬μš©ν•  μˆ˜λŠ” μ—†λ‹€.
    μ œμ–΄μžλ“€μ„ μ‘°ν•©ν•΄μ„œ μ‚¬μš©ν•  λ•Œ, μ œμ–΄μžμ˜ μˆœμ„œλŠ” 상관이 μ—†λ‹€. 보톡 μ ‘κ·Ό μ œμ–΄μžλ₯Ό κ°€μž₯ μ™Όμͺ½μ— 두고, κ·Έ μ™Έμ˜ μ œμ–΄μžλ“€μ„ μ μ ˆν•˜κ²Œ μž‘μ„±ν•˜λ©΄ λœλ‹€.

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

    μ ‘κ·Ό μ œμ–΄μžλŠ” 클래슀, λ³€μˆ˜, λ©”μ†Œλ“œμ— μ μš©ν•΄μ„œ μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•˜μ§€ λͺ»ν•˜λ„둝 μ œν•œν•˜λŠ” 역할을 ν•œλ‹€. 
    μ™ΈλΆ€λ‘œλΆ€ν„° 데이터λ₯Ό λ³΄ν˜Έν•˜κΈ° μœ„ν•΄μ„œ, λΆˆν•„μš”ν•œ 뢀뢄을 감좔기 μœ„ν•΄μ„œ μ‚¬μš©ν•˜λŠ” 것이닀. 객체지ν–₯κ°œλ…μ˜ μΊ‘μŠν™” (Encapsulation)에 ν•΄λ‹Ήν•œλ‹€.

    ν΄λž˜μŠ€μ—λŠ” public, default μ œμ–΄μžκ°€ ν—ˆμš©λ˜κ³ ,
    λ³€μˆ˜μ™€ λ©”μ†Œλ“œμ—λŠ” public, protected, default, private μ œμ–΄μžκ°€ ν—ˆμš©λœλ‹€.

    μ ‘κ·Ό μ œμ–΄μžλ₯Ό λ”°λ‘œ μ •μ˜ν•˜μ§€ μ•ŠλŠ” 경우, default μ œμ–΄μžκ°€ 기본으둜 μ μš©λœλ‹€.

    public μ ‘κ·Ό μ œν•œμ΄ μ—†λ‹€.
    protected 같은 νŒ¨ν‚€μ§€ λ‚΄μ—μ„œ, λ‹€λ₯Έ νŒ¨ν‚€μ§€μΈ 경우 μžμ‹ ν΄λž˜μŠ€μ—μ„œ 접근이 κ°€λŠ₯ν•˜λ‹€.
    default 같은 νŒ¨ν‚€μ§€ λ‚΄μ—μ„œ 접근이 κ°€λŠ₯ν•˜λ‹€.
    private 같은 클래슀 λ‚΄μ—μ„œλ§Œ 접근이 κ°€λŠ₯ν•˜λ‹€.


    final

    final μ œμ–΄μžλŠ” 클래슀, λ©”μ†Œλ“œ, λ³€μˆ˜ λͺ¨λ‘μ— 뢙일 수 μžˆλ‹€. 

    ν΄λž˜μŠ€μ— 뢙이면 λ³€κ²½, ν™•μž₯ν•  수 μ—†λŠ” ν΄λž˜μŠ€κ°€ 되고, λ©”μ†Œλ“œμ— 뢙이면 μ˜€λ²„λΌμ΄λ”©μ„ 톡해 μž¬μ •μ˜ 될 수 μ—†κ³ , λ³€μˆ˜μ— 뢙이면 값을 λ³€κ²½ν•  수 μ—†λŠ” μƒμˆ˜κ°€ λœλ‹€.

    final class FinalClass {
        final int MAX_VALUE = 1_000;
        
        final void getMaxValue() {
            return MAX_VALUE;
        }
    }


    final 이 뢙은 λ³€μˆ˜λŠ” μƒμˆ˜κ°€ 되기 λ•Œλ¬Έμ— 일반적으둜 μ„ μ–Έκ³Ό λ™μ‹œμ— μ΄ˆκΈ°ν™”λ₯Ό ν•œλ‹€. ν•˜μ§€λ§Œ μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ— 뢙은 final λ³€μˆ˜λŠ” μƒμ„±μžμ—μ„œ μ΄ˆκΈ°ν™”ν•˜λ„λ‘ ν•  수 μžˆλ‹€.

    λ§€κ°œλ³€μˆ˜λ₯Ό λ°›λŠ” μƒμ„±μžλ₯Ό μž‘μ„±ν•΄μ„œ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ final 이 뢙은 λ³€μˆ˜λ₯Ό μ΄ˆκΈ°ν™” ν•˜λŠ”λ° ν•„μš”ν•œ 값을 μ œκ³΅λ°›μ•„ μ΄ˆκΈ°ν™” ν•˜λŠ” 것이닀. μ΄λ•Œ κΈ°λ³Έ μƒμ„±μžκ°€ 있으면 μ—λŸ¬κ°€ λ°œμƒν•œλ‹€.

    class FinalClass {
        final int constValue;
        
        public FinalClass(int constValue) {
            this.constValue = constValue;
        }
    }


    상속을 λ§‰λŠ” 두 가지 방법

    두 가지 방법 쀑 ν•˜λ‚˜λŠ” λ°”λ‘œ μœ„μ—μ„œ 봀던 final 을 class 에 λΆ™μ΄λŠ” 것이닀. 또 λ‹€λ₯Έ 방법은 클래슀의 μƒμ„±μžμ— private 을 λΆ™μ΄λŠ” 것이닀.

    μžμ‹ ν΄λž˜μŠ€μ—μ„œ λΆ€λͺ¨ 클래슀의 μƒμ„±μžλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•˜λŠ”λ° λΆ€λͺ¨ 클래슀 μƒμ„±μžμ˜ μ ‘κ·Ό μ œμ–΄μžκ°€ private 이기 λ•Œλ¬Έμ— μžμ‹ ν΄λž˜μŠ€μ—μ„œ 접근이 λΆˆκ°€λŠ₯ν•œ 것이닀.

    class FinalClass {
    
        private FinalClass() {
        }
        
    }


    ν•˜μ§€λ§Œ 이런 경우 λͺ…μ‹œμ μœΌλ‘œ class μ•žμ— final 을 μΆ”κ°€ν•˜λŠ” 것이 더 μ’‹κ² λ‹€.

    μƒμ„±μžκ°€ private 인 경우 static public λ©”μ†Œλ“œλ₯Ό μž‘μ„±ν•΄μ„œ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•΄μ£ΌλŠ” μž‘μ—…μ„ ν•œλ‹€. μΈμŠ€ν„΄μŠ€μ˜ 개수λ₯Ό μ œν•œν•˜κ±°λ‚˜ ν•  λ•Œ 이런 방법을 μ‚¬μš©ν•œλ‹€.

     

    λ‹€ν˜•μ„±, Polymorphism

    객체지ν–₯κ°œλ…μ—μ„œ λ‹€ν˜•μ„±μ€ 'μ—¬λŸ¬ 가지 ν˜•νƒœλ₯Ό κ°€μ§ˆ 수 μžˆλŠ” λŠ₯λ ₯'을 μ˜λ―Έν•œλ‹€. Java μ—μ„œλŠ” λ‹€ν˜•μ„±μ„ λΆ€λͺ¨ 클래슀의 μ°Έμ‘° λ³€μˆ˜λ‘œ μžμ‹ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•  수 μžˆλ„λ‘ κ΅¬ν˜„ν–ˆλ‹€.

    class Product {
        private String productCode;
        private String productType;
    }
    
    class Book extends Product {
        private String author;
        private String title;
    }
    
    
    public class SampleTest {
    
        public static void main(String[] args) {
            Product bookProduct = new Book();
        }
    
    }


    bookProduct λŠ” Product λ₯Ό μ°Έμ‘°ν•  수 μžˆλŠ” μ°Έμ‘°λ³€μˆ˜μ΄μ§€λ§Œ, Product 클래슀λ₯Ό 상속 받은 Book 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€.
    μΈμŠ€ν„΄μŠ€λ₯Ό λΆ€λͺ¨ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ‘œ μ°Έμ‘°ν•˜λŠ” 것과, μžμ‹ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ‘œ μ°Έμ‘°ν•˜λŠ” 것은 μ‚¬μš©ν•  수 μžˆλŠ” μžμ›μ˜ λ²”μœ„μ—μ„œ 차이가 생긴닀.

    class Product {
        private String productCode;
        private String productType;
        
        void showCode() {}
        void showType() {}
    }
    
    class Book extends Product {
        private String author;
        private String title;
        
        void showAuthor() {}
        void showTitle() {}
    }
    
    
    public class SampleTest {
    
        public static void main(String[] args) {
            Product bookProduct = new Book();
            bookProduct.showCode();
            bookProduct.showType();
            // bookProduct.showAuthor(); μ—λŸ¬!
        }
    
    }



    Product νƒ€μž…μ˜ μ°Έμ‘°λ³€μˆ˜λ‘œλŠ” λΆ€λͺ¨ ν΄λž˜μŠ€μ—μ„œ μ •μ˜λ˜μ–΄ μžˆλŠ” μžμ›λ“€μ— ν•œν•΄μ„œ μ ‘κ·Όν•  수 μžˆλ‹€.

    μžμ‹ 클래슀의 λ ˆνΌλŸ°μŠ€λ‘œλŠ” λ‹Ήμ—°νžˆ Book μΈμŠ€ν„΄μŠ€μ˜ λͺ¨λ“  μžμ›μ— 접근이 κ°€λŠ₯ν•˜λ‹€.

     

     

     

    λ°˜λŒ€λ‘œ μžμ‹ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ‘œ λΆ€λͺ¨ 클래슀의 μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°ν•  μˆ˜λŠ” μ—†λ‹€.

    Book book = new Product(); // μ—λŸ¬!


    μ°Έμ‘° λ³€μˆ˜μ˜ ν˜• λ³€ν™˜

    μœ„μ—μ„œ Product 의 μ°Έμ‘° λ³€μˆ˜λ‘œλŠ” Book μΈμŠ€ν„΄μŠ€μ˜ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜μ§€ λͺ»ν–ˆλŠ”데, μ°Έμ‘° λ³€μˆ˜λ₯Ό ν˜• λ³€ν™˜ ν•΄μ„œ ν•΄κ²° ν•  수 μžˆλ‹€.

    public static void main(String[] args) {
        Product bookProduct = new Book();
        bookProduct.showType();
    
        Book book = (Book) bookProduct;
        book.showAuthor();
    }


    μ„œλ‘œ 상속 관계에 μžˆλŠ” 클래슀 μ‚¬μ΄μ—μ„œλ§Œ κ°€λŠ₯ν•˜λ‹€. μžμ‹ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ₯Ό λΆ€λͺ¨ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ‘œ, λΆ€λͺ¨ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ₯Ό μžμ‹ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ‘œ ν˜•λ³€ν™˜μ΄ κ°€λŠ₯ν•˜λ‹€.

    μžμ† νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ₯Ό λΆ€λͺ¨ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ‘œ ν˜•λ³€ν™˜ ν•˜λŠ” 것을 Up-Casting
    λΆ€λͺ¨ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ₯Ό μžμ‹ νƒ€μž…μ˜ μ°Έμ‘° λ³€μˆ˜λ‘œ ν˜•λ³€ν™˜ ν•˜λŠ” 것을 Down-Casting 라고 ν•œλ‹€.

    μ—¬κΈ°μ„œ Up-Casting ν•  λ•ŒλŠ” ν˜•λ³€ν™˜ μ—°μ‚°μžλ₯Ό μƒλž΅ν•  수 μžˆλ‹€.

        public static void main(String[] args) {
            Product bookProduct = new Book();
            bookProduct.showType();
    
            Book book = (Book) bookProduct; // (Book) μƒλž΅ λΆˆκ°€
            book.showAuthor();
    
            Book book2 = new Book();
            Product bookProduct2 = book2; // (Product) μƒλž΅ κ°€λŠ₯
        }


    ν˜•λ³€ν™˜ μ‹œ μ£Όμ˜ν•  것

    public static void main(String[] args) {
        Product product = new Product();
        Book book = (Book) product;
    }


    μœ„μ™€ 같이 ν˜•λ³€ν™˜ ν•˜λ©΄ λŸ°νƒ€μž„ μ‹œ ClassCastException μ˜ˆμ™Έκ°€ λ°œμƒν•œλ‹€.
    λ¬Έμ œλŠ” product κ°€ μ°Έμ‘°ν•˜λŠ” μΈμŠ€ν„΄μŠ€κ°€ Product νƒ€μž…μ΄κΈ° λ•Œλ¬Έμ— Book νƒ€μž…μ˜ μ°Έμ‘°λ³€μˆ˜λ‘œ ν˜•λ³€ν™˜ ν•  수 μ—†λ‹€.

    μ°Έμ‘° λ³€μˆ˜κ°€ μ‚¬μš©ν•  수 μžˆλŠ” μžμ›μ˜ μˆ˜λŠ” μΈμŠ€ν„΄μŠ€μ˜ μžμ› μˆ˜λ³΄λ‹€ κ°™κ±°λ‚˜ 적어야 ν•˜λŠ”λ°, Book μ°Έμ‘°λ³€μˆ˜λ‘œλŠ” Product μ°Έμ‘° λ³€μˆ˜κ°€ μ°Έμ‘°ν•  수 μžˆλŠ” μžμ›λ³΄λ‹€ 더 λ§Žμ„ 수 있기 λ•Œλ¬Έμ— λ¬Έμ œκ°€ λ°œμƒν•˜λŠ” 것이닀.

    κ·Έλž˜μ„œ 항상 μ°Έμ‘°λ³€μˆ˜λ₯Ό ν˜•λ³€ν™˜ ν•  λ•Œμ—λŠ” instanceof μ—°μ‚°μžλ₯Ό μ‚¬μš©ν•΄μ„œ μΈμŠ€ν„΄μŠ€μ˜ νƒ€μž…μ΄ 무엇인지 ν™•μΈν•˜λŠ” μž‘μ—…μ΄ μ€‘μš”ν•˜λ‹€.

    public static void main(String[] args) {
        Product product = new Product();
        if (product instanceof Book) {
            Book book = (Book) product;
        }
    }


    Dynamic Method Dispatch

    Dynamic Method Dispatch λŠ” μ˜€λ²„λΌμ΄λ”© 된 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ μ–΄λ–€ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν• μ§€μ— λŒ€ν•œ 결정을 컴파일 μ‹œμ μ΄ μ•„λ‹ˆλΌ λŸ°νƒ€μž„ μ‹œμ μ— κ²°μ •ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜μ„ λœ»ν•œλ‹€.

    λ§λΆ™μ—¬μ„œ μ„€λͺ…ν•˜λ©΄, λΆ€λͺ¨ 클래슀의 μ°Έμ‘° λ³€μˆ˜λ‘œ μ˜€λ²„λΌμ΄λ”© 된 λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λ €κ³  ν•˜λŠ” κ²½μš°μ— μ°Έμ‘°λ˜λŠ” μΈμŠ€ν„΄μŠ€μ˜ νƒ€μž…μ„ κΈ°μ€€μœΌλ‘œ μ–΄λ–€ λ©”μ†Œλ“œλ₯Ό 싀행할지λ₯Ό κ²°μ •ν•˜λŠ” 것이닀. μΈμŠ€ν„΄μŠ€μ˜ νƒ€μž…μ„ 보고 κ²°μ •ν•˜κΈ° λ•Œλ¬Έμ— λŸ°νƒ€μž„ μ‹œμ μ— κ²°μ •ν•œλ‹€λŠ” 것이닀.

    class Parent {
        void show() {
            System.out.println("Parent - show method is called.");
        }
    }
    
    class ChildA extends Parent {
        void show() {
            System.out.println("Child A - show method is called.");
        }
    }
    
    class ChildB extends Parent {
        void show() {
            System.out.println("Child B - show method is called.");
        }
    }
    
    
    public class SampleTest {
    
        public static void main(String[] args) {
            Parent parent = new Parent();
            ChildA childA = new ChildA();
            ChildB childB = new ChildB();
    
            Parent ref = null;
    
            ref = parent;
            ref.show(); // Parent - show method is called.
    
            ref = childA;
            ref.show(); // Child A - show method is called.
    
            ref = childB;
            ref.show(); // Child B - show method is called.
        }
    
    }


    show() λ©”μ†Œλ“œλŠ” 호좜 μ‹œμ— μ°Έμ‘°λ˜λŠ” μΈμŠ€ν„΄μŠ€μ˜ νƒ€μž…μ— λ”°λΌμ„œ λΆ€λͺ¨μ˜ show() ν˜Ήμ€ μžμ‹μ˜ show() 쀑 μ–΄λ–€ λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν• μ§€ κ²°μ •ν•˜λŠ” 것이닀.

    Dynamic Method Dispatch λŠ” 멀버 λ³€μˆ˜μ— λŒ€ν•΄μ„œλŠ” μ μš©λ˜μ§€ μ•ŠλŠ”λ‹€. μ–΄λ–€ μΈμŠ€ν„΄μŠ€μΈμ§€κ°€ μ•„λ‹ˆλΌ μ–΄λ–€ μ°Έμ‘° λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜κ³  μžˆλŠ”μ§€λ₯Ό 보고 κ²°μ •λœλ‹€.

    class Parent {
        int num = 100;
    }
    
    class ChildA extends Parent {
        int num = 200;
    }
    
    public class SampleTest {
    
        public static void main(String[] args) {
            Parent p = new ChildA();
            ChildA c = new ChildA();
    
            System.out.println("Parent Ref: " + p.num); // Parent Ref: 100
            System.out.println("Child Ref: " + c.num); // Child Ref: 200
        }
    
    }


    좔상 클래슀

    좔상 ν΄λž˜μŠ€λŠ” 좔상 λ©”μ†Œλ“œλ₯Ό 가진 클래슀λ₯Ό λœ»ν•œλ‹€. 좔상 λ©”μ†Œλ“œλŠ” μ œμ–΄μžμ—μ„œ 봀던 abstract ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ λ§Œλ“€ 수 μžˆλ‹€.

    abstract class AbstractClass {
        abstract void doSomething();
    }


    좔상 λ©”μ†Œλ“œκ°€ μžˆλŠ” ν΄λž˜μŠ€μ— abstract μ œμ–΄μžκ°€ μ—†μœΌλ©΄ μ—λŸ¬κ°€ λ°œμƒν•œλ‹€. 

    좔상 λ©”μ†Œλ“œλŠ” 아직 μ™„μ„±λ˜μ§€ μ•Šμ€ λ©”μ†Œλ“œλ₯Ό λœ»ν•˜κ³ , 좔상 ν΄λž˜μŠ€μ—μ„œ 좔상 λ©”μ†Œλ“œλŠ” μ„ μ–ΈλΆ€λ§Œ μ‘΄μž¬ν•œλ‹€. μœ„μ—μ„œλ„ doSomething(); μ΄λ ‡κ²Œ λλ‚œκ±Έ λ³Ό 수 μžˆλ‹€.

    좔상 클래슀λ₯Ό μƒμ†λ°›λŠ” μžμ‹ ν΄λž˜μŠ€μ—μ„œ ν•΄λ‹Ή 좔상 λ©”μ†Œλ“œμ˜ μ •μ˜λ₯Ό κ°•μ œν•œλ‹€. 이 같은 이유둜 좔상 클래슀λ₯Ό μΈμŠ€ν„΄μŠ€λ‘œ 생성할 수 μ—†λ‹€. μ •μ˜λ˜μ§€ μ•ŠλŠ” λ©”μ†Œλ“œκ°€ μžˆλŠ” μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€ μˆ˜λŠ” μ—†κΈ° λ•Œλ¬Έμ΄λ‹€.

    abstract class Machine {
        abstract void run();
        abstract void stop();
    }
    
    class Tv extends Machine {
        @Override
        void run() {
            System.out.println("Tv Run");
        }
    
        @Override
        void stop() {
            System.out.println("Tv Stop");
        }
    } 
    
    public class SampleTest {
    
        public static void main(String[] args) {
            // Machine m = new Machine(); μ—λŸ¬!
            Tv tv = new Tv();
            Machine tv2 = new Tv(); // 좔상 ν΄λž˜μŠ€λ„ λ‹€ν˜•μ„± 적용이 κ°€λŠ₯ν•˜λ‹€.
        }
    
    }


    좔상 ν΄λž˜μŠ€λŠ” 좔상 λ©”μ†Œλ“œκ°€ μžˆλ‹€λŠ” 것 λ§κ³ λŠ” 일반 ν΄λž˜μŠ€μ™€ λ‹€λ₯Ό 것은 μ—†λ‹€. λ˜‘κ°™μ΄ λ³€μˆ˜, λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

     

    Object 클래슀

    Object ν΄λž˜μŠ€λŠ” λͺ¨λ“  클래슀의 졜고 쑰상이 λ˜λŠ” ν΄λž˜μŠ€μ΄λ‹€. λͺ¨λ“  ν΄λž˜μŠ€λŠ” 사싀 Object 클래슀λ₯Ό 상속받고 μžˆλŠ” 것이닀. λ”°λ‘œ extends ν•΄μ„œ 상속 λ°›λŠ” ν΄λž˜μŠ€κ°€ μ—†μ—ˆλ‹€λ©΄ μžλ™μœΌλ‘œ Object 클래슀λ₯Ό 상속 λ°›κ²Œλœλ‹€.

    Object ν΄λž˜μŠ€λŠ” java.lang νŒ¨ν‚€μ§€μ— μžˆλŠ”λ° μžλ°” ν”„λ‘œκ·Έλž˜λ°μ—μ„œ κ°€μž₯ 기본이 λ˜λŠ” ν΄λž˜μŠ€λ“€μ„ ν¬ν•¨ν•˜κ³  μžˆλ‹€. java.lang ν•˜μœ„μ˜ ν΄λž˜μŠ€λ“€μ€ λ”°λ‘œ import ν•˜μ§€ μ•Šμ•„λ„ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€. 


    Object ν΄λž˜μŠ€λŠ” λͺ¨λ“  클래슀의 쑰상이 되기 λ•Œλ¬Έμ— Object 클래슀의 멀버듀을 λͺ¨λ“  ν΄λž˜μŠ€μ—μ„œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

    Object ν΄λž˜μŠ€λŠ” 멀버 λ³€μˆ˜λŠ” μ—†κ³ , 11 개의 λ©”μ†Œλ“œλ§Œ 가지고 μžˆλ‹€.

    clone() 객체 μžμ‹ μ˜ 볡사본 λ°˜ν™˜
    equals() 객체 μžμ‹ κ³Ό 같은 객체인지 boolean νƒ€μž…μœΌλ‘œ λ°˜ν™˜
    finalize() 객체가 μ†Œλ©Έλ  λ•Œ GC 에 μ˜ν•΄ μžλ™μ μœΌλ‘œ 호좜, μ†Œλ©Έμ‹œ μˆ˜ν–‰ν•΄μ•Όν•  μž‘μ—…μ΄ 있으면 μž¬μ •μ˜ ν•˜λ©΄ λœλ‹€. (거의 μ‚¬μš©ν•˜μ§€ μ•ŠμŒ)
    getClass() 객체의 클래슀 정보λ₯Ό λ‹΄κ³  μžˆλŠ” Class μΈμŠ€ν„΄μŠ€ λ°˜ν™˜
    hashCode() 객체의 hash code λ°˜ν™˜
    toString() 객체의 정보λ₯Ό λ¬Έμžμ—΄λ‘œ λ°˜ν™˜
    notify() 객체λ₯Ό μ‚¬μš©ν•˜λ €λŠ” Thread λ₯Ό ν•˜λ‚˜λ§Œ κΉ¨μš΄λ‹€.
    notifyAll() 객체λ₯Ό μ‚¬μš©ν•˜λ €λŠ” λͺ¨λ“  Thread λ₯Ό κΉ¨μš΄λ‹€.
    wait() λ‹€λ₯Έ Thread κ°€ notify(), notifyAll() λ₯Ό ν˜ΈμΆœν•  λ•ŒκΉŒμ§€ ν˜„μž¬ Thread λ₯Ό κΈ°λ‹€λ¦¬κ²Œ ν•œλ‹€.
    λ¬΄ν•œν•˜κ²Œ ν˜Ήμ€ μ§€μ •λœ μ‹œκ°„λ™μ•ˆ κΈ°λ‹€λ¦¬κ²Œ ν•  수 μžˆλ‹€. (timeout 은 1/1000 초, nanos λŠ” 1/10^9 초)
    wait(long timeout)()
    wait(long timeout, int nanos)


    equals(Object obj)

    λ§€κ°œλ³€μˆ˜λ‘œ μ°Έμ‘° λ³€μˆ˜λ₯Ό λ°›μ•„μ„œ 같은 μ°Έμ‘° λ³€μˆ˜μΈμ§€ κ²°κ³Όλ₯Ό boolean νƒ€μž…μœΌλ‘œ μ•Œλ €μ€€λ‹€.
    μ£Όμ†Œ 값이 μ•„λ‹ˆλΌ μ‹€μ œ μΈμŠ€ν„΄μŠ€μ˜ λ‚΄μš©μ„ λΉ„κ΅ν•˜κ³  싢은 경우 equals λ₯Ό μž¬μ •μ˜ν•œλ‹€. String 클래슀의 equals() λ©”μ†Œλ“œλŠ” μ‹€μ œ λ¬Έμžμ—΄ 값을 λΉ„κ΅ν•˜λ„λ‘ λ˜μ–΄μžˆλ‹€.

    hashCode()
    hashCode() λ©”μ†Œλ“œλŠ” 객체의 μœ μΌν•œ ν•΄μ‹œ μ½”λ“œ 값을 λ§Œλ“€μ–΄ λ°˜ν™˜ν•œλ‹€. Object 클래슀의 hashCode() λ©”μ†Œλ“œλŠ” 객체의 μ£Όμ†Œ 값을 μ΄μš©ν•œλ‹€. 
    같은 ν•΄μ‹œμ½”λ“œκ°€ μ‘΄μž¬ν•  수 μžˆμ§€λ§Œ Object 의 hashCode() λ©”μ†Œλ“œλŠ” 객체의 μ£Όμ†Œ 값을 μ‚¬μš©ν•΄μ„œ μ½”λ“œλ₯Ό λ§Œλ“€κΈ° λ•Œλ¬Έμ— 두 κ°μ²΄λŠ” κ²°μ½” 같은 값을 κ°€μ§ˆ 수 μ—†λ‹€. μΈμŠ€ν„΄μŠ€ λ‚΄μš©μ„ 가지고 ν•΄μ‹œ μ½”λ“œλ₯Ό λ§Œλ“€κ³  μ‹Άλ‹€λ©΄ μž¬μ •μ˜ν•΄μ•Όν•œλ‹€. 

    μΈμŠ€ν„΄μŠ€ κ°’μœΌλ‘œ 두 객체λ₯Ό λΉ„κ΅ν•˜κ³  μ‹Άλ‹€λ©΄ equals, hashCode 두가지 λ©”μ†Œλ“œλ₯Ό λͺ¨λ‘ 적절히 μž¬μ •μ˜ν•΄μ•Όν•œλ‹€.

    toString()
    μΈμŠ€ν„΄μŠ€μ— λŒ€ν•œ 정보λ₯Ό λ¬Έμžμ—΄λ‘œ μ œκ³΅ν•œλ‹€. μž¬μ •μ˜ ν•˜μ§€ μ•ŠμœΌλ©΄ 클래슀 이름과 16μ§„μˆ˜ ν•΄μ‹œ μ½”λ“œκ°€ λ°˜ν™˜λœλ‹€. 적절히 μž¬μ •μ˜ ν•˜λŠ” 것이 μ’‹λ‹€.

     

    References

    https://www.geeksforgeeks.org/dynamic-method-dispatch-runtime-polymorphism-java/
    μžλ°”μ˜ 정석 (www.yes24.com/Product/Goods/24259565)
Designed by Tistory.