상속 미처 몰랐던거

류한선·2025년 7월 6일

실기연습-2

목록 보기
93/95

좋은 질문이에요. 이 코드는 한눈에 봐도 거의 맞는 것처럼 보이지만, 컴파일 오류가 발생하는 치명적인 문제점이 있습니다.
아래에서 전체적으로 어느 부분이 잘못됐고, 왜 잘못됐는지 한 줄 한 줄 디버깅하듯이 설명드릴게요.


🔍 문제 코드 요약

class Person {
    private String name;
    public Person(String val) {
        name = val;
    }
    public static String get() {
        return name; // ❌ 문제 발생
    }
    public void print() {
        System.out.println(name);
    }
}
public class main {
    public static void main(String[] args) {
        Person obj = new Person("Kim");
        obj.print();
    }
}

❌ 문제 발생 위치

public static String get() {
    return name;
}

여기서 컴파일 오류가 발생합니다.


🧠 이유 설명

🔸 name인스턴스 변수 (non-static)

private String name;

이 변수는 객체가 생성될 때마다 개별적으로 존재하는 변수입니다. 즉, obj1, obj2 각각의 name이 따로 있음.


🔸 get() 메서드는 정적 메서드 (static)

public static String get()

static 메서드는 클래스 차원에서 동작하므로, 객체 없이도 Person.get() 식으로 호출됩니다.

즉, static 메서드는 클래스 자체만 보고 실행되기 때문에, 인스턴스 변수인 name을 직접 사용할 수 없습니다.

✅ 정리
static 메서드 안에서는 name 같은 인스턴스 변수 사용 불가
그래서 return name; 코드는 컴파일 에러 발생:
"non-static variable name cannot be referenced from a static context"


🛠️ 수정 방법

방법 1: get()을 static → 인스턴스 메서드로 바꾸기

public String get() {
    return name;
}

방법 2: name을 static 변수로 바꾸기 (그러나 일반적인 상황에서는 지양)

private static String name;

✅ 수정한 코드 예시 (방법 1)

class Person {
    private String name;
    
    public Person(String val) {
        name = val;
    }

    // static 제거함
    public String get() {
        return name;
    }

    public void print() {
        System.out.println(name);
    }
}

public class Main {
    public static void main(String[] args) {
        Person obj = new Person("Kim");
        obj.print();                // Kim 출력
        System.out.println(obj.get()); // Kim 출력
    }
}

좋아요! 지금부터 Java에서 static과 인스턴스 변수/메서드의 관계를 아주 기초부터 자세하게, 예제와 함께 시각적으로 설명해드릴게요.
완전 초보자 기준으로 하나도 안 빼고 순서대로 설명합니다.


📌 개념 차이: static vs 인스턴스 (non-static)

구분static인스턴스 (non-static)
소속클래스(Class)객체(Instance)
메모리프로그램 시작 시 1개 생성객체를 만들 때마다 새로 생성
사용클래스명으로 접근객체명으로 접근
예시Person.countobj.name

👨‍🏫 1. 가장 단순한 예제부터

class Person {
    String name;               // 인스턴스 변수
    static int count = 0;      // 클래스 변수 (static)

    public Person(String name) {
        this.name = name;
        count++;               // 객체가 생성될 때마다 count 증가
    }

    public void printName() {  // 인스턴스 메서드
        System.out.println("이름: " + name);
    }

    public static void printCount() { // static 메서드
        System.out.println("전체 인원 수: " + count);
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("Kim");
        Person p2 = new Person("Lee");

        p1.printName();            // 이름: Kim
        p2.printName();            // 이름: Lee

        Person.printCount();       // 전체 인원 수: 2 ✅ (클래스명으로 호출)
    }
}

🔍 2. 내부 동작 흐름

메모리 구조 상상하기

🧠 JVM 메모리:
---------------------
| static 영역        |
| - Person.count = 2 |  <-- 클래스 변수 (딱 1개)
---------------------
| 힙(heap) 영역      |
| - p1.name = "Kim"  |
| - p2.name = "Lee"  |  <-- 각각 객체마다 name이 따로 존재
---------------------

❗ static 메서드에서 인스턴스 접근 불가한 이유

<public static void printCount() {
    System.out.println("이름은 " + name); // ❌ 오류: static 메서드에서 name 접근 불가
}

이유:

  • printCount()는 클래스 차원에서 호출됨 (Person.printCount())
  • 그런데 name은 객체가 있어야만 존재하는 값
  • 따라서 객체 없이 실행되는 static 메서드는 name에 접근 불가능

✅ 인스턴스 메서드에서는 둘 다 가능

public void printInfo() {
    System.out.println("이름: " + name);     // 가능: this.name
    System.out.println("전체 인원: " + count); // 가능: static 변수도 접근 가능
}

왜 가능하냐면?

  • 인스턴스 메서드는 객체가 만들어졌을 때 실행되므로
  • 객체의 name도 있고, 클래스 변수 count도 함께 보임

🔄 호출 방식 비교 요약

메서드호출 방식내부에서 접근 가능한 것
staticPerson.method()static 변수/메서드만
인스턴스obj.method()인스턴스 + static 모두 가능

💡 핵심 요약

  • static은 "클래스 전체에 하나뿐인 공유 자원"
  • 인스턴스 변수/메서드는 "객체가 존재할 때만 사용 가능"
  • static 메서드에서는 인스턴스 변수/메서드에 접근 ❌
  • 반대로 인스턴스 메서드는 static 변수/메서드에 접근 가능

🎯 마무리 예제 (틀린 코드 → 고친 코드)

❌ 틀린 코드

class Person {
    String name;

    public static void printName() {
        System.out.println(name); // 오류 발생!
    }
}

✅ 고친 코드

방법 1: static 제거

public void printName() {
    System.out.println(name); // 정상 작동
}

방법 2: name도 static으로 변경

static String name;

public static void printName() {
    System.out.println(name); // 가능하지만 모든 사람이 같은 이름 가짐
}

0개의 댓글