Cohe

10 Interface 인터페이스 본문

개발 언어/JAVA

10 Interface 인터페이스

코헤0121 2024. 3. 18. 17:57
728x90

Interface

인터페이스

  • 인터페이스 선언
  • interface InterfaceName [**extends** <SuperInterface>,<SupterInterface>....] { interfaceBody }
  • 예) 인터페이스 정의
  • public intrface Aquatic { **public abstract** void swimming(); public abstract void breathUnderWater(); }
  • 인터페이스는 골격만 정의해 놓은 것으로 주로 기능(메서드)의 명세를 정의
  • 인터페이스 내에 메서드는 모두 추상메서드이며 public abstract는 생략 가능합니다.
  • 인터페이스 내에 변수는 항상 public static final이며 이 또한 생략이 가능합니다.
  • 인터페이스는 구현하면 다중 상속과 같은 효과를 낼 수 있습니다.(상속을 여러개 받으면 어느 부모의 멤버를 상속받아야할지 결정할 수 없지만, 인터페이스는 클래스의 골격에 해당하기 때문에 여러개를 구현할 수 있습니다.)
  • class className implements InterfaceName1, InterfaceName2,... { classbody; }
  • 예) 클래스에 인터페이스 구현
  • public class Mermaid extends Human implements Aquatic { public void swimming() { //인어가 수영하는 기능 구현... } public void breathUnderWater() { //물속에서 숨쉬는 기능 구현... } }
  • 인터페이스는 implements 라는 키워드를 통해서 구현
  • 여러개의 인터페이스를 동시에 구현할 수 있습니다.
  • 반드시 인터페이스 내에 모든 메서드를 구현해야 합니다.

  • 인터베이스 변수는 public static final을 생략할 수 있고, 이는 상수로
  • 인터페이스 메서드는 추상 메서드로 public abstract를 생략할 수 있음

인터페이스 정리

  • 단일 상속 문제를 해결 할 수 있음
  • 인터페이스 메서드는 추상 메서드
  • 인터페이스 변수는 자동으로 상수
  • 인터페이스 구현은 implements (구현)할 수 있다
  • 인터페이스 상속은 다른 인터페이스 여러개를 extends로 할 수 있음.
  • 기능 명세를 위해 사용(프로그램의 구조를 기술하기 때문
package D_java;

import D_java.Interface_.ISomething;

public class D03_InterfaceEx3 implements ISomething{
    @Override
    public void run(){
        System.out.println("run() : "+ISomething.A);

    }
    public static void main(String[] args) {
        //상수라면 다 똑같다
        System.out.println(ISomething.MY_INT);
        System.out.println(D03_InterfaceEx3.MY_INT);

        //메서드의 동작이 같다 -> 다형성
        ISomething is = new D03_InterfaceEx3();
        is.run();

        D03_InterfaceEx3 di = new D03_InterfaceEx3();
        di.run();       
    }
}

내부 클래스(inner Class)

  • 클래스안에 또 클래스를 선언하는 경우

존재 유무에 따라서 4가지 형태로 나눔

  • 멤버 이너 클래스 : 클래스 안에 멤버로 존재하는 형태
  • 로컬 이너 클래스 : 메서드 또는 블록 안에 존재하며 이름이 있는 형태
  • 익명 클래스 : 메서드 또는 블록 안에 존재하지만 이름이 없는 형태
  • 정적 중첩 클래스 : 멤버 이너 클래스에 static이 붙은 형태

사용하는 경우

  • 코드 캡슐화 : 프로그램에는 수많은 클래스들이 필요. 일정 범위 이상의 역할을 하지 않는 클래스는 굳이 클래스 형태로 작성할 필요가 없음. 작성하게 된다면 많은 클래스로 인해 코드 파악, 유지 및 보수가 어렵다.

클래스간의 의존성이 높은 경우 : B라는 클래스가 A라는 클래스에 의해 항상 호출되어야 하지만, 따로 클래스화하기
애매한 코드일 경우 내부 클래스를 사용하면 깔끔한 코드 작성이 가능하다...

 


JAVA GUI란?

  • 프로그램을 그래픽화(프레임창(시켜 작동 시키는 것
  • AWT(만들기 쉽고, 무겁다) Swing(만들기 어렵고 가볍다) 패키지를 이용해서 프레임창 구현
  • Frame 또는 JFrame 클래스를 이용해 프레임 창을 구현 프레임 창 구현 후에 각종 이벤트 처리 및 버튼, 패널, 입력창, 메뉴바, 속성 같은 구성요소들을 각 클래스들을 이용해서 구현
  • Frame(A) 클래스가 각종 구성요소(B)클래스들을 전부 호출, 구성요소(B) 클래스 들은 각 프레임 창별로 달라지기 때문에 개별 클래스와 한다면 여러 츨면에서 낭비 → 내부클래스 사용
static 내부 클래스 : static 붙은 멤버와 동일하게 사용이 가능하다.
    내부 클래스는 static 붙어 있기 때문에 static이 붙은 멤버에만 접근이 가능하다.
    접근 방식에 의해 객체 생성 방법에서 차이가 생기게 된다.
    static 없는 멤버 이너 클래스는 외부 객체를 생성한 후에 내부 클래스에 접근이 가능
    static 있는 경우 외부 클래스 객체 생성 없이 바로 호출이 가능하다.
   

익명 클래스 예제

package D_java;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class D04_anonymousEx1 {
    private Frame f;
    public D04_anonymousEx1(){
        f = new Frame("Anonymous innerClass");
    }
    public void launchFrane(){
        //익명 클래스 사용 - 익명 클래스는 이름이 없기 때문에 생성자를 가지지 않고, 호출 및 상속 x
        //이미 만들어진 인터페이스나 클래스를 상속 또는 구현해서 만들어지게 된다.
        //여러번 사용할 클래스가 아닌 한 번만 사용할 클래스에 주로 사용됩니다.
        // 클래스 내에 메서드를 재정하기 하기 용이하여 '함수형 프로그램과 비슷하게 활용할 수 있음'
        //인터페이스와 익명 클래스를 같이 사용하면 여러 상황에서 쓰일 수 있는 유틸리티 클래스를 만들어 사용할 수 있다.
        f.addWindowListener(new WindowAdapter() {
            //WindowAdapter 추상 클래스이다.
            @Override
            public void windowClosing(WindowEvent e) {
                System.out.println("종료 버튼을 눌렀어요.");
                System.exit(0);
            }
        });
        f.setSize(640,480);
        f.setVisible(true);
    }
    public static void main(String[] args) {
        D04_anonymousEx1 da = new D04_anonymousEx1();
        da.launchFrane();
    }

}

만능 리모컨

익명클래스 + 인터페이스 =>
익명클래스와 인터페이스를 함께 사용하면 상황에 따라 가변 가능한 코드를 만들 수 있습니다.
Machine이라는 클래스를 상속해서 에어컨, 컴퓨터, TV등의 여러가지 기계 클래스들이 존재한다고 가정!
이때 어느 기계에도 적용 가능한 만들 리모콘을 만들어 보세요!!!

Machine 클래스

  • 변수 : name
  • 메서드 : machineWork -> 리모콘을 이용하여 On/Off기능을 동작함!

TV, 컴퓨터, 에어컨 -> Machine을 상속받아서 이름만 동작하고, 일부 메서드는 알아서 작성하세요!!!

Main메서드가 있는 클래스를 생성하여 테스트 해보세요

~

  • 참고 사항
  • Machine 클래스
    • 멤버 변수 : name
    • 메서드 : machineWork -> 리모컨을 이용한 On/Off기능의 동작 리모컨 인터페이스
    • On - Off TV, 컴퓨터, 에어컨 등에서 machineWork를 사용하면 리모컨의 On/Off기능을 통해서 꺼지고, 켜지는 내용이 출력되게 만들어 줌

 

package week01;

 interface RemoteMachine{
    void trunON();
    void trunOff();
 }

class Machine {
    String name;
    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

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

    public void machineWork(RemoteMachine m ){
        System.out.println(name + "을(를) 조작합니다.");
        m.trunON();
        m.trunOff();       
    } 
    public static void machineWork(RemoteMachine m , Machine t){
        m.trunON();
        m.trunOff();       
    }
}
class  TV extends Machine {
    public TV(String name){
        super(name);
    }
    @Override
    public String getName() {
        return super.getName();
    }
    @Override
    public void setName(String name) {
        super.setName(name);
    }
    public void show(){
        System.out.println("방송 중입니다.");
    }
    

    
}

public class D_Quiz_Inner {
    public static void main(String[] args) {
        // Machine tv = new Machine("TV"){
        //     @Override
        //     public void machineWork(RemoteMachine m) {
        //         super.machineWork(m);
        //     }
        // };
        // tv.machineWork(new RemoteMachine() {
        //     @Override
        //     public void trunON() {
        //         System.out.println(tv.name + "전원이 켜집니다.");
                
        //     }
        //     @Override
        //     public void trunOff() {
        //         System.out.println(tv.name +"전원이 꺼집니다.");
                
        //     }
        // });
        Machine tv = new TV("TV");
        Machine.machineWork(new RemoteMachine() {
            @Override
            public void trunON() {
                System.out.println(tv.getName()+"를 켭니다");
                
            }
            @Override
            public void trunOff() {
                System.out.println(tv.getName()+"를 끕니다");
            }
        },tv);

    

        Machine computer = new Machine("computer"){
            @Override
            public void machineWork(RemoteMachine m) {
                super.machineWork(m);
            }
        };;
        computer.machineWork(new RemoteMachine() {
            @Override
            public void trunON() {
                System.out.println(computer.name + "전원이 켜집니다.");
                
            }
            @Override
            public void trunOff() {
                System.out.println(computer.name +"전원이 꺼집니다.");
                
            }
        });


        Machine aircon = new Machine("aircon"){
            @Override
            public void machineWork(RemoteMachine m) {
                super.machineWork(m);
            }
        };;
        aircon.machineWork(new RemoteMachine() {
            @Override
            public void trunON() {
                System.out.println(aircon.name + "전원이 켜집니다.");
                
            }
            @Override
            public void trunOff() {
                System.out.println(aircon.name +"전원이 꺼집니다.");
                
            }
        });

        
    }
}

다중 상속-인터페이스, 추상 클래스 비교!!!

인터페이스

  • 구현 객체의 같은 동작을 보장하는 용도

추상클래스

  • 추상클래스를 상속받아 기능을 이용 및 확장하는 용도

Ex) 동물은 육지동물과 해양동물을 가리지 않고 자다, 먹다는 개념이 있다.

동물 (자다, 먹다)
육지 동물 - 개(자다 - 개는 잠을 잡니다., 먹다 - 개는 사료를 먹습니다.),
호랑이(자다 - 호랑이는 잠을 잡니다., 먹다 - 호랑이는 고기를 먹습니다.)
해양 동물 - 금붕어(자다 - 금붕어는 잠을 잡니다., 먹다 - 금붕어는 플랑크톤을 먹습니다.)
상어(자다 - 상어는 잠을 잡니다., 먹다 - 상어는 물고기를 먹습니다.)

ex) 도형은 좌표를 이용해 각 도형의 요소들을 나타낼 수 있지만, 넓이를 구하는 방식은 도형별로 다르다.

 

 

package week01;

interface Animal{
    void sleep();
    void eat();
}
// 추가
interface Pet {
    void play();
    
}

class LandAnimal{
    String name;
    String food;
    public LandAnimal(String name , String food){
        this.name = name;
        this.food = food;
    }
}

class SeeAnimal {
    String name;
    String food;
    public SeeAnimal(String name , String food){
        this.name = name;
        this.food = food;
    }
}
class Dog extends LandAnimal implements Animal, Pet {
    
    public Dog(String name, String food){
        super(name,food);
    }
    @Override
    public void sleep() {
        System.out.println(name +"는 잠을 잔다");
    }
    @Override
    public void eat() {
        System.out.println(name +"는 "+food+"을 먹는다");
    }    
    @Override
    public void play() {
        System.out.println("이 동물은 애완동물이 될 수 있다.");
    }
}

class PrintStatus{
    public void show(Animal a){
        a.eat();
        a.sleep();
    }

}

public class D_QuizInterface2 {

    public static void main(String[] args) {
        PrintStatus p = new PrintStatus();
        Dog dog = new Dog("개", "사료");
        p.show(dog);
        dog.play();
        
    }
}

'개발 언어 > JAVA' 카테고리의 다른 글

12 JAVA API  (0) 2024.03.20
11 Exception  (0) 2024.03.19
09 Usage Modifier  (0) 2024.03.15
08 상속, modify  (0) 2024.03.14
07 Class, Method, Package  (0) 2024.03.13