혼자 공부하는 자바 개정판

[혼공자] 5주차_인터페이스, 중첩 클래스와 중첩 인터페이스

혼자 공부하는 자바 개정판


5주차 학습 진도 : Chapter 8, 9 (인터페이스, 중첩 클래스와 중첩 인터페이스)




Chapter 8 인터페이스

8-1 인터페이스


인터페이스 선언

인터페이스는 클래스가 구현해야 하는 메서드의 집합을 정의합니다. 인터페이스는 interface 키워드를 사용하여 선언합니다. 인터페이스 내의 메서드는 기본적으로 추상 메서드로 정의되며, 메서드의 몸체는 포함되지 않습니다. 아래는 간단한 인터페이스의 예입니다:


public interface RemoteControl {
    // 상수
    public int MAX_VOLUME = 10;
    public int MIN_VOLUME = 0;

    // 추상 메소드
    public void turnOn();
    public void turnOff();
    public void setVolume(int volume);
}




인터페이스 구현

클래스는 인터페이스를 구현하기 위해 implements 키워드를 사용합니다. 한 클래스는 여러 개의 인터페이스를 구현할 수 있으며, 이때 각 인터페이스의 모든 메소드를 구현해야 합니다. 아래는 RemoteControl 인터페이스를 구현한 Television 클래스의 예입니다.


public class Television implements RemoteControl {
    
    public void turnOn() {
        System.out.println("TV를 켭니다.");
    }

    public void turnOff() {
        System.out.println("TV를 끕니다.");
    }
}




인터페이스 사용

인터페이스를 사용하면 객체지향 프로그래밍의 다형성을 활용할 수 있습니다. 인터페이스 타입으로 변수 선언 후, 이를 구현한 객체를 할당하여 메소드를 호출할 수 있습니다. 다음은 RemoteControl 인터페이스를 사용하는 간단한 예제입니다.


public class MyClass {

    RemoteControl rc = new Television();

    MyClass(RemoteControl rc) {
        this.rc = rc;
        rc.turnOn();
        rc.setVolume(5);
    }

}


public class MyClassExample {
    public static void main(String[] args) {
        MyClass myClass1 = new MyClass();
        myClass1.rc.turnOn();
        myClass1.rc.setVolume(5);
    }
}





8-2 타입 변환과 다형성


자동 타입 변환

자바에서는 자식 클래스의 객체를 부모 클래스 타입으로 자동 변환할 수 있습니다. 이는 자식 클래스가 부모 클래스의 모든 특성을 가지기 때문입니다.


필드의 다형성

필드의 다형성은 객체지향 프로그래밍에서 중요한 개념으로, 동일한 타입의 필드가 다양한 구현체를 참조할 수 있게 해줍니다. 이를 통해 코드의 유연성과 확장성을 높일 수 있습니다.


public class Car {
    Tire frontLeftTire = new HankookTire();
    Tire frontRightTire = new HankookTire();
    Tire backLeftTire = new HankookTire();
    Tire backRightTire = new HankookTire();

    void run() {
        frontLeftTire.roll();
        frontRightTire.roll();
        backLeftTire.roll();
        backRightTire.roll();
    }
}




매개 변수의 다형성

메서드 매개변수로 인터페이스 타입을 사용하면 다양한 객체를 전달할 수 있습니다. 이는 코드의 유연성을 높이는 중요한 요소입니다.


public class Driver {
    public void drive(Vehicle vehicle) {
        vehicle.run();
    }
}




강제 타입 변환

자동 타입 변환 후, 원래의 객체 타입으로 다시 변환할 수 있습니다. 이때는 명시적으로 타입을 지정해야 하며, 올바른 타입으로 변환하지 않으면 ClassCastException이 발생할 수 있습니다.


public class VehicleExample {
    public static void main(String[] args) {
        Vehicle vehicle = new Bus();
        
        vehicle.run();
        
        Bus bus = (Bus) vehicle;    // 강제 타입 변환
        
        bus.run();
        bus.checkFare();
    }
}




객체 타입 확인

instanceof 연산자를 사용하여 객체의 타입을 확인할 수 있습니다. 이를 통해 안전하게 강제 타입 변환을 수행할 수 있습니다.


public class Driver {
    public void drive(Vehicle vehicle) {
        if(vehicle instanceof Bus) {
            Bus bus = (Bus) vehicle;
            bus.checkFare();
        }
    }
}




인터페이스 상속

인터페이스는 다른 인터페이스를 상속받을 수 있습니다. 이는 인터페이스 간의 관계를 형성하고, 메서드의 집합을 작성하는데 유용합니다.


public interface InterfaceC extends interfaceA, interfaceB {
    public void methodC();
}





Chapter 9. 중첩 클래스와 중첩 인터페이스


9-1 중첩 클래스와 중첩 인터페이스 소개


중첩 클래스

중첩 클래스는 다른 클래스의 내부에 정의된 클래스를 말합니다. 중첩 클래스는 외부 클래스의 멤버 변수와 메서드에 직접 접근할 수 있습니다.


class A {
    class B {
        B() {}    // 생성자

        int field1; // 인스턴스 필드
        void method1() { //인스턴스 메서드
            System.out.println("method1 호출됨");
        }
    }

    public static void main(String[] args) {
        A outer = new A();       // 외부 클래스 인스턴스 생성
        B inner = outer.new B(); // 중첩 클래스 인스턴스 생성
        inner.field1 = 10;       // 필드 값 설정
        inner.method1();         // 메서드 호출
        System.out.println("field1: " + inner.field1); // 필드 값 출력
    }
}



중첩 클래스의 접근 제한

중첩 클래스는 외부 클래스의 접근 제한자에 따라 접근할 수 있는 범위가 달라집니다. 예를 들어, private로 선언된 외부 클래스의 멤버는 내부 클래스에서 접근할 수 있습니다.


public class A {
    private class B {
        void display() {
            System.out.println("B 클래스의 메서드");
        }
    }

    public class C {
        void display() {
            System.out.println("C 클래스의 메서드");
        }
    }

    void method1() {
        B b = new B();   // B는 A 내에서만 접근 가능
        C c = new C();   // C는 외부에서도 접근 가능
        b.display();
        c.display();
    }

    public static void main(String[] args) {
        A a = new A();
        a.method1();   // 메서드 호출
    }
}



중첩 인터페이스

중첩 인터페이스는 클래스 내부에 정의된 인터페이스입니다. 중첩 인터페이스는 외부 클래스의 멤버로 사용할 수 있으며, 주로 외부 클래스와 관련된 특정 기능을 정의할 때 유용합니다.


class A {
    [static] interface I {    // 중첩 인터페이스
    void method();
    }
}



9-2 익명 객체


익명 객체는 이름이 없는 클래스의 객체로, 주로 일회성으로 사용됩니다. 익명 객체는 인터페이스를 구현하거나 추상 클래스를 상속받을 때 사용됩니다.


익명 자식 객체 생성

익명 자식 객체는 인터페이스를 구현하는 익명 객체를 생성할 때 사용됩니다.



class Parent {}

class A {
    Parent field = new Parent();    // 익명 자식 객체 생성
    void method() {
        Parent localVar = new Parent();    // 로컬 변수에 익명 자식 객체를 대입
    }
}



익명 구현 객체 생성

추상 클래스를 상속받는 익명 객체도 생성할 수 있습니다. 이를 통해 간편하게 특정 클래스의 기능을 구현할 수 있습니다.


class A {
    void method1(RemoteControl rc) { }

    void method2() {
        method1(    // method1() 메서드 호출
            new RemoteControl() {    // method1()의 매개값으로 익명 구현 객체를 대입
                @Override
                void turnOn() { }
            }
        );
    }
}



익명 객체의 로컬 변수 사용

익명 객체 내에서 로컬 변수에 접근하려면 그 변수가 final이거나 사실상 final이어야 합니다. 이는 익명 클래스가 로컬 변수를 캡처할 수 있도록 보장하는 자바의 규칙입니다.


class Anonymous {
    void method(int x, int y) {
        System.out.println("x: " + x + ", y: " + y);
    }
}

public class AnonymousExample {
    public static void main(String[] args) {
        // 익명 객체 생성
        new Anonymous() {
            @Override
            public void method(final int x, int y) {
                System.out.println("Anonymous - x: " + x + ", y: " + y);
            }
        }.method(0, 0); // 메서드 호출
    }
}





기본 숙제(필수) : 클래스를 선언할 때 인터페이스는 어떻게 선언 될 수 있는지 정리하기


인터페이스는 interface키워드를 사용해 선언하며, 메서드는 기본적으로 추상적이고, 상수를 정의할 수 있습니다.


public interface RemoteControl {
    // 상수
    public int MAX_VOLUME = 10;
    public int MIN_VOLUME = 0;

    // 추상 메서드
    public void turnOn();
    public void turnOff();
    public void setVolume(int volume);
}



클래스는 implements 키워드를 사용해 인터페이스를 구현하며, 모든 추상 메서드를 오버라이드해야 합니다.


public class Television implements RemoteControl {

    // 필드
    private int volume;
    
    // turnOn() 추상 메서드의 실체 메서드
    public void turnOn() {
        System.out.println("TV를 켭니다.");
    }
    
    // turnOff() 추상 메서드의 실체 메서드
    public void turnOff() {
        System.out.println("TV를 끕니다.");
    }
}




추가 숙제(선택) : p.443 (09-1) 확인 문제 3번 풀어보기



3. 다음과 같이 Car 클래스 냅부에 Tire와 Engine이 멤버 클래스로 선언되어 있습니다. 바깥클래스(NestedClassExample)에서 멤버 클래스의 객체를 생성하는 코드를 빈칸에 작성해 보세요.


package sec01.verify.exam03;

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


package sec01.verify.exam03;

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();
    }
}

Posts created 243

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top
Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detected!!!

현재 **광고 차단 프로그램(AdBlock)**이 켜져 있어 사이트의 일부 기능이 제한될 수 있습니다. 쾌적한 이용과 블로그 운영을 위해 광고 차단 해제(화이트리스트 등록) 후 새로고침을 부탁드립니다. 감사합니다!