Wanna be Brilliant Full-Stack Developer

자바 제네릭고급(와일드카드) 란 무엇인가? 본문

Some Memos/Java

자바 제네릭고급(와일드카드) 란 무엇인가?

Flashpacker 2023. 3. 18. 00:09


와일드카드란 무엇인가? 제네릭 고급이다.

와일드카드는 ? 를 말하는데 무슨뜻인가 몰라라는것이다?

어떤 메서드가 리턴 타입이 ?라고 되어있으면 무엇을 리턴할지 모른다는것이다.

어떤 메서드를 만들때 String add() {} 이라고 되어있으면 이 메서드는 String을 리턴하는 메서드인데

이게 아니라 몰라(?)라고 할 수 있따.

 

몰라는 무슨뜻인가?

개념은 <? extends Object> 오브젝트를 상속하고 있는 모든 클래스들 중 하나도 된다라는 뜻이다.

즉 ?(몰라)는 모든 클래스를 의미한다.

? 라고 적는것은 뒷부분에 extends Object가 생략되어있는것이다.

 

몰라는 오브젝트를 상속하고 있는 모든것들중 하나라는 의미이다.

 

실습을 한번 해보자! 

객체지향적으로 만들어보자!

그리고 애를 리턴할 수 있는 함수를 만들어보자!

그리고 위에다가 클래스를 더 만든다.

그리고 똑같이 Set을 만들건데 

Generate Getters and Setters 애를 클릭을 하면 

private 변수에 대한 메서드를 만들어준다. 상태에 대한 두개의 행위가 만들어진다.

상태에 직접적으로 접근을 하지 못하니까 행위를 통해 접근하는 것이다. 

 

그래서 가방에 다가 

공을 한번 담아볼껀데 공을 먼저 만들어보자 

'

두개를 만들고 

첫번쨰 가방에는 농구공을 담고 

두번쨰 가방에는 축구공을 담는다.

농구공과 축구공이 제네릭을 이용하여 잘담겼다.

그럼 봐보자 

가방의 제네릭에 농구공이 들어왔으니까  가방 <T>에도 농구공이 들어오고

여기 다 농구공이다! 

두번쨰로 축구공이 들어왔으니까 재네들도 다 축구공이 들어가 있는것이다.

그래서 내가 밑에서 sysout해서 b1.getData() 를 실행해도 결과값이 제대로 나오지 않는다?

왜냐하면 b1이 농구공을 가지고 있지 않으니까

b1에 농구공을 담아야한다. 

b2.에도 축구공을 담아서

실행을 해보면 이상한 값이 나온다. 

근데 getData().getName()이라고 하면 결과값이 제대로 나온다. 

여기다가 메서드를 하나 만들것인데 꺼내기라는 메서드이다. 

int time을 적는다. 지금 만약 9시면 축구를 해야하고 12시면 농구를 해야한다 이런 가정을 하고

한번 해보자! 

축구를 해야하면 무엇을 꺼내야하는가 축구공을 꺼내야한다.

축구공을 꺼내는데 결국 가방에다가 축구공을 담아야한다. 가방<축구공>

9시면 축구공을 하나 사서 가방을 하나사서 가방에다가 축구공을 담아내야하고 

9시가 아니면 농구공을 하나사서 그리고 가방을 하나 사고

가방에다가 농구공을 담아야한다. 

 

그리고나서 Return을 해야하는데 b2는 b2는 축구공이 담긴 가방이다.

그건 잘된다.

return b1;이 안된다. b2는 가방이 축구공에 담겨 있고 

b1 가방은 농구공이 담겨 있으니까 

저 가방에 담겨있는것과 다르다. 이떄 사용하는게 와일드카드이다 ?이다.

그러면 꺼내기할때  

?는 extends Object가 생략되어있는것과 같다고 했다. 

그런데 문제가 있다.

문제가 머냐면 내가 r1가방에서 getData를하면 타입이 Object이다.

왜 getData가 오브젝트냐면 ? 

?가 되었기 떄문에 오브젝트의 자식이니까 저들이 다 Object가 된다.

내가 멀 못하는가? 내가 축구공과 농구공도 아니고 Object니까 .name도 호출할 수 없다.

 

그래서 와일드카드를 쓸떄는 축구공과 농구공을 타입을 일치 시켜야한다. 

추상클래스를 하나 만들어야한다. 

오브젝트로 하면 다운캐스팅하는것이 힘들기 떄문에 이렇게 만든다.

둘다 공의 자식이 된다. 

그러면 ? 와일드카드가 extends가 오브젝트가 아니라 공이 된다 .

그러면 이거 할떄도 받을떄도 extends 공이라고 해야한다.

그러면 r1.getData()라고 하면 공이 된다. 공은 함수의 getName을 안들고 있다.

공은 getName 메서드가 없다. 없기 떄문에 이거를 OVerrrid 무효화 기법을 하면 된다.

껍데기 함수를 쓰면 되는데?! 

부모도 getName도 자식도 가지고 있기 떄문에 자식이 부모와 메서드가 동일한걸 들고 있으면

부모의 메서드가 오버라이드가 된다 무효화가 된다고 했다.

그러면 공의 getName을 호출하면 getData()는 공이고. getName하면 공의 Getname인데 자식의

getName을 호출한다. 

농구공인가 축구공인가? r1은 

9시니까 축구공이고 축구공이 나오고 오버라이딩이 되어서 동적바인딩된 결과 값이 나온다.

이 와일드카드 를 알기 위해서는 타입의 일치 다형성을 알아야하고

두번쨰로는 Object을 알아야하고 추상클래스를 알아야하고

오버라이딩은 무효화한다는것을 알아야하고

무효화가 되면 동적바인딩이 일어나는것도 전반적인 모든것을 알아야해서

굉장히 어렵다.

만약에 이해를 했다면 엄청나게 많은 자바의 실력이 늘었다고 생각하면 된다!

 

이해가 잘안된다면 웹에서 다시 공부를 해야하고 프로그램을 만들때

엄청난 위력을 발이 할것이다!