ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 제네릭 변수의 참조와 상속의 관계
    JAVA/Generic 2020. 10. 18. 22:12

    아래와 같은 프로그램이 있다고 하자.

    위의 OhMethod함수의 인자로 전달될 수 있는 참조 값의 자료형은 두 가지이다.

    1. FruitBox<Fruit>의 인스턴스 참조 값

    2. FruitBox<Fruit>를 상속하는 인스턴스의 참조 값

     

    위의 클래스 Fruit와 Apple 클래스의 상속 구조에서 

    FruitBox<Apple> 클래스는 OhMethod의 인자가 될 수 없다.

    반드시 키워드 extends를 이용해서 상속이 명시된 대상만 인자로 전달 될 수 있다.

            ... extends FruitBox<Fruit>

    다음과 같은 구조이다. 일단 보고 넘기자. 아래에 이 내용이 나온다.

     

     

     

    와일드 카드와 제네릭 변수의 선언

    와일드 카드란, 이름 또는 문자열에 제한을 가하지 않음을 명시하는 용도로 사용하는 특별한 기호이다.

    위의 <? extends Fruit>가 의미하는 바는 "Fruit를 상속하는 모든 클래스"이다.

    FruitBox<Fruit> 인스턴스의 참조 값도, FruitBox<Apple> 인스턴스의 참조 값도

    인자와 전달받을 수 있는 매개변수의 선언에는 와일드카드 문자?가 사용된다.

     

    아래의 문장이 의미하는 것은 자료형에 상관 없이 FruitBox<T>의 인스턴스를 참조해 사용되는

    참조변수로 다음의 선언과 동일하다.

    즉,아래의 두 문장은 서로 같다.

     

    예제

    소스 코드

    더보기
    class Fruit
    {
    	public void ShowYou()
    	{
    		System.out.println("I am Fruit.");
    	}
    }
    
    class Apple extends Fruit
    {
    	@Override
    	public void ShowYou()
    	{
    		System.out.println("I red Fruit.");
    	}
    }
    
    class FruitBox<T>
    {
    	T item;
    	
    	public void Store(T item) {this.item = item;}
    	public T PullOut() {return this.item;}
    }
    
    public class Exam1 
    {
    	public static void main(String[] args) 
    	{
    		FruitBox<Fruit> box1 = new FruitBox<Fruit>();
    		box1.Store(new Fruit());
    		
    		FruitBox<Apple> box2 = new FruitBox<Apple>();
    		box2.Store(new Apple());
    	}
    	
    	public static void OpenAndShowFruitBox(FruitBox<? extends Fruit> box)
    	{
    		Fruit fruit = box.PullOut();	//	Fruit클래스를 상속받은 객체들이 저장된다.
    		fruit.ShowYou();
    	}
    }

     

     

    하위 클래스를 제한하는 용도의 와일드 카드

    위는 ~을 상속하는 클래스라면 무엇이든지라는 의미를 갖는다.

    즉, Apple 상속하는 클래스의 인스턴스라면 무엇이든지 참조 가능한 참조변수 선언이다.

     

    위는 ~이 상속하는 클래스라면 무엇이든지라는 의미를 갖는다.

    Apple 상속하는 클래스의 인스턴스라면 무엇이든지 참조 가능한 참조변수 선언이다.

     

     

    제네릭 클래스의 다양한 상속 방법1

    위와 같이 제네릭 클래스도 상속이 가능하다. 그리고 이 경우 다음과 같이 인스턴스를 생성하게 된다.

    아래를 보자. 

    위와 같은 경우는 T는 각 각 String과 Integer로 대체되어 인스턴스가 생성된다.

     

     

    제네릭 클래스의 다양한 상속 방법2

    아래와 같이 제네릭 클래스의 자료형을 결정해서 상속하는 것도 가능하다.

    이 경우, BBB클래스는 제네릭과 관련 없는 클래스가 되어, 일반적인 방법으로 인스턴스를 생성하면 된다.

    아래의 예제를 보자.

    프로그램 실행결과

    소스 코드

    더보기
    class AAA<T>
    {
    	T itemAAA;
    	
    	//	생성자
    	public AAA(T itemAAA)
    	{
    		this.itemAAA = itemAAA;
    	}
    	
    	public void Print()
    	{
    		System.out.println("AAA : " +this.itemAAA);
    	}
    }
    
    class BBB extends AAA<String>
    {
    	int itemBBB;
    	
    	//	생성자
    	public BBB(String item) 
    	{
    		super(item);	//	부모 클래스 AAA<String>를 호출
    	}
    }
    
    public class Exam1 
    {
    	public static void main(String[] args) 
    	{
    		BBB bbb = new BBB("MyString");
    		
    		bbb.Print();
    	}
    }

     

    제네릭 인터페이스의 구현 방법

    아래와 같이 인터페이스가 있다고 하자.

    위의 인터페이스를 상속하는 두 클래스를 정의해보자.

    1. 클래스

    위의 클래스를 보면 알겠지만, 일반적인 인터페이스의 상속과 차이가 없다.

     

    2. 클래스

    위의 클래스를 보면 제네릭 인터페이스의 자료형을 지정해서 구현하는 것도 가능함을 알 수 있다.

     

    소스 코드

    더보기
    interface MyInterface<T>
    {
    	public T MyFunc(T item);	//	러턴형이 T인 추상 메소드
    }
    
    class MyImplement<T> implements MyInterface<T>
    {
    	@Override
    	public T MyFunc(T item)
    	{
    		return item;
    	}
    }
    
    class MyImplementString implements MyInterface<String>
    {
    	@Override
    	public String MyFunc(String item)
    	{
    		return item;
    	}
    }
    
    public class Exam1 
    {
    	public static void main(String[] args) 
    	{
    		
    	}
    }

     

    'JAVA > Generic' 카테고리의 다른 글

    제네릭 메소드와 배열  (0) 2020.10.18
    매개변수의 자료형 제한  (0) 2020.10.18
    제네릭 메소드  (0) 2020.10.18
    제네릭 클래스의 이해와 설계  (0) 2020.10.18

    댓글

Designed by Tistory.