[혼공자] 5주차_클래스로 부족한 자바, 인터페이스 개념 정리

경운·2025년 8월 7일
0

혼공자

목록 보기
5/7
post-thumbnail


📚 5주차 미션 정리

🔖 기본 미션 (필수)

클래스를 선언할 때 인터페이스는 어떻게 선언될 수 있는지 정리하기

1. 하나의 인터페이스 구현 선언

public interface Car {
    void run();
    void stop();
}

public class Taxi implements Car {
    @Override
    public void run() {
        System.out.println("택시가 달립니다.");
    }

    @Override
    public void stop() {
        System.out.println("택시가 멈춥니다.");
    }
}

2. 여러 개의 인터페이스 구현 선언

public interface Car {
    void run();
}

public interface Sound {
    void beep();
}

public class Bus implements Car, Sound {
    public void run() {
        System.out.println("버스가 달립니다.");
    }

    public void beep() {
        System.out.println("버스가 빵빵 경적을 울립니다.");
    }
}

🔖 추가 미션 (선택)

P.443 (09-1) 확인 문제 3번 풀어보기

1. Car.java

public class Car {
	class Tire {}
    static class Engine {}
}

2. NestedClassExample.java

public class NestedClassExample {
	public static void main (String[] args) {
    Car myCar = new Car();
    
    Car.Tire tire = myCar.new Tire(); //인스턴스 맴버 클래스 객체 생성
    Car.Engine engine = new Car.Engine(); //정적 멤버 클래스 객체 생성
  1. 인스턴스 멤버 클래스는 외부 클래스(Car)의 객체가 먼저 있어야 생성 가능
  2. 정적 클래스는 외부 클래스 객체 없이도 생성 가능

📌 Chap08 내용 정리 | 인터페이스

인터페이스

  • 개발 코드와 객체가 서로 통신하는 접점 역할
  • 인터페이스의 메소드를 호출하면 인터페이스는 객체의 메소드를 호출

1. 인터페이스(interface) 선언

public interface Car {
	//상수
    public static final String name = "자동차" //타입 상수 이름 = 값;
    //추상 메소드
    public abstract void stop();
    public abstract void run(); // 타입 메소드이름(매개변수, );
}

인터페이스는 상수 필드와 추상 메소드만 가질 수 있음
인터페이스는 객체로 생성할 수 없기 때문에 생성자를 가질 수 없음


2. 인터페이스 구현 및 사용

public class Taxi implements Car{
    
    @Override
    //인터페이스에 선언된 추상 메소드의 실체 메소드 선언
    public void stop() {
        System.out.println("택시가 멈춥니다");
    }
    
    @Override
    public void run() {
        System.out.println("택시가 달립니다");
    }
}
public class Bicycle implements Car{
    
    @Override
    //인터페이스에 선언된 추상 메소드의 실체 메소드 선언
    public void stop() {
        System.out.println("자전거가 멈춥니다");
    }
    
    @Override
    public void run() {
        System.out.println("자전거가 달립니다");
    }
}
public class Main {
    public static void main(String[] args) {
        Car taxi = new Taxi();
        Car bicycle = new Bicycle();
        
        taxi.run();
        taxi.stop();

        bicycle.run();
        bicycle.stop();
    }
}

Car 인터페이스를 implements 키워드로 구현하고 인터페이스 추상 메서드들을 재정의!


3. 타입 변환과 다형성
위 코드를 보자

  • 자동 타입 변환
Car taxi = new Taxi();
Car bicycle = new Bicycle();

자식 → 부모로의 업캐스팅(자동) / 따라서 Car 인터페이스에 정의된 메서드만 호출 가능

강제 타입 변환 및 객체 타입 확인

1. Car. java (인터페이스)

public interface Car {
    void run();
    void stop();
}

2. Taxi.java (Car 구현 + 추가 기능)

public class Taxi implements Car {

    @Override
    public void run() {
        System.out.println("택시가 달립니다.");
    }

    @Override
    public void stop() {
        System.out.println("택시가 멈춥니다.");
    }

    // Taxi에만 있는 고유 메서드
    public void pickUpPassenger() {
        System.out.println("승객을 태웁니다.");
    }
}

3. Bicycle.java (Car 구현)

public class Bicycle implements Car{
    
    @Override
    public void stop() {
        System.out.println("자전거가 멈춥니다");
    }
    
    @Override
    public void run() {
        System.out.println("자전거가 달립니다");
    }
}

4. Main.java

public class Main {
    public static void main(String[] args) {
        Car car = new Taxi();
        car.run();  // 택시가 달립니다.
        car.stop(); // 택시가 멈춥니다.

        // car.pickUpPassenger(); //오류 발생 Car 타입에는 없음

        // 강제 타입 변환 - 다시 Taxi 타입으로 변환해야 가능
        if (car instanceof Taxi) {
            Taxi taxi = (Taxi) car; // 강제 타입 변환
            taxi.pickUpPassenger(); 
        }

        // Bicycle은 pickUpPassenger 메서드 없음 → 다운캐스팅 불가
        Car bicycle = new Bicycle();
        if (bicycle instanceof Taxi) {
            Taxi wrongTaxi = (Taxi) bicycle;  // 실행 시 ClassCastException 오류 발생
            wrongTaxi.pickUpPassenger();
        } else {
            System.out.println("이 객체는 Taxi가 아닙니다.");
        }
    }
}

강제 타입 변환을 하기 전에 instanceof 키워드를 사용해서 변환이 가능한 지 조사를 해야함
신경 안쓰고 그냥 했다간 ClassCastException 오류 발생

  • 다형성 - 하나의 타입 (Car)으로 여러 형태(Taxi, Bicycle)의 객체를 참조할 수 있는 성질
    → 즉, 부모 타입(인터페이스)으로 여러 자식클래스의 객체 사용 가능

4. 인터페이스의 상속

  • class와 class 의 상속 → 키워드 extends 사용
  • class와 implements의 상속 → 키워드 implements 사용
  • implements와 implements의 상속 → 키워드 extends 사용

📌 Chap09 내용 정리 | 중첩 클래스와 중첩 인터페이스

중첩 클래스

1. 인스턴스 멤버 클래스

class A {
	class B{}
}
  • A 객체를 생성해야만 사용 할 수 있는 B 클래스
  • static 키워드 없이 중첩 선언된 클래스 → 인스턴스 필드와 메소드만 선언 가능 / 정적 필드와 메소드는 선언 불가 (static 붙은 건 사용 불가)

2. 정적 멤버 클래스

class A {
	static class B{}
}
  • A 클래스로 바로 접급할 수 있는 B 클래스
  • static 키워드로 선언된 클래스 → 모든 종류의 필드와 메소드를 선언 가능

3. 로컬 클래스 → 생성자 또는 메소드 내부에서 선언되는 중첩 클래스

class A {
 void method () {
   class B {}  
   }
}
  • method()가 실행할 때만 사용할 수 있는 B 클래스
  • 매소드 내부에서만 사용하니까 → 접근제한자(public, private) 및 static 붙일 수 없음

중첩 인터페이스

1. 버튼 클릭 리스너

public class Button {
    // 중첩 인터페이스
    public interface OnClickListener {
        void onClick(); // 추상 메서드
    }

    private OnClickListener listener;

    // 외부에서 인터페이스 구현체를 전달 받는 메서드
    public void setOnClickListener(OnClickListener listener) {
        this.listener = listener;
    }

    public void click() {
        if (listener != null) {
            listener.onClick();
        }
    }
}

2. Main 클래스

public class Main {
    public static void main(String[] args) {
        Button button = new Button();

        // 중첩 인터페이스 구현
        button.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick() {
                System.out.println("버튼이 클릭되었습니다!");
            }
        });

        button.click();
    }
}

0개의 댓글