티스토리 뷰
1. Generic 메소드에 대하여 설명하시오.
클래스 뿐만 아니라 메소드도 제네릭으로 선언할 수 있다.
이 경우 제네릭 클래스와 마찬가지로 함수를 만들 때는 정확한 타입을 정해주지 않고 메소드를 호출할 때 타입인자가 정해지게 된다.
(매개 타입과 리턴 타입으로 타입 파라미터를 갖는 메소드)
제네릭 메소드의 형태는 아래와 같다.
public static <T> Box<T> makeBox(T o) {
접근제한자(public) + static + 파라미터 값으로 T o(타입)을 사용하기 위해서 <T> 제네릭 선언 + 리턴타입(Box<T>) + 함수명(makeBox) + (T o)파라미터 값
}
2.Generic(제네릭) 클래스의 타입 인자 제한하는 방법과 효과는?
제네릭 클래스의 경우 타입 인자를 특정 클래스의 자식으로 제한할 수 있다.
class Box<T extends Number> {
}
→ 인스턴스 생성 시 타입 인자로 Number 또는 이를 상속하는 클래스만 올 수 있음
위와 같이 extends를 붙여주면 해당 클래스 또는 해당 틀래스의 자식 클래스만 타입 인자로 받을 수 있다.
(implements를 써서 인터페이스 역시 동일하게 사용 가능하다.)
또한 &을 사용하면 하나의 클래스와 인터페이스를 동시에 사용할 수 있다.
ex) class Box<T extends Number & Toy>
3.와일드 카드란?
이전에 제네릭 메소드에 <T>를 통해 함수에 제네릭 선언를 해서 타입 인자를 받았던 것을 일반 메소드에서 제네릭 선언을 붙이지 않고 제네릭 인스턴스를 파라미터 값으로 받는 것을 말한다.
본래 일반 메소드는 직접 제네릭을 파라미터 값으로 받을 수 없다.
왜냐하면 제네릭 안의 인스턴스는 폴리몰티즘이 적용되지 않기 때문에 <Object>를 사용해도 다른 타입 인자를 받을 수 없다.
(Object 클래스는 모든 클래스이 부모 클래스이자만 <Object>와 <Integer>, <String>등은 서로 상속 관계가 아닌 완전히 별개이다.)
이 때 함수 앞에 <T>를 선언하지 않아도 제네릭을 파라미터로 받을 수 있게 하는 것이 와일드 카드 <?>이다.
와일드 카드의 형태는 아래와 같다.
public static void peekBox(Box<?> box) {
} // Box<Integer>의 인스턴스, Box<String>의 인스턴스를 인자로 전달 가능
제네릭 메소드와 와일드 카드는 형태만 다를 뿐 기능적으로는 완전히 동일하다. 다만 와일드 카드를 사용할 경우 코드가 좀 더 간결해 지는 장점이 있다.
4. 아래가 에러나는 이유를 설명하시오.
class Box<T> {
private T ob;
public void set(T o) { ob = o; }
public get() { return ob; }
}
public static void inBox(Box<? super Toy> box, Toy n) {
box.set(n); // 넣는 것! OK!
Toy myToy = box.get(); // 꺼내는 것! Error!
}
super Toy는 Toy 클래스의 부모 클래스만 온다는 뜻이다.(하한 제한)
따라서 Toy myToy = box.get(); 의 경우 자식 = 부모를 해준 것과 같다.
부모에는 자식의 내용물(메소드, 인스턴스 등)이 없기 때문에 부모 것을 꺼내서 자식에게 넣을 수가 없다.
반대로 extends의 경우
public static void outBox(Box<? extends Toy> box) {
box.get(); // 꺼내는 것! OK!
box.set(new Toy()); // 넣는 것! ERROR!
}
Toy 클래스를 상속받는 자식 클래스만 온다는 뜻이다.(상한 제한)
ex)Car car = new Toy();자식 = 부모이기때문에 폴리몰티즘 적용이 되지 않아 오류.....
super는 set만
extends는 get만
5. 아래의 소스코드 중에 System.out.println(zBox.get().get().get()); 부분을 설명하시오.
class Box<T> {
private T ob;
public void set(T o) {
ob = o;
}
public T get() {
return ob;
}
}
public class BoxInBox {
public static void main(String[] args) {
Box<String> sBox = new Box<>();
sBox.set("I am so happy.");
Box<Box<String>> wBox = new Box<>();
wBox.set(sBox);
Box<Box<Box<String>>> zBox = new Box<>();
zBox.set(wBox);
System.out.println(zBox.get().get().get());
}
}
위의 코드의 경우 출력 값이 I am so happy.이다.
zBox.get().get().get()
→ wBox.get().get()
→ sBox.get()
와 같기 때문에 결국 sBox.get()으로 호출된 값이 출력되게 된다.
6. 아래를 컴파일 에러가 나지 않게끔 프로그래밍 하시오.
public static void main(String[] args) {
Box7<Integer> box1 = new Box7<>();
box1.set(99);
Box7<Integer> box2 = new Box7<>();
box2.set(55);
System.out.println(box1.get() + " & " + box2.get());
swapBox(box1, box2);
System.out.println(box1.get() + " & " + box2.get());
}
출력 =========================================
99 & 55
55 & 99
class Box7<T>{
private T ob;
public void set(T ob) {
this.ob = ob;
}
public T get() {
return ob;
}
}
class GenericPrac2 {
public static <T> void swapBox(Box7<T> box1, Box7<T> box2) {
/*
T ob1 = box1.get(); // 오토 박싱?
T ob2 = box2.get();
box1.set(ob2);
box2.set(ob1);
*/
T ob = box1.get();
box1.set(box2.get());
box2.set(ob);
// 정석 스왑 방식
}
public static void main(String[] args) {
Box7<Integer> box1 = new Box7<>();
box1.set(99);
Box7<Integer> box2 = new Box7<>();
box2.set(55);
System.out.println(box1.get() + " & " + box2.get());
swapBox(box1, box2);
System.out.println(box1.get() + " & " + box2.get());
}
}
//99 & 55
//55 & 99
스왑 방식은 먼저 빈 공간을 만들어서 그곳에 하나를 담고 시작!
제네릭으로 바로 만들기 힘들면 일단 지정된 객체를 넣고 만든 다음 순차적으로 수정해가기.
7.Scanner를 이용하여 한 라인을 읽고, 공백으로 분리된 어절이 몇 개 들어 있는지 "그만"을 입력할 때까지 반복하는 프로그램을 작성하라.
>>I love Java.
어절 개수는 3
>>자바는 객체 지향 언어로서 매우 좋은 언어이다.
어절 개수는 7
>>그만
종료합니다...
[Hint] Scanner.nextLine()을 이용하면 빈칸을 포함하여 한 번에 한 줄을 읽을 수 있다.
(1) StringTokenizer 클래스를 이용하여 작성하라.
import java.util.Scanner;
import java.util.StringTokenizer;
class WordTest {
public static void main(String[] args) {
while (true) {
Scanner sc = new Scanner(System.in);
System.out.println("글을 입력하세요. 종료를 원하시면 " + "\"" + "그만" + "\"" + "을 입력하세요.");
System.out.print(">>");
String str = sc.nextLine();
if (str.equals("그만")) {
System.out.println("종료합니다.");
break;
}
StringTokenizer st = new StringTokenizer(str, " ");
int sum = 0;
while (st.hasMoreTokens()) {
String[] nt = { st.nextToken() };
sum += nt.length; // foreach써도 되네...?
} // while(st.hasMoreTokens())
System.out.println("어절 개수는 " + sum);
} // while(true)
}
}
이번에도.....클래스로 빼주는 건 실패......
앗...countTokens()함수가 있었다니..
try catch 써주기(사실 netLine은 대부분의 것을 다 받기 때문에 오류가 날 확률이 거의 없지만 써주는 습관 들이기)
버퍼 비우기!(sc.nextLine();)
먼저 클래스 만들고 하나의 함수에 전체를 다 넣어주기!
import java.util.Scanner;
import java.util.StringTokenizer;
class TokensCount {
private String words;
public void run() {
Scanner sc = new Scanner(System.in);
while (true) {
try {
words = sc.nextLine();
if (words.equals("그만")) {
System.out.println("종료합니다.");
break;
}
StringTokenizer tokens = new StringTokenizer(words, " ");
System.out.println("어절 갯수는 " + tokens.countTokens());
} catch (Exception e) {
System.out.println("잘못된 입력입니다. 다시 입력하세요.");
sc.nextLine();
}
} // while(true)
}
}
class WordTest {
public static void main(String[] args) {
TokensCount count = new TokensCount();
count.run();
}
}
제네릭 복습..........필수..........정리해도 무슨 소린지 모르겠다..........
input 태그
See the Pen formtag by SE (@whaletree) on CodePen.
'수업문제' 카테고리의 다른 글
[문제] 11월 8일 (ArrayList 와 LinkedList, Set, 선택자, 하이 서울 브랜드) (0) | 2021.11.08 |
---|---|
[문제] 11월 5일 (블록 태그, 인라인 태그, 선택자, ArrayList 와 LinkedList, 홀리그램) (1) | 2021.11.05 |
[문제]11월 3일 (제네릭, HTML 주간 히트송) (0) | 2021.11.03 |
[문제] 11월 2일 (equals 오버라이딩, 정렬, Arrays.sort(), Comparable) (0) | 2021.11.02 |
- Total
- Today
- Yesterday
- 진척도 70번
- Request
- exception
- 채팅
- 래퍼 클래스
- 참조형
- Generic
- hashset
- compareTo
- 입출력
- SOCKET
- 세션
- Servlet
- 쿠키
- 프로토콜
- response
- 예외처리
- object
- 쓰레드
- el
- 사칙연산 계산기
- equals
- JSP
- 제네릭
- toString
- Session
- abstract
- string
- 부트스트랩
- TreeSet
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |