본문 바로가기
코딩/수업 정리

20.12.21 Mon [021]

by 6^6 2020. 12. 21.
728x90

타입매개변수

 

 

21강

 

 

21-12 다중 매개변수 기반 제네릭 클래스의 정의

바로 int이런식으로 선언 못해서 DBox<String, Integer>(참조형 데이터 타입)선언한다. - 반드시 객체로 선언해야함.

- 객체 만들었으니 set을 통해 값을 넣는다. - set메소드에서 box.set("Apple", 25); 로 들어감.

- 들어 갈 수 있는 이유는 오토박싱이 되어있기 때문에

 

 

//21-12예제
package java_1221;

public class BoxClass {

	public static void main(String[] args) {
		DBox<String, Integer> box = new DBox<String, Integer>();
		box.set("Apple", 25);
		System.out.println(box);

	}

}

class DBox<L, R> {
	private L left;
	private R right;

	public void set(L o, R r) {
		left = o;
		right = r;

	}

	@Override
	public String toString() {
		return left + " & " + right;
	}
}

 

 

 

 

21-13 타입 매개변수의 이름 규칙

 

 

21-14 기본 자료형에 대한 제한 그리고 래퍼 클래스

<int>x - 기본타입형x

<Integer>o - Wrapper 클래스 (객체)o

 

 

 

 

21-15 다이아몬드 기호

<>뒤에 생략하면 앞에거 <Apple> 따라옴 

 

 

 

 

21-16 ‘매개변수화 타입’을 ‘타입 인자’로 전달

//21-16 예제
package java_1221;

public class BoxClass {

	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());
	}
}

class Box<T> {
	private T ob;

	public void set(T o) {
		ob = o;
	}

	public T get() {
		return ob;
	}
}

 

 

21-17 제네릭 클래스의 타입 인자 제한하기

Number는 

T가 Number이거나 Number를 상속.

 

위의 코드에서는 T는 Integer나 Double만 올수 있음. - String 이런거 오면 오류뜸

 

 

인스턴스 생성 시 타입 인자로 Number 또는 이를 상속하는 클래스만 올 수 있음 
ex) class Box<T extends Number> {...} => 와 같이 Number 클래스를 상속하면 기본형으로 타입을 제한-String, Apple과 같은 타입은 들어오지 못함

 

 

 

21-18 타입 인자 제한의 효과

왜 <T extends Number>이렇게 제한할까? ob.intValue();를 호출해주는 게 목적. .intValueNumber에 있다.

근데 Number상속하지 않은 코드에서는 실수로 ob.을 붙여서 에러남.

객체 안에있는 함수를 호출하려면  반드신 extends Number처럼 함수을 제한시켜야한다.

 

 

 

 

21-19 제네릭 클래스의 타입 인자를 인터페이스로 제한하기

T (=ob)가 제한되어야함. Eatable로 제한해줌.

 

 

 

상위 타입은 클래스 뿐만 아니라 인터페이스도 가능하다. 인터페이스라고 해서 extends 대신 implements를 사용하지 않는다.

(출처: https://ict-nroo.tistory.com/42 [개발자의 기록습관])

 

//21-19 예제
package java_1221;

interface Eatable {
	public String eat();
}

class Apple implements Eatable {
	public String toString() {
		return "I am an apple.";
	}

	@Override
	public String eat() {
		return "It tastes so good!";
	}
}

class Box<T extends Eatable> {
//class Box<T extends Apple> { -상관x Apple상속받은것이기 때문
	private T ob;

	public void set(T o) {
		ob = o;
	}

//한 입 먹고 반환하는 행위의 메소드로 수정
	public T get() {
		System.out.println(ob.eat());
		return ob;
	}

}

class BoundedInterfaceBox {
	public static void main(String[] args) {
		Box<Apple> box = new Box<>();
		box.set(new Apple());

		Apple ap = box.get();
		System.out.println(ap);
	}
}

T는 전부 Apple 이 된다. - 형변환없이 꺼낸다는게 장점

 

 

 

 

21-20 하나의 클래스와 하나의 인터페이스에 대해 동시 제한

 

제네릭 타입에서만 class Name<T extends A & B>{ } 이런식으로 사용 가능

 

 

 

21-21 제네릭 메소드의 정의 - 여기서 어렵. 이해안되면 일단 이해하지말기

 

public static = 이미 배운것

<T> = 제네릭 메소드 라고 알려주는것. (함수앞에 꺽쇠오면 제네릭메소드다)

Box<T> = 리턴타입

 

class BoxFactory <T>{} 이렇게 T가오면 클래스전체에 T가 온다는것.

public static <T> : 이 함수에서만 써먹겠다 - 근데 써먹는거 없음. 걍 제네릭 메소드라는 걸 알려주려고 하는것.

 

그 다음 오는 Box<T>가  다음에 오는 Box<T>와 box에 영향을 줌.

 

 

 

 

 

 

 

21-22 제네릭 메소드의 제한된 타입 매개변수 선언

//21-22 예제
class Box<T> {
	private T ob;

	public void set(T o) {
		ob = o;
	}

	public T get() {
		return ob;
	}
}

class BoxFactory{

	public static <T> Box<T> makeBox(T o) {
		Box<T> box = new Box<T>();
		box.set(o);
		return box;
	}
}

class GenericMethodBoxMaker {
	public static void main(String[] args) {
		Box<String> sBox = BoxFactory.makeBox("Sweet");
		System.out.println(sBox.get());

		Box<Double> dBox = BoxFactory.makeBox(7.59);
		System.out.println(dBox.get());
	}
}

 

 

 

 

 

 

 

22강

- 현업에서도 여기까지 모르는사람들 많음. 모르겠으면 일단 패스~~

 

22-3 제네릭 클래스와 상속

(상속이 안되면 다형성이 안되기때문)

 

 SteelBox<Integer>는 왜 Box<String>을 상속할 수 없을까? 문법적으로 맞지도않고 안에 내용물이 일단 다르다.

(상속관계에서도 일단 맞아야함.)

 

 

 

 

 

 

 

22-4 타겟 타입 - 현업에서도 잘 알지못함.

...?

 

 

 

 

 

 

22-5 와일드카드의 설명에 앞서(제네릭 메소드 vs. 일반 메소드)

상속관계가 되려면 부모에있는 데이터멤버와 함수를 그대로 올려놓고 갖다 써야하는데 String으로 체인지해서 들어가면 상속자체가 안된다.

따라서 매개변수에 Object는 들어갈 수 없다.

 

 

 

 

22-6 와일드카드 - 제네릭하고는 또 다르지만 똑같은 문법

<?> = 와일드 카드 : 마땅한 번역이 없음. 걍 와일드카드라고함.

Object랑 비슷한 기능함. <T> 붙으나 <?> 붙으나 기능은 똑같은데 <?>은 인스턴스 맘대로 넣을 수 있다.

 

 

 

22-7

<T>문법상으론 더 복잡해져서 <?>이걸 쓰는걸 더 권고함!

 

 

 

22-8  와일드 카드의 상한과 하한의 제한: Bounded Wildcards

 

 

 

22-9 상한 제한된 와일드카드(Upper-Bounded Wildcards)

와일드카드에다가 extends 준것.

Number를 상속한 것.

 

 

 

22-10 하한 제한된 와일드카드(Lower-Bounded Wildcards)

super Integer 안헷갈리는 해석 : Integer위에 있는것

 

 

 

 

22-11 와일드카드 제한의 이유 설명을 위한 도입

 

22-12 상한 제한의 목적

//22-12
class Box<T> {
	private T ob;

	public void set(T o) {
		ob = o;
	}

	public T get() {
		return ob;
	}
}

class Toy {
	@Override
	public String toString() {
		return "I am a Toy";
	}
}

class BoxHandler {
	public static void outBox(Box<? extends Toy> box) {
		Toy t = box.get(); // 박스에서 꺼내기
		// box.set(new Toy());-★오류남-why?다형성때문에.-왜 오류나는지 꼭알기
		System.out.println(t);

	}

	public static void inBox(Box<? super Toy> box, Toy n) {
		box.set(n); // 박스에 넣기
	}
}

class BoundedWildcardUsage2 {
	public static void main(String[] args) {
		Box<Toy> box = new Box<>();
		BoxHandler.inBox(box, new Toy());
		BoxHandler.outBox(box);
	}
}

 

 

22-13

 

 

22-14

Toy부모는 Plastic

 

 

 

 

22-15

 

 

 

 

22-16 상한 제한과 하한 제한의 좋은 예 하나!

----------------여기까지만 이해해도 괜춘

 

 

22-17

 

 

22-18 다음 형태로 메소드 오버로딩 불가능하다

제내릭 안에있는 매개변수 타입에 대해서는 오버로딩이 안된다.

, 찍고 매개변수 한개 더 적어주면 된다.

 

 

22-19 그래서 와일드 카드 선언을 갖는 메소드를 제네릭으로

와일드 카드와 제네릭을 섞음.

 

===============여기까지 활용도필요없음 이해까지만이라도 하면 됨.==================

 

 

22-20 제네릭 인터페이스의 정의와 구현

 

interface Getable<T> {
	public T get();
}

//졸아서 코드 오류남
class Box<T> implements Getable<T> {
	private T ob;

	public void set(T o) {

	}

	ob=o;

}

	@Override
	public T et() {
		return ob;
	}

	class Toy {
		@Override
		public String toString() {
			return "Im a Toy";
		}
	}

class BoundedWildcardUsage2 {
	public static void main(String[] args) {
Box<Toy> box = new Box();
box.set(new Toy());

Getable<Toy> gt = box;
System.out.println(gt.get());
	}
}

 

23강 프레임워크

 

23-3  컬렉션 프레임워크 - 컴공과학생들이 차이있음

4가지-반드시 외우기

Set, List, Queue(상속받는 3개),  Map    셀리큐맵

 

 

컬렉션프레임워크란?? 자료구조, 알고리즘을 구현해놓은 일종의 라이브러리.

 

 

 

 

23-5 List 인터페이스 -중요

List - 걍 1번2번3번4번 차례로 오는 개념

중복저장을 허용한다.

//23-5 그림 예제
package java_1222;

class Link {
	int num; // object해서 객체로 받아도 상관x
	Link link; //자기자신x
}

public class aaaa {

	public static void main(String[] args) {
		Link link1 = new Link();
		link1.num = 3;
		
		Link link2 = new Link();
		link2.num = 5;
		link1.link = link2; //그림의 예제임.

	}

}

 

 

23-6 ArrayList 클래스

캡슐화가 잘되어있다.

배열안쓰고 ArrayList같은걸로 씀

결국 ArrayList는 배열이랑 똑같은 것임. 배열로 관리한다.

 

 

List에다가 <String>(제네릭으로 선언) 넣고 new 객체 생성

list.add()하게 되면 넣는것, 이걸 꺼내는 방법은 list.get으로 꺼낸다.

 

그리고 그 배열을 지우고싶으면 list.remove를 쓰면된다.

그럼 다음 배열이 알아서 0번째로 옮겨간다.

 

.

 

//23-6 예제
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class BoundedWildcardUsage2 {
	public static void main(String[] args) {
		List<String> list = new ArrayList<>(); // 유일한 변화!!!
		// 컬렉션 인스턴스에 문자열 인스턴스 저장
		list.add("Toy");
		list.add("Box");
		list.add("Robot");
		// 저장된 문자열 인스턴스의 참조
		for (int i = 0; i < list.size(); i++)
			System.out.print(list.get(i) + '\t');
		System.out.println();
		list.remove(0); // 첫 번째 인스턴스 삭제
		// 첫 번째 인스턴스 삭제 후 나머지 인스턴스들을 참조
		for (int i = 0; i < list.size(); i++)
			System.out.print(list.get(i) + '\t');
		System.out.println();
	}
}//Toy	Box	Robot	
//Box	Robot	

 

 

 

 

 

23-7 LinkedList 클래스

배열은 연속된 공간이다. LinkedList연속된 공간이 아니다.

유일한 변화있음

다형성, 함수오버라이딩

 

//23-7 예제
import java.util.LinkedList;
import java.util.List;

public class BoundedWildcardUsage2 {
	public static void main(String[] args) {
		List<String> list = new LinkedList<>(); // 유일한 변화!!!
		// 컬렉션 인스턴스에 문자열 인스턴스 저장
		list.add("Toy");
		list.add("Box");
		list.add("Robot");
		// 저장된 문자열 인스턴스의 참조
		for (int i = 0; i < list.size(); i++)
			System.out.print(list.get(i) + '\t');
		System.out.println();
		list.remove(0); // 첫 번째 인스턴스 삭제
		// 첫 번째 인스턴스 삭제 후 나머지 인스턴스들을 참조
		for (int i = 0; i < list.size(); i++)
			System.out.print(list.get(i) + '\t');
		System.out.println();
	}
}//Toy	Box	Robot	
//Box	Robot	

 

 

 

**LinkedList랑 ArrayList를 쓰는게 실력차이가 난다

23-8 ArrayList<E> vs. LinkedList<E>

 

ArrayList 는 배열을 한번 복사하는데도 시간걸림, 지우는것도 시간 걸림 - 배열의 단점 그대로.(단점)

검색(=참조)은 빠르다. 다이렉트로 찾아감(장점)

 

LinkedList 는 검색은 느리다.(단점)

저장공간은 객체를 하나씩 늘리기때문에 과정이 간단.(장점)

 

---장단점 잘 생각해서 둘 중 하나로 쓰면 됨!

 

 

 

 

 

 

오늘의 문제

1.제네릭 클래스의 타입 인자 제한하는 방법과 효과는?
: super 나 extends 예약어를 넣어줘서 해당클래스이거나 상속을 받는(or 하는) 애들로만 제한 할 수 있어 오류를 잡을 수 있다. 

//다른분 예시
class Box <T extends Number> { // Number 혹은 Number에게 상속 받는 클래스들에게만 대상
    private T ob;
    
    public int toValue() {
        return ob.intValue(); // Number에 있는 메소드를 호출하기 위함!
    }
}



2.아래와 같이 출력값이 나오도록 프로그래밍 하시오.

class DDBoxDemo {
    public static void main(String[] args) {
        DBox<String, Integer> box1 = new DBox<>();
        box1.set("Apple", 25);

        DBox<String, Integer> box2 = new DBox<>();
        box2.set("Orange", 33);
        
        DDBox<DBox<String, Integer>, DBox<String, Integer>> ddbox = new DDBox<>();
        ddbox.set(box1, box2);

        System.out.println(ddbox);
    }
}

==================
Apple & 25
Orange & 33
class DDBoxDemo {
	public static void main(String[] args) {
		DBox<String, Integer> box1 = new DBox<>();
		box1.set("Apple", 25);

		DBox<String, Integer> box2 = new DBox<>();
		box2.set("Orange", 33);

		DDBox<DBox<String, Integer>, DBox<String, Integer>> ddbox = new DDBox<>();
		ddbox.set(box1, box2);

		System.out.println(ddbox);
	}
}

class DDBox<F, A> {
	protected F fruit;
	protected A age;

	public void set(F f, A a) {
		fruit = f;
		age = a;
	}

	@Override
	public String toString() {
		return fruit + " & " + age + "\n";

	}

}

class DBox<F, A> extends DDBox<F, A> {
	public void set(F f, A a) {
		fruit = f;
		age = a;
	}

	public F getFruit() {
		return fruit;
	}

	public void setFruit(F fruit) {
		this.fruit = fruit;
	}

	public A getAge() {
		return age;
	}

	public void setAge(A age) {
		this.age = age;
	}

}
//Apple & 25
// & Orange & 33
//오류 &이 한번 더 출력

 

 

 

 

 

3.아래와 같이 출력값이 나오도록 프로그래밍 하시오.

    public static void main(String[] args) {
        Box<Integer> box1 = new Box<>();
        box1.set(99);

        Box<Integer> box2 = new Box<>();
        box2.set(55);

        System.out.println(box1.get() + " & " + box2.get());
        swapBox(box1, box2);
        System.out.println(box1.get() + " & " + box2.get());
    }
==========
99 & 55
55 & 99
public class NumMain {

	public static void main(String[] args) {
		Box<Integer> box1 = new Box<>();
		box1.set(99);

		Box<Integer> box2 = new Box<>();
		box2.set(55);

		System.out.println(box1.get() + " & " + box2.get());
		swapBox(box1, box2);
		System.out.println(box1.get() + " & " + box2.get());
	}

	private static void swapBox(Box<Integer> box1, Box<Integer> box2) {

	}
}

class Box<T> {
	private T inte;

	public void set(T t) {
		inte = t;

	}

	public T get() {

		return inte;
	}

}
//==========
//99 & 55
//55 & 99

오류
//99 & 55
99 & 55

↓문제풀이

 

//???
package java_1222;

class QuizMain {
	private static <T extends Number> void swapBox(Box<T> box1, Box<T> box2) {
//		int temp = box1.get();
//		box1.set(box1.get());
//		box1.set(temp);

		T temp = box1.get();
		box1.set(box2.get());
		box2.set(temp);
	}

}

public class NumMain {

	public static void main(String[] args) {
		Box<Integer> box1 = new Box<>();
		box1.set(99);

		Box<Integer> box2 = new Box<>();
		box2.set(55);

		System.out.println(box1.get() + " & " + box2.get());
		swapBox(box1, box2);
		/*
		 * 원래는 int a = 1; int b = 2; temp = a; a = b; b = temp; 이렇게 바꿈 - 이걸 구현
		 */
		System.out.println(box1.get() + " & " + box2.get());
	}

	private static void swapBox(Box<Integer> box1, Box<Integer> box2) {

	}
}

class Box<T> {
	private T obj;

	public void set(T obj) {
		this.obj = obj;

	}

	public T get() {

		return obj;
	}

}

 

4. 지네릭 메소드에 대하여 설명하시오.
: public static <T> 에서 <T>는 제네릭 메소드 라고 알려주는것이다. (함수앞에 꺽쇠오면 제네릭메소드다)


5. 와일드 카드와 상한 제한, 하한 제한에 대하여 설명하시오. *참고 vvshinevv.tistory.com/56 
 - 상한 제한

ex. public static void PaperBox(Paper<? extends Box> box){ }

위 코드에서 ?는 와일드카드 이므로 어떤 타입이 와도 상관 없다. 근데  extends Box로 예약어를 걸어둠으로서 Box이거나 Box를 상속하는 클래스만 와라 라고 제한을 걸어두었다. (=Box위에 Object는 올 수 없음) = 상한제한

 

- 하한 제한

ex. public static void PaperBox(Paper<? super Box> box){ }

위 코드에서 ?는 와일드카드이므로 box 파라미터 변수에 어떤 타입을 전달 받아도 상관없다. 근데 super Box로 예약어를 걸어두어 Box이거나 Box가 상속하는 클래스만 와라 라고 제한을 걸어두었다. (=Box아래에 있는 Double, Integer, Long 은 올 수 없음) = 하한제한

 

 

6. 아래가 에러가 나는 이유를 설명하시오.

public static void inBox(Box<? super Toy> box, Toy n) {
   box.set(n);   // 넣는 것! OK!
   Toy myToy = box.get();   // 꺼내는 것! Error!
}

super Toy 하한제한 예약어를 줌으로서 box 인스턴스에 넣는 것은 가능하고 box 인스턴스에 꺼내는 것은 불가능
Toy 는 자식클래스인데 box.get();을 해주게 되면 자식클래스에있는 인스턴스를 꺼내게될지 부모클래스에 있는 인스턴스를 꺼내게될지 모르기때문에 에러가 난다.

 

 

 

7. 아래와 같이 메소드 오버로딩이 되지 않는 이유는?

   // 다음 두 메소드는 오버로딩 인정 안됨.
   public static void outBox(Box<? extends Toy> box) {...}
   public static void outBox(Box<? extends Robot> box) {...}

제내릭 안에있는 매개변수 타입에 대해서는 오버로딩이 안된다. - 컴파일 과정에서 내용이 지워지기 때문에
 

오버로딩 시키려면  → , 찍고 매개변수 한개 더 적어주면 된다.

(Box<? super Toy> box, Toy t){ }

(Box<? super Robot> box, Robot r){ }

 

 

 


8. 아래의 결과가 나오도록 프로그래밍을 완성하시오.

 public static void main(String[] args) {
        Box<Integer> box1 = new Box<>();
        box1.set(24);

        Box<String> box2 = new Box<>();
        box2.set("Poly");

        if(compBox(box1, 25))
            System.out.println("상자 안에 25 저장");

        if(compBox(box2, "Moly"))
            System.out.println("상자 안에 Moly 저장");
        
        System.out.println(box1.get());
        System.out.println(box2.get());
    }

=======
24
Poly

:
public class PolyMolyMain {

	public static void main(String[] args) {
		Box<Integer> box1 = new Box<>();
		box1.set(24);

		Box<String> box2 = new Box<>();
		box2.set("Poly");

		if (compBox(box1, 25))
			System.out.println("상자 안에 25 저장");

		if (compBox(box2, "Moly"))
			System.out.println("상자 안에 Moly 저장");

		System.out.println(box1.get());
		System.out.println(box2.get());
	}

	private static boolean compBox(Box<Integer> box1, int i) {

		return false;
	}

	private static boolean compBox(Box<String> box2, String string) {

		return false;
	}
}//24
//Poly

 


9. 콜렉션 프레임워크란?

Set List Queue Map 셀리큐맵!
: 자료구조, 알고리즘을 구현해놓은 일종의 라이브러리이다.

 

Set< E >

(현재배운것)List< E >: 인스턴스의 저장 순서를 유지하고 동일 인스턴스의 중복 저장을 허용할 수 있다.

  -ArrayList< E >: 배열 기반 자료구조로 배열을 이용하여 인스턴스에 저장한다.

  -LinkedList< E >: 리스트 기반 자료구조로 리스트를 구성하여 인스턴스에 저장한다.

Queue< E >

Map<K, V>

 

728x90

'코딩 > 수업 정리' 카테고리의 다른 글

20.12.24 Thu [024] JSP  (0) 2020.12.24
20.12.22 Tue [022]  (0) 2020.12.22
20.12.18 Fri [020]  (0) 2020.12.18
20.12.17 Thu [019]  (0) 2020.12.17
20.12.16 Wed [018] 예외처리, 가상머신  (0) 2020.12.16

댓글