본문 바로가기
Java

Java | 자바 기본 개념 : 클래스, 객체, 상속

by sseul-log 2025. 9. 26.

목차

  1. 클래스와 객체의 관계
  2. 인스턴스란 무엇인가?
  3. 생성자(Constructor)란?
  4. 오버로딩(Overloading) vs 오버라이딩(Overriding)
  5. 상속(Inheritance)과 생성자 호출 순서
  6. 실전 예제와 연습 문제

1. 클래스와 객체의 관계

클래스는 설계도다!

 
java
public class Handbag {
    // 속성(필드)
    String brandName;
    int price;
    String bagName;
    boolean hasHandle;
    
    // 행동(메서드)
    void display() {
        System.out.println(bagName + " by " + brandName);
    }
}

시각적 이해

┌─────────────────────────────┐
│       CLASS (설계도)          │
│   ┌─────────────────────┐   │
│   │  brandName: String  │   │ ← 이것만으로는
│   │  price: int         │   │   아무것도 할 수 없음!
│   │  bagName: String    │   │   
│   │  hasHandle: boolean │   │
│   └─────────────────────┘   │
└─────────────────────────────┘
              ↓ new 키워드로 실체화
┌──────────┐  ┌──────────┐  ┌──────────┐
│  bag1    │  │  bag2    │  │  bag3    │
│ "에르메스" │  │  "샤넬"   │  │  "구찌"   │
│  50000   │  │  30000   │  │  20000   │
└──────────┘  └──────────┘  └──────────┘
   (객체1)       (객체2)       (객체3)

2. 인스턴스란 무엇인가?

핵심 개념

  • 클래스: 붕어빵 틀 (메모리에 존재하지 않음)
  • 인스턴스: 실제로 만들어진 붕어빵 (메모리에 존재)
  • new 키워드: 붕어빵을 굽는 행위
 
java
public class Main {
    public static void main(String[] args) {
        // Dog 클래스의 인스턴스 생성
        Dog myDog = new Dog();      // 첫 번째 강아지
        Dog yourDog = new Dog();    // 두 번째 강아지
        
        // 각각 독립적인 메모리 공간
        myDog.name = "Buddy";
        yourDog.name = "Max";
        
        System.out.println(myDog.name);   // Buddy
        System.out.println(yourDog.name); // Max
    }
}

메모리 구조

HEAP 메모리
┌─────────────────────────────────┐
│  myDog (주소: 0x100)             │
│  ┌──────────────┐               │
│  │ name: "Buddy"│               │
│  │ age: 3       │               │
│  └──────────────┘               │
│                                 │
│  yourDog (주소: 0x200)           │
│  ┌──────────────┐               │
│  │ name: "Max"  │               │
│  │ age: 5       │               │
│  └──────────────┘               │
└─────────────────────────────────┘

3. 생성자(Constructor) 란 ?

생성자의 규칙

  1. 클래스 이름과 동일해야 함
  2. 반환 타입이 없음 (void도 쓰지 않음)
  3. 객체 생성 시 자동 호출
 
java
class Handbag {
    String brandName;
    int price;
    
    // 기본 생성자
    public Handbag() {
        brandName = "No Brand";
        price = 0;
    }
    
    // 매개변수가 있는 생성자 (오버로딩)
    public Handbag(String brandName, int price) {
        this.brandName = brandName;  // this = 현재 객체
        this.price = price;
    }
}

this 키워드의 이해

 
java
public Handbag(String brandName, int price) {
    this.brandName = brandName;
    //  ↑ 객체의 필드    ↑ 매개변수
    
    this.price = price;
    //  ↑ 객체의 필드  ↑ 매개변수
}

this가 가리키는 것

Handbag bag1 = new Handbag("에르메스", 50000);
         ↓
    this는 bag1을 가리킴
    
Handbag bag2 = new Handbag("샤넬", 30000);
         ↓
    this는 bag2를 가리킴

4. 오버로딩 vs 오버라이딩

오버로딩 (Overloading) - "다양한 방법"

같은 이름, 다른 매개변수

 
java
class Calculator {
    // 정수 2개 더하기
    int add(int a, int b) {
        return a + b;
    }
    
    // 정수 3개 더하기 (오버로딩)
    int add(int a, int b, int c) {
        return a + b + c;
    }
    
    // 실수 2개 더하기 (오버로딩)
    double add(double a, double b) {
        return a + b;
    }
}

오버라이딩 (Overriding) - "재정의"

상속받은 메서드를 자식이 다시 정의

 
 
java
class Car {
    void refuel() {
        System.out.println("⛽ 주유소에서 기름 넣기");
    }
}

class ElectricCar extends Car {
    @Override
    void refuel() {
        System.out.println("🔌 충전소에서 전기 충전");
    }
}

class HydrogenCar extends Car {
    @Override
    void refuel() {
        System.out.println("💧 수소 충전소에서 수소 충전");
    }
}

비교표

특징 오버로딩 오버라이딩
위치 같은 클래스 부모-자식 관계
메서드명 동일 동일
매개변수 반드시 달라야 함 반드시 같아야 함
반환타입 상관없음 같아야 함
접근제어자 상관없음 부모보다 좁으면 안됨
@Override 사용 안함 권장 (명확성)

5. 상속과 생성자 호출 순서

상속 계층 구조

 
java
class Vehicle {
    Vehicle() {
        System.out.println("1. Vehicle 생성자");
    }
}

class Car extends Vehicle {
    Car() {
        System.out.println("2. Car 생성자");
    }
}

class ElectricCar extends Car {
    ElectricCar() {
        System.out.println("3. ElectricCar 생성자");
    }
}

// 실행
ElectricCar tesla = new ElectricCar();
// 출력:
// 1. Vehicle 생성자
// 2. Car 생성자  
// 3. ElectricCar 생성자

생성자 호출 흐름도

     [Vehicle]
         ↑
     [Car]      ← super() 자동 호출
         ↑
   [ElectricCar] ← super() 자동 호출
         ↑
      new 호출

super 키워드

java
class Car {
    String model;
    int year;
    
    Car(String model, int year) {
        this.model = model;
        this.year = year;
    }
}

class ElectricCar extends Car {
    int batteryCapacity;
    
    ElectricCar(String model, int year, int battery) {
        super(model, year);  // 부모 생성자 명시적 호출
        this.batteryCapacity = battery;
    }
}

6. 실전 예제

종합 예제: 은행 계좌 시스템

 
java
// 기본 계좌 클래스
class Account {
    protected String accountNumber;
    protected double balance;
    
    public Account(String accountNumber) {
        this.accountNumber = accountNumber;
        this.balance = 0;
    }
    
    // 입금
    public void deposit(double amount) {
        balance += amount;
        System.out.println("입금: " + amount);
    }
    
    // 출금
    public void withdraw(double amount) {
        if (balance >= amount) {
            balance -= amount;
            System.out.println("출금: " + amount);
        } else {
            System.out.println("잔액 부족!");
        }
    }
}

// 저축 계좌 (상속)
class SavingsAccount extends Account {
    private double interestRate;
    
    public SavingsAccount(String accountNumber, double rate) {
        super(accountNumber);  // 부모 생성자 호출
        this.interestRate = rate;
    }
    
    // 이자 계산 (새로운 메서드)
    public void addInterest() {
        double interest = balance * interestRate;
        balance += interest;
        System.out.println("이자 추가: " + interest);
    }
}

// 체크카드 계좌 (상속 + 오버라이딩)
class CheckingAccount extends Account {
    private double overdraftLimit;
    
    public CheckingAccount(String accountNumber, double limit) {
        super(accountNumber);
        this.overdraftLimit = limit;
    }
    
    @Override
    public void withdraw(double amount) {  // 오버라이딩
        if (balance + overdraftLimit >= amount) {
            balance -= amount;
            System.out.println("출금(마이너스 통장): " + amount);
        } else {
            System.out.println("한도 초과!");
        }
    }
}

추가 학습 자료

Oracle 공식 문서

핵심 암기 사항 ✅

  1. 클래스 = 변수의 타입
  2. 생성자 = 클래스명과 동일
  3. this = 현재 객체 참조
  4. super = 부모 클래스 참조
  5. new = 인스턴스 생성
  6. extends = 상속 키워드
  7. @Override = 메서드 재정의 표시

연습 문제

java
// 문제: Animal 클래스를 상속받는 Cat 클래스를 만들고,
// makeSound() 메서드를 오버라이딩하세요.

class Animal {
    String name;
    
    void makeSound() {
        System.out.println("동물이 소리를 냅니다");
    }
}

// 여기에 Cat 클래스 작성
class Cat extends Animal {
    @Override
    void makeSound() {
        System.out.println("야옹~");
    }
    
    // Cat만의 메서드
    void scratch() {
        System.out.println("할퀴기!");
    }
}