Java / / 2024. 7. 15. 11:48

제네릭과 인터페이스 활용

Why Use Generics? 😄

 

간단히 말해서, 제네릭은 클래스, 인터페이스 및 메서드를 정의할 때 타입(클래스 및 인터페이스)을 파라미터로 사용할 수 있도록 합니다. 제네릭을 통해 동일한 코드를 다양한 타입으로 재사용할 수 있게 되며, 타입 안전성을 강화하고 코드의 가독성을 높일 수 있습니다.

 

제네릭의 주요 이점 💡

 

1. 컴파일 시간에 더 강력한 타입 검사: 자바 컴파일러는 제네릭 코드에 강력한 타입 검사를 적용하여, 코드가 타입 안전을 위반하는 경우 오류를 발생시킵니다. 이는 런타임 오류를 예방할 수 있어, 코드의 안정성을 높입니다.

2. 캐스트 제거: 제네릭을 사용하면 코드에서 불필요한 캐스팅을 제거할 수 있습니다. 제네릭이 없는 코드는 다음과 같습니다:

List list = new ArrayList();    
list.add("hello");             
String s = (String) list.get(0);

 

제네릭을 사용하면 캐스팅이 필요하지 않게 됩니다:

List<String> list = new ArrayList<>();
list.add("hello");
String s = list.get(0);   // no cast

 

제네릭 타입 🛠️

 

제네릭 타입은 타입 파라미터를 사용하는 클래스나 인터페이스를 의미합니다. 예를 들어, 다음과 같은 Box 클래스가 있습니다:

public class Box<T> {
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

 

여기서 T는 타입 파라미터로, 이 클래스는 모든 참조 타입을 가질 수 있습니다. 즉, 제네릭을 사용함으로써 다양한 타입에 대해 유연하게 재사용할 수 있습니다.

 

타입 파라미터 네이밍 규칙 📛

 

타입 파라미터 이름은 일반적으로 단일 대문자를 사용합니다. 이는 변수 이름과 구별하기 쉽게 하기 위해서입니다. 자주 사용되는 타입 파라미터 이름은 다음과 같습니다:

 

E - Element (Java Collections Framework에서 많이 사용됨)

K - Key

N - Number

T - Type

V - Value

S, U, V 등 - 2번째, 3번째, 4번째 타입

 

다이아몬드 연산자 💎

 

Java SE 7 이상에서는 다이아몬드 연산자 <>를 사용하여 제네릭 클래스의 생성자를 호출할 때 타입 아규먼트를 생략할 수 있습니다. 예를 들어:

Box<Integer> integerBox = new Box<>();

 

위 코드에서 Box<Integer>의 인스턴스를 생성할 때 뒤에 타입을 생략했는데, 이를 다이아몬드 연산자라고 부릅니다.

 

TV 인터페이스와 구현 📺

 

다음은 TV 인터페이스와 이를 구현한 SamsungTVLGTV 클래스의 예제입니다.

 

TV 인터페이스 정의

public interface TVInterface {
    void turnOn();
    void turnOff();
    void changeChannel(int channel);
    void changeVolume(int volume);
}
public class SamsungTV implements TVInterface {
    private String turnon;
    private String turnoff;
    private int channel;
    private int volume;

    public SamsungTV(String turnon, String turnoff, int channel, int volume) {
        this.turnon = turnon;
        this.turnoff = turnoff;
        this.channel = channel;
        this.volume = volume;
    }

    @Override
    public void turnOn() {
        System.out.println("Samsung TV is now ON");
    }

    @Override
    public void turnOff() {
        System.out.println("Samsung TV is now OFF");
    }

    @Override
    public void changeChannel(int channel) {
        System.out.println("Samsung TV changed to channel " + channel);
    }

    @Override
    public void changeVolume(int volume) {
        System.out.println("Samsung TV changed to Volume " + volume);
    }
}

 

LGTV 클래스 구현

public class LGTV implements TVInterface {
    private String turnon1;
    private String turnoff1;
    private int channel1;
    private int volume1;

    public LGTV(String turnon1, String turnoff1, int channel1, int volume1) {
        this.turnon1 = turnon1;
        this.turnoff1 = turnoff1;
        this.channel1 = channel1;
        this.volume1 = volume1;
    }

    @Override
    public void turnOn() {
        System.out.println("LG TV is now ON");
    }

    @Override
    public void turnOff() {
        System.out.println("LG TV is now OFF");
    }

    @Override
    public void changeChannel(int channel1) {
        System.out.println("LG TV changed to channel " + channel1);
    }

    @Override
    public void changeVolume(int volume1) {
        System.out.println("LG TV changed to Volume " + volume1);
    }
}

 

메인 클래스 예제 🎮

 

다음은 위에서 정의한 클래스를 사용하는 예제입니다.

 

public class Main {
    public static void main(String[] args) {
        Pair<String, Integer> pair = new Pair<>("toString" , 123);
        Pair<String, String> pair2 = new Pair<>("Hello", "World");
        First<String> first = new First<>("HelloWorld");
        First<Integer> first2 = new First<>(12344);
        Second<Integer> second = new Second<>(123456);

        System.out.println(pair.getFirst());
        System.out.println(pair.getSecond());
        System.out.println(pair.toString());
        System.out.println(pair2.getFirst());
        System.out.println(pair2.getSecond());
        System.out.println(first.getFirst());
        System.out.println(first.toString1());
        System.out.println(first2.getFirst());
        System.out.println(second.toString2());
        System.out.println(second.getSecond());
    }
}
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유