*자료형 변환
1. 기본 자료형 변환 ex double <-> int
2. Wrapper Class ex 기본자료형 <-> 참조형 (int <->String)
3. 레퍼런스 형변환

***레퍼런스 형변환***
 :(=강제 타입 변환Casting) 부모 타입을 자식 타입으로 변환하는 것
  - 조건: 두개의 클래스 사이에 상속관계가 있어야 하고 (전제)
            자식 타입을 부모 타입으로 자동 변환 후 다시 자식 타입으로 변환해야 할 때.

 
업캐스팅(자동 형변환) 
   1. 서브클래스에서 슈퍼클래스로 형변환
   2. 참조 가능한 영역이 축소
   3. 컴파일러에 의해 암시적 형변환(자동 형변환) -> 강제형변환 할 필요 없음

   Parent p;
   Child c = new Child();
   p = c;  //업캐스팅(자동 형변환)
// p = (Parent) c; // 원래 이런 모양인데, 자식객체를 부모객체로 넘기는거라 자료형 변환 생략 가능 -> 암시적 형변환

   Parent p1 = (Parent)new Child();

    c.parentPrn();   //Child 객체로 부모한테 받은 메소드 당연히 호출 가능
    c.childPrn();     // 자식이 가진 메소드도 자기 거니까 당연히 호출 가능

    p.parentPrn(); -> 업캐스팅으로 자식 클래스 호출 통해서, 부모클래스 메소드(상속해준 메소드)만 호출 가능
    p.childPrn();  -> 자식 클래스의 메소드는 부모 클래스가 상속해준 메소드가 아니므로, 업캐스팅이랑 관계없이 부모클래스의 객체로 호출이 불가능! 
----> 부모 클래스 객체로 업캐스팅하면 자식클래스 객체보다 부모클래스 객체로 호출할 수 있는 메소드가 줄어든다 -> 참조 가능한 영역이 축소된다 


   * 다운 캐스팅(강제 형변환)
   1. 슈퍼클래스에서 서브클래스로 형변환
   2. 참조 가능한 영역이 확대
   3. 컴파일러에 의해서 암시적 형변환(자동 형변환) 불가 -> 자료형을 생략할 수 없다(강제 형변환)

   // Child c = (Child) new Parent();  //-> 이런식으로, Parent 클래스로 인스턴스 선언해서 Child 클래스 객체로 집어넣는 방식으로 다운캐스팅하면 오류 발생

   ↓!!!해결 방법!!!
   Parent p = new Child(); // 업캐스팅 먼저 해서 서브클래스 인스턴스 선언하고
   Child c; // 서브클래스 객체 선언
   c = (Child) p;          // 그리고 다운 캐스팅(명시적 형변환) 하면 괜찮음
 (위에 두 줄 Child c=(Child) p; 로 줄이는 건 ㄱㅊ)    순 서 가 중 요 해
 ----> 차이는 인스턴스 객체 선언을 어떻게 했느냐임
          결과적으로 다운캐스팅은 자식 클래스로 인스턴스 선언한 걸 업캐스팅으로 부모 클래스 객체에 넣었다가 다시 자식 클래스 객체로 되돌려 넘겨주는 과정인 것임
-> 어쨌든 p는 잠깐 스쳐지나갔고 결과적으로 자식 객체로 자식 인스턴스 사용한 꼴이라 Child가 상속한 메소드와 원래 가지고 있던 메소드를 모두 사용할 수 있게 됨 -> 참조 가능한 영역이 확대된다

-> 꼭 업캐스팅 시 사용한 자식클래스의 객체로 되돌릴 필요는 없고, 자식 클래스라면 어디든 돌려줄 수 있고 이 과정이 다운캐스팅! (단, heap 영역에 저장된 값과 동일한 자료형으로 돌려줘야 함)



***자료구조***
java.util.*;
Set, List, Vector, Map, Queue, Stack etc.
여러가지 자료형의 객체 값을 모두 저장할 수 있음
왜냐면 값을 입력받는 메소드의 매개변수가 Object거든 -> 업캐스팅 ㄱㄱ
배열의 확장 version -> 객체를 효율적으로 추가,삭제,검색할 수 있음
>> 배열과의 차이점 1. 여러 자료형 값을 다 받을 수 있고 2. 동적으로 크기를 늘릴 수 있음

https://www.toolsqa.com/java/data-structure/

1. Set Interface -Inhe: HashSet, TreeSet Class
순서 없이 입,출력. 중복 data 저장 불가능 -> 중복 제거해야할 때 사용할 수 있겠음

*Interator Interface
Interator e = set.iterator(); //Set의 iterator() 메소드를 인터페이스 Iterator의 객체로 할당시키고
while(elements.hasNext()) {} //Iterator의 메소드 hasNext()로 다음 값이 존재하는 경우 true-> while문으로 값 전부 가져옴


HashSet- 무작위로 출력
TreeSet- 오름차순 정렬 (1234... , abcd...) //TreeSetTest.java 참고
-> 둘 다 중복 저장 안됨 이건 Set 특징임

2. ★★List Interface -Inhe: ArrayList Class
index번호 순으로 저장되어 출력. 중복 data 저장 가능
Interface List<E>에서 <E>:제네릭, 특정 자료형만 입력하고 싶을 때 지정해줌, E는 Object라고 생각해

Collections04.java
list.add("하나");
list.add(2);
list.add(3.0);
list.add("넷");
list.add("five");

while(i<list.size())
Object obj=list.get(i); -> 이건 ㄱㅊ음
String s=(String)list.get(i); ->이건 에러남
ㄴ> list에 저장된 값의 자료형이 달라 String형으로 담을 수 없음-> 인식 ㄴ->오류!
그냥 list.get(i)으로 출력해도 되지만 다른 방법을 사용하고 싶다면
향상된 for문이나
for(Object obj:list){
s.o.p(obj);
}
Iterator반복자 를 사용하든지..
Iterator elements=list.iterator();    
while(elements.hasNext()) {
      System.out.println("\t\t" + elements.next());
}
아무튼 자료형이 달라서 String형으로 다운캐스팅은 불가능함
각 값마다 맞는 자료형으로 다운캐스팅하는건 오류 안 남 근데 이건 너무 비효율적이잖어
-> 그냥 Object형으로 묶어서 출력하는게 가장 쉽고 좋은 방법인 것.

add로 값 넣고 get으로 값 빼낸다는 걸 기억하세요
+ 원소의 개수(=리스트 개수)는 size임 

3. Vector Class (List와 같은 기능)
: index번호 순으로 저장되어 출력. 중복 data 저장 가능

4. Map Interface -Inhe: HashMap, HashTable Class
: data 저장 시 Key, Value를 동시에 저장

5.Queue Interface -Inhe: LinkedList Class
: FIFO(First In First Out:선입선출) 

6. Stack Class
: LIFO(Last In First Out:후입선출)


+ Recent posts