JiwonDev

μžλ°”μ˜ μƒμ„±μž λ™μž‘λ°©μ‹ (+Inner클래슀)

by JiwonDev

λ‹€λ₯Έ 언어와 λ‹€λ₯΄κ²Œ λ™μž‘ν•΄μ„œ μΆ”κ°€λ‘œ μž‘μ„±-

 

#1. 객체 생성 μˆœμ„œ

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

λΆ€λͺ¨ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜μ§€μ•ŠμœΌλ©΄, 컴파일이 λΆˆκ°€λŠ₯ν•˜λ‹€.

μ‰½κ²Œλ§ν•˜λ©΄ λΆ€λͺ¨ 레퍼런슀( Animal dog = new Dog() )에 μ—…μΊμŠ€νŒ…ν•œ 객체λ₯Ό λ‹€μ‹œ μžμ‹κ°μ²΄( Dog newDog = dog )둜 λ‹€μš΄μΊμŠ€νŒ…ν•΄λ„ μ •μƒλ™μž‘ν•œλ‹€. 즉 μžμ‹ κ°μ²΄λŠ” λΆ€λͺ¨ 레퍼런슀(super)λ₯Ό 가지고 μžˆμ–΄ ν•„μš”ν•˜λ‹€λ©΄ μžμ‹ 객체 μ•ˆμ—μ„œ λΆ€λͺ¨ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

 

μ΄λŠ” this의 λ™μž‘μ›λ¦¬μ™€ λΉ„μŠ·ν•˜λ‹€. νž™λ©”λͺ¨λ¦¬ λ˜ν•œ λΆ€λͺ¨μ™€ μžμ‹μ΄ κ΅¬λΆ„μ§€μ–΄μ„œ 가지고 μžˆκ²Œλœλ‹€.

 

πŸ€” λΆ€λͺ¨λž‘ μžμ‹μ΄ λ˜‘κ°™μ€ μ΄λ¦„μ˜ ν•„λ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ μ–΄λ–»κ²Œλ˜λ‚˜μš”?

μ΄λ ‡κ²Œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ”κ±΄ μ •μ‹ λ‚˜κ°„ 짓이라 해본적은 μ—†κ² μ§€λ§Œ, μ˜μ™Έλ‘œ κ°€λŠ₯ν•˜λ‹€.

class Parent {

    public String name;

    public Parent(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class Child extends Parent {

    public String name; // λΆ€λͺ¨μ™€ λ˜‘κ°™μ€ μ΄λ¦„μ˜ ν•„λ“œ

    public Child(String pName, String cName) {
        super(pName);
        this.name = cName;
    }
}

이 경우, 같은 μΈμŠ€ν„΄μŠ€λΌλ„ Parent νƒ€μž…μ΄λƒ Child νƒ€μž…μ΄λƒμ— 따라 λ‹€λ₯Έ νž™ λ©”λͺ¨λ¦¬μ˜ name을 κ°€μ Έμ˜€κ²Œ λœλ‹€.

public static void main(String[] args) {
    Parent parent = new Child("parent", "child");
    System.out.println(parent.name); // "parent"κ°€ λ°˜ν™˜λ¨
    System.out.println(parent.getName()); // "parent"κ°€ λ°˜ν™˜λ¨

    Child child = (Child) parent;
    System.out.println(child.name); // "child"κ°€ λ°˜ν™˜λ¨
    System.out.println(child.getName()); // getterλ₯Ό μ˜€λ²„λΌμ΄λ”© μ•ˆν–ˆμœΌλ―€λ‘œ, parentκ°€ λ°˜ν™˜λ¨
}

hashcodeλ₯Ό 보면 μ‹€μ œλ‘œ λΆ€λͺ¨μ™€ μžμ‹μ˜ name λ©”λͺ¨λ¦¬κ°€ 닀름을 μ•Œ 수 μžˆλ‹€.

참고둜 μ΄λŠ” Outer - Innerμ—μ„œλ„ λ™μΌν•˜κ²Œ λ™μž‘ν•œλ‹€. κ²°κ΅­ ν΄λž˜μŠ€κ°€ 2개 λ§Œλ“€μ–΄μ§€κ³ , 레퍼런슀λ₯Ό κ°€μ§€λŠ”κ±°λ‹ˆκΉŒ

κ·Έλž˜μ„œ Outer의 레퍼런슀λ₯Ό κ°€μ§€μ§€μ•ŠλŠ” static InnerλŠ” Outer.name을 μ‚¬μš©ν•  수 μ—†λ‹€. μ»΄νŒŒμΌμ—λŸ¬!

class Shadowing {
    String name = "Outer John";

    class innerShadowing {
        String name = "Inner John";

        public void print() {
            System.out.println("Inner/name: " + name);
//            System.out.println(Shadowing.name); 참고둜 이건 Static ν•„λ“œλ₯Ό κ°€μ Έμ˜€λŠ” 문법이닀.
            System.out.println("Inner/Shadowing.this.name: " + Shadowing.this.name);
        }
    }

    public void outerPrint() {
        System.out.println("Outer/name: " + name);
    }
}

class Main {

    // Main driver method
    public static void main(String[] args) {
        Shadowing obj = new Shadowing();

        Shadowing.innerShadowing innerObj
            = obj.new innerShadowing();

        obj.outerPrint(); // Outer.name
        innerObj.print();
        System.out.println("Main/inner.name :" + innerObj.name); // Inner.name
    }
}

μ΄λŸ°μ‹μœΌλ‘œ ν•„λ“œμ΄λ¦„μ΄ κ°€λ €μ Έμ„œ, μˆ¨κ²¨μ§„ λΆ€λͺ¨.name 이 μžˆλŠ”κ±Έ Shadowing 이라고 ν•œλ‹€. (JS의 ν΄λ‘œμ €μ™€ λΉ„μŠ·)

 

더보기
사싀 μžλ°”μ—μ„œλŠ” Method의 μ •λ³΄λŠ” Staticμ˜μ—­μ— μ €μž₯ν•΄μ„œ λͺ¨λ“  객체가 κ³΅μœ ν•΄μ„œ μ‚¬μš©ν•œλ‹€.
κ·ΈλŸ¬λ‹€κ°€ 본인 객체의 ν•„λ“œκ°€ ν•„μš”ν•΄μ§„ 경우, λ©”μ„œλ“œκ°€ 가지고 μžˆλŠ” this(νž™ λ©”λͺ¨λ¦¬ 레퍼런슀)λ₯Ό ν†΅ν•΄μ„œ 본인 객체의 ν•„λ“œλ₯Ό 가져와 λ©”μ„œλ“œλ₯Ό μ‹€ν–‰μ‹œν‚€κ³ , thisλ₯Ό μ΄μš©ν•΄ νž™λ©”λͺ¨λ¦¬μ— λ‹€μ‹œ μ €μž₯ν•˜λŠ” 방식이닀.

즉 super도 λ§ˆμ°¬κ°€μ§€λ‘œ νž™λ©”λͺ¨λ¦¬μ— λΆ€λͺ¨λ©”μ„œλ“œ 정보가 μžˆλŠ”κ²Œ μ•„λ‹ˆλΌ, 단지 λΆ€λͺ¨ νž™λ©”λͺ¨λ¦¬ 레퍼런슀일 뿐이닀.
Dog dog = new Dog()

 

# 2. λ””ν΄νŠΈ μƒμ„±μž(Default Constructor)

μ΄λ ‡κ²Œ μžμ‹κ°μ²΄λŠ” λΆ€λͺ¨κ°μ²΄λ₯Ό λ§Œλ“€ λ•Œ λΆ€λͺ¨μ˜ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•œλ‹€.

λ‹€λ§Œ μ›ν•œλ‹€λ©΄ λͺ…μ‹œμ μœΌλ‘œ μ›ν•˜λŠ” λΆ€λͺ¨μƒμ„±μžλ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ λ°˜λ“œμ‹œ μƒμ„±μž 제일 첫문μž₯에 super()λ₯Ό ν˜ΈμΆœν•΄μ•Όν•˜λ©°, 이λ₯Ό μ–΄κΈ΄λ‹€λ©΄ μ»΄νŒŒμΌμ‹œ 였λ₯˜κ°€ λ°œμƒν•˜κ²Œ λœλ‹€.

public class Dog(){

  Public Dog() {
      super(); // λͺ…μ‹œμ μΈ λΆ€λͺ¨ μƒμ„±μžμ„ μ–Έ. λ°˜λ“œμ‹œ μƒμ„±μž 첫쀄에 μ‚¬μš©
      ...
    }
}

 

이 λ•Œ λͺ…μ‹œμ μœΌλ‘œ μƒμ„±μžλ₯Ό μž‘μ„±ν•˜μ§€ μ•Šμ•„λ„ μžλ™μœΌλ‘œ λ§Œλ“€μ–΄μ„œ ν˜ΈμΆœλ˜λŠ” μƒμ„±μžλ₯Ό Default μƒμ„±μžλΌκ³  ν•œλ‹€. λ¬Όλ‘  μƒμ„±μžλ₯Ό μž‘μ„±ν•˜μ§€ μ•Šμ•˜μ„ λ•Œ 이야기이고, λ§Œμ•½ λͺ…μ‹œμ μœΌλ‘œ μž‘μ„±ν•œ μƒμ„±μžκ°€ μžˆλ‹€λ©΄ 직접 νŒŒλΌλ©”νƒ€κ°€ μ—†λŠ” μƒμ„±μžλ₯Ό λ§Œλ“€μ–΄μ•Όν•œλ‹€.

public class Animal {

    public Animal() { } // μƒμ„±μžκ°€ μ—†λ‹€λ©΄ μžλ™μƒμ„±.
    
    public Animal(name){ } //μ΄λ ‡κ²Œ κ°œλ°œμžκ°€ μž‘μ„±ν•œ μƒμ„±μžκ°€ μžˆλ‹€λ©΄ μžλ™ μƒμ„±λ˜μ§€μ•ŠμŒ.
   
}

μƒμ„±μžκ°€ 없어도 μ΄λŸ°μ‹μœΌλ‘œ μ‚¬μš©κ°€λŠ₯ν–ˆλ˜κ±΄, Default μƒμ„±μžμ˜ μžλ™μƒμ„± λ•Œλ¬Έμ΄λ‹€.

 


# Inner 클래슀의 λ™μž‘λ°©μ‹ (λ‚΄λΆ€ 정적 클래슀)

Q. static ν΄λž˜μŠ€λŠ” 컴파일 μ—λŸ¬κ°€ λœ¨λŠ”λ°, μ™œ Innerν΄λž˜μŠ€μ—λŠ” static을 뢙일 수 μžˆμ„κΉŒμš”?

 

  1. 일단 정적 ν΄λž˜μŠ€λΌλŠ”κ±΄ μ‘΄μž¬ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. μ•„λ‹ˆ μ •ν™•νžˆλŠ” '정적이 μ•„λ‹Œ' ν΄λž˜μŠ€λΌλŠ” κ°œλ…μ΄ μ—†μŠ΅λ‹ˆλ‹€. μ• μ΄ˆμ— 클래슀의 μ •λ³΄λŠ” JVM의 ClassLoaderκ°€ μ½μ–΄λ“€μΌλ•Œ μ „λΆ€ μ •μ μ˜μ—­(λ©”μ„œλ“œ μ˜μ—­)에 μ €μž₯ν•˜λ‹ˆκΉŒμš”.
    * λ‹€λ§Œ JVM은 Lazyν•˜κ²Œ 클래슀λ₯Ό μ½μŠ΅λ‹ˆλ‹€. μ½”λ“œλ₯Ό μž‘μ„±ν–ˆλ‹€ 해도 μ‹€μ œ μ‚¬μš©ν•˜κΈ° μ „κΉŒμ§€ ClassLoading을 λ―Έλ£Ήλ‹ˆλ‹€.
  2. 사싀은 ν΄λž˜μŠ€μ •λ³΄, static ν•„λ“œ λΏλ§Œμ•„λ‹ˆλΌ λ©”μ„œλ“œ 정보도 μ •μ μ˜μ—­(λ©”μ„œλ“œ μ˜μ—­)에 μ €μž₯ν•΄μ„œ λͺ¨λ“  ν΄λž˜μŠ€κ°€ κ³΅μœ ν•©λ‹ˆλ‹€. static이 뢙지 μ•Šμ€ 일반 λ©”μ„œλ“œλ„ μ „λΆ€μš”.

 

μ΄λ ‡κ²Œ μ‚¬μš©ν•˜λ©΄ λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•  λ•Œ [νž™ λ©”λͺ¨λ¦¬μ— μžˆλŠ” ν˜„μž¬ 객체의 λ©€λ²„λ³€μˆ˜]λ₯Ό μ‚¬μš©ν•˜λ©΄ λ¬Έμ œκ°€ 생기겠죠. κ·Έλž˜μ„œ JVM은 μΆ”κ°€μ μœΌλ‘œ [이 λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜κ³ μžˆλŠ” 객체의 νž™λ©”λͺ¨λ¦¬ 레퍼런슀]λ₯Ό νŒŒλΌλ―Έν„°λ‘œ 주게 λ˜λŠ”λ°, 그게 λ°”λ‘œ thisν‚€μ›Œλ“œμ£ . thisν‚€μ›Œλ“œλŠ” λ‹¨μˆœνžˆ νŽΈμ˜μƒ μ œκ³΅λ˜λŠ” κΈ°λŠ₯이 μ•„λ‹ˆλΌ, 이런 비밀이 μˆ¨μ–΄ μžˆμ—ˆλ‹€κ³  ν•˜λ„€μš”.

 

  1. λ‹€μ‹œ 본둠으둜 λŒμ•„μ™€μ„œ, ν΄λž˜μŠ€μ— static을 λΆ™μ˜€λ‹€κ³ ν•΄μ„œ 정적 ν΄λž˜μŠ€κ°€ λ˜λŠ”κ²Œ μ•„λ‹™λ‹ˆλ‹€. μ›λž˜ 정적곡간에 μ €μž₯λ©λ‹ˆλ‹€.
  2. μžλ°”λŠ” class λ‹¨μœ„λ‘œ λ°”μ΄νŠΈμ½”λ“œλ₯Ό λ§Œλ“­λ‹ˆλ‹€. μ»΄νŒŒμΌμ„ 해보면 μ•Œκ² μ§€λ§Œ inner 클래슀, outer ν΄λž˜μŠ€κ°€ λ°”μ΄νŠΈμ½”λ“œ(.class)κ°€ λ”°λ‘œ μ‘΄μž¬ν•©λ‹ˆλ‹€.
  3. κ·Έλž˜μ„œ inner 클래슀만 λ”°λ‘œ μ‚¬μš©ν•  수 μžˆμ§€λ§Œ, 기본적으둜 μžλ°”μ—μ„œλŠ” inner ν΄λž˜μŠ€λŠ” outerν΄λž˜μŠ€κ°€ μ—†μœΌλ©΄ λ§Œλ“€ 수 μ—†κ²Œ μ„€μ •λ˜μ–΄μžˆμŠ΅λ‹ˆλ‹€.
  4. 단 inner ν΄λž˜μŠ€μ— static을 λΆ™μ΄κ²Œ 되면 outer ν΄λž˜μŠ€κ°€ 없어도 λ§Œλ“€ 수 μžˆλ„λ‘ ν—ˆμš©ν•΄μ€λ‹ˆλ‹€.
  5. λ‹€λ§Œ μ΄λ ‡κ²Œ μ–΅μ§€λ‘œ inner 클래슀λ₯Ό κΊΌλ‚΄μ„œ μ‚¬μš©ν•˜κ²Œλ˜λ©΄ λ©”λͺ¨λ¦¬ λˆ„μˆ˜λ“±μ˜ λ¬Έμ œκ°€ μžˆλŠ”λ°, 그건 이 링크에 μ—„μ²­ μžμ„Έν•˜κ²Œ λ‚˜μ™€μžˆμŠ΅λ‹ˆλ‹€.
 

정적, 비정적 λ‚΄λΆ€ 클래슀 μ•Œκ³  μ‚¬μš©ν•˜κΈ°

μžλ°”μ˜ 쀑첩 클래슀(Nested Class)μ—λŠ” μ—¬λŸ¬ 가지 μ’…λ₯˜κ°€ μžˆλŠ”λ° 그쀑 정적 λ‚΄λΆ€ ν΄λž˜μŠ€μ™€ 비정적 λ‚΄λΆ€ ν΄λž˜μŠ€μ— λŒ€ν•΄ λ‹€λ€„λ³΄κ³ μž ν•œλ‹€. κΈ€μ—μ„œ μ‚¬μš©λœ μ½”λ“œλŠ” Github…

woowacourse.github.io

 

λΈ”λ‘œκ·Έμ˜ 정보

JiwonDev

JiwonDev

ν™œλ™ν•˜κΈ°