Java TPC Part-2

박철현·2023년 10월 8일

Java

목록 보기
6/13

수평적구조vs수직적구조

  • 수평적 설계
    ex) 개(먹다, 이름, 나이, ..), 고양이(먹다, 이름, 나이,..)

    • 코드의 중복 발생
    • 새로운 요구사항에 대한 코드 수정 불가피
      • 변수 하나 추가하면 여러 클래스에 다 추가해야 함
    • 관리 어려움
  • 수직적 설계(계층화, 상속구조)

    • 수평적 설계의 단점을 극복할 수 있다.
    • 확장을 쉽게할 수 있다.(부모의 기능 물려받음)
    • 코드가 복잡해진다.(이점이 많다)
    • super class(상위, 부모)
      • 추상화, 보편화, 일반화, 개념화
    • sub class(하위, 자식)
      • 세분화, 상세화, 구체화, 구상화
    // 모든 클래스는 Object 클래스를 기본으로 상속 받음
    public clss Animal extends Object {
    	public String name;
      public int age;
      public String part;
      
      public void eat() {
      	System.out.println("?"); // 포괄적, 추상적
      }
     	public Animal() {
      	super();
      }
    }
    
    public class Dog extends Animal {
    	public void eat() {
      	System.out.prinln("게 처럼 먹다.");
      }
      public Dog() {
     		super(); // new Animal(); 실행, 생략해도 컴파일러가 자동으로 넣어 줌
          // 객체는 부모가 만들어 지고 자식이 만들어져야 함
      }
    }
    
    public class Cat extends Animal {
    	public void eat() {
      	System.out.prinln("고양이 처럼 먹다.");
      }
      public Cat() {
     		super(); // new Animal(); 실행
      }
    }
    • Object -> Animal -> Dog or Cat 순서로 생성됨
      • 상속 체이닝

재정의(Override)

  • 상속받은 하위 클래스가 상위 클래스의 동작을 수정하는 것

    • 부모와 자식 메서드가 공존하지만 결국 자식메서드가 실행된다
  • 동적바인딩 : 호출될 메서드가 실행 시점에 결정되는 바인딩
    ex) animal의 eat() 메서드 / Dog의 eat()메서드 => Dog꺼

    • 컴파일 시점에서 Animal의 eat() -> 컴파일 시점에 자식 찾아서 Dog의 eat() 실행
    • 하위 클래스의 동작 방식을 모르더라도 부모 클래스의 메서드로 실행시킬 수 있다.
  • 자동형변환 : 부모 = 자식(하위 클래스의 타입이 상위 클래스에 들어가는 것, 프로모션, object casting)

    • upcasting이 자동으로 됨
    • downcasting은 부모 -> 자식 / (자식)부모 형태
      • (Cat)ani 이런 형태
    // Dog의 모든 동작을 알고있을 때
    Dog d = new Dog();
    d.eat();
    
    // Dog 클래스의 동작을 모를 때, 부모 클래스로 생성해서 호출
    Animal d = new Dog(); // upcasting(자식 타입을 부모가 받는 것)
    // 부모 클래스는 하위 클래스가 재정의한지 찾아보고 재정의한 메서드를 참조하게 되어있음
    // Dog의 기능을 모르더라도 부모의 타입으로 Dog가 가지고 있는 eat()를 실행시킬 수 있음
    // 실행할 때 메서드 찾아감(동적 바인딩)
    d.eat();
    public class Dog extends Animal {
    
    public void eat() {
    	System.out.printlm("개처럼 먹다.");
      }
    }
    
    public class Cat extends Animal {
    
    	public void eat() {
    		System.out.printlm("고양이처럼 먹다.");
      }
    }
    
    Animal ani = new Dog();
    ani.eat(); // "개처럼 먹다"로 출력됨
    
    ani = new Cat();
    ani.eat(); // "고양이 처럼 먹다"로 출력됨

나보다 부모가 먼저야!

  Animal d = new Dog(); // 간접
  Dog d = new Dog(); // 직접, super(); 생략되어있음
  • 상속관계에서 객체생성 방법
  • 리모콘 - tv : tv 구체적 동작 몰라도 리모콘으로 TV 구동 가능
    • 리모콘 : 인터페이스 역할
    • 하위 클래스의 구체적 동작 방식을 모르는 경우가 많기 때문에 부모 클래스를 활용하는 경우가 많음
    • 하위 클래스에서 오버라이드 해둔 메서드가 있다면, 부모 타입에서 접근할 수 있음
    • 하위 클래스를 몰라도 재정의된 메서드를 통해 하위 타입을 구동할 수 있음
public class Main {
	public static void main(String[] args) {
		Animal a = new Dog(); // upcasting
		a.eat(); // "456" 출력, Animal 갔다가, Dog에 오버라이드 메서드 있어서 자식으로 실행(동적 바인딩)
        
        Animal c = new Cat();
        ((Cat) c).night(); // downcasting, Animal에 있는 메서드가 아닌 Cat의 고유 기능이므로, 접근 불가능 하니 다운캐스팅 필요
        // "." 연산자가 캐스팅연산자 보다 우선순위가 높아서 괄호 처리 해야함
	}
}

class Animal (extends Object){
	public void eat() {
		System.out.println("123");
	}
    
     // (기본 생성자)
    public Animal() {
    	super(); // new Object();
    }
}

class Dog extends Animal {
	// @Override시 부모 클래스로 해당 함수를 검색하는데
	// 부모클레스에 해당 함수 이름이 없으면 에러
	@Override
	public void eat() {
		System.out.println("456");
	}
    // 기본 생성자
    public Dog() {
    	super(); // new Animal();
    }
}

class Cat extends Animal {
	@Override
	public void eat() {
		System.out.println("789");
	}
    
    public void night() {
    	System.out.println("밤에 눈에서 빛이난다.");
    }
}
	
  • 다형성 : 상위 클래스가 하위 클래스에게 동일한 메서드를 보내면 하위클래스가 서로 다르게 반응하는 것
    • 상속 관계에서 업캐스팅 형태로 객체를 생성하면 다형성 적용 가능

부모 자식간 형변환이 된다!

  • Object Casting(객체 형변환) : 상속관계에 있는 클래스들 간의 형(DataType)을 바꾸는 것

    • Upcasting(자동 형변환) : 하위에서 상위로 변경
    Animal r = new Dog();
    		r = new Cat();
    • Downcasting(강제형변환) : 업캐스팅 후에 강제로 하위로 변경
    Dog g = (Dog) r;
    Cat c = (Cat) r;
    
    Animal r = new Cat();
    Cat c = (Cat)r; // downcasting
    c.night();
  • 다형성 : 상위 클래스가 하위 클래스에게 동일한 메세지로 서로 다르게 동작시키는 원리

리모콘 너무 좋은데(다형성 이론)

  • 다형성(message polymorphism) : 상속관계에 있는 클래스에서 상위클래스가 동일한 메시지로 하위클래스들을 서로 다르게 동작시키는 객체지향 원리
    • Override가 전제 조건
    • 부모 타입에서 Override를 통해 하위 클래스 접근

너무 좋아 좋아! 다형성의 활용

  • 다형성 이론의 전제조건(부모 클래스를 잘 활용하라)
    • 상속관계가 되어야 한다.
    • 객체생성을 upcasting으로 할 것(상위클래스가 하위 클래스에게 메세지를 보내야 하므로)
      • upcasting이 되면 downcasting해야 한다.
    • 동적 바인딩을 통해 실행된다.
      (실핼 시점에 사용될 메서드가 결정되는 바인딩, 프로그램의 속도를 떨어트리는 원인이 된다.)
      • 속도가 떨어져도 이점이 훨씬 많기 때문에 사용
  • 다형성 인수(데이터 이동)
Dog d = new Dog();
display(d);
Cat c = new Cat();
display(c);

// display 메서드를 하나로 만들기 위해 상위클래스를 받는 메서드 구현
// 만일 따로 만들면 Cat, Dog 받는 2개의 메서드 정의 필요
// 동물이 더 많아지면 메서드도 많아져야 하는 불편함
public static void display(Animal r) {
// Animal r : 다형성 인수(하위 클래스를 받을 수 있다)
// 업캐스팅
	r.eat();
    // instanceof 메서드로 다운캐스팅 할 때를 지정 가능
    if(r instanceof Cat) {
    	((Cat)r).night();
    }
}
  • 다형성 배열(서로 다른 객체를 담을 수 있다.)
    • 서로 다른 하위클래스를 담을 수 있다.
  Animal[ ] r = new Animal[2];
  r[0] = new Dog();
  r[1] = new Cat();

// 오버라이드 되어있어서 다운 캐스팅 없이도 갈 수 있음
  r[0].eat();
  r[1].eat();
  ((Cat)r[1]).night(); // 오버라이딩 안된 메서드는 형변환을 통해 하위 클래스 메서드 사용 가능

추상클래스(일부 다형성 보장)

  • 다형성 보장 : 상위 클래스에서 명령 내리면 반드시 동작 하는것을 보장
  • 하위 클래스에서 상위 클래스의 메서드를 재정의를 함 -> 부모 클래스의 메서드는 동작을 안하는 셈 -> 메서드의 구현부를 없애도 됨
public void eat() {
	System.out.println("?");
}
// 추상 메서드 -> 구현부가 없음
// 추상 메서드를 하나라도 가지면 추상 클래스라 함
// 불완전한 메서드
public abstract void eat();
  • 추상클래스(불완전한 객체) : 추상 메서드 + 구현 메서드(없을 수도 있음)

    • 객체를 생성할 수 없음(불완전 메서드가 있기에 불완전하여 생성할 수 없음)
    • 구현 불가, 상속만 가능
    • 하위클래스가 추상 메서드를 반드시 구현하여 다형성을 보장하기 위함
    public abstract class Animal {
    	public abstract void eat(); // 추상메서드
          public void move() { // 구현메서드
      	    System.out.println("무리를 지어서 이동한다.");
          }
    }
  • 추상 메서드는 하위 클래스가 반드시 재정의 해야한다.

    • 하지 않으면 하위 클래스에서 추상 메서드 자체를 받으니 객체를 생성할 수 없으니깐!
  • 추상 클래스는 부모 역할 가능 -> 다형성 보장 가능

    public abstract class Animal {
      // 추상 메서드...
    }
    
    public class Dog extends Animal {
    	// 추상 메서드를 반드시 구현
      }
    public class Cat extends Animal {
    	// 추상 메서드를 반드시 구현
      }
      
    Animal r1 = new Dog();
    		r1.eat();  // 재정의가 반드시 되어있으니 동작 가능
    Animal r2 = new Cat();
    		r2.eat(); // 재정의가 반드시 되어있으니 동작 가능
  • 서로 기능이 비슷한 클래스를 묶음 -> 자연스럽게 추상 클래스가 많이 등장하게 됨

  • 부모에게 있는 구현 메서드는 자식에서 재정의 하지 않아도 사용 가능

    • 자식에게 들어가도 이상이 없도록 설계하는 것이 일반적
    • move 메서드(움직임)은 고양이나 개에도 적용되니 이상이 없음
    • 추상 클래스는 일부만 다형성 보장(구현 메서드는 공통의 코드여야 하니깐)
  • 인터페이스 : 서로 기능이 다른 클래스를 묶을때 사용하는 클래스

    • 100% 다형성 보장
    • 구현 메서드는 사용할 수 없고 100% 추상메서드만 사용 가능
      • 하위 클래스가 모든 메서드를 구현해야 함

인터페이스(100% 다형성 보장)

  • 인터페이스 : 100% 추상메서드만 가능, 구현된 메서드를 가질 수 없다.

    • 인터페이스에 상수 사용할 수 있음
    • 서로 기능이 다른 클래스 공통으로 묶을 수 있음
    • 리모콘 - TV, Radio
    public interface RemoCon {
    	// 인터페이스에 변수 넣으면 자동으로 상수 취급
      // 괄호 부분을 안적어도 동일
    	public (static final) int MAXCH = 100;
    	public abstract void chUp();
      public void chDown();
      public abstract void internet();
     // 구현 메서드 가질 수 x
     public void internet() {
      	System.out.println("123");
      }
    }
    
    public class TV implements RemoCon {
    	public void chUp() {
      	System.out.println("TV 채널이 올라간다.");
      }
      public void chDown() {
      	System.out.println("TV 채널이 내려간다.");
      }
       public void internet() {
      	System.out.println("인터넷이 된다.");
      }
    }
    
      public class Radio implements RemoCon {
    	public void chUp() {
      	System.out.println("Radio 채널이 올라간다.");
      }
      public void chDown() {
      	System.out.println("Radio 채널이 내려간다.");
      }
       public void internet() {
      	System.out.println("인터넷이 지원되지 않는다.");
      }
    }
    
    RemoCon r1 = new TV();
    r1.chUP();
    r1.chDown();
    r1.internet();
    
    RemoCon r2 = new Radio();
    r2.chUp();
    r2.chDown();
    r2.internet();
  • 인터페이스의 동작 방식을 알면 실제 핵심 클래스를 몰라도 동작시킬 수 있음

  • 단독적 객체 생성 불가

부모가 있어서 너무 좋아!

  • 추상 클래스

    • 구현 메서드를 가질 수 있다
    • 서로 기능이 비슷한 클래스의 공통부분을 묶을 때 사용
  • 인터페이스

    • 서로 기능이 다른 클래스의 공통부분을 묶을 때 사용
    • 100% 추상 메서드로 이루어진다.
    • 다중상속 형태를 지원한다.
    • final static 멤버변수를 가질 수 있다.
    
     public class TV implements RemoCon {
     int curCh = 1;
    	public void chUp() {
      	// 인터페이스에 정의된 static 변수 사용 가능
      	if(curCh < Remocon.MAXCH) {
          	curCh++;
      		System.out.println("TV 채널이 올라간다.");
          }
      }
      public void chDown() {
      	System.out.println("TV 채널이 내려간다.");
      }
       public void internet() {
      	System.out.println("인터넷이 된다.");
      }
    }
    
    Remocon.MAXCH

인터페이스와 JDBC의 관계

  • JDBC 프로그램 : 자바, DB연결 프로그래밍
  • DB벤더(공급자) 별로 DB 접속방법, CRUD 동작방법이 다르다.
  • 벤더에서 제공하는 클래스가 통일되어 있지 않으면 자바 개발자들은 모든 데이터베이스의 동작을 알고 있어야 JDBC 프로그래밍이 가능하다
    • 사실상 불가능
    • 인터페이스로 만들어 두고, DB벤더들은 구현 클래스를 만들도록 하면 됨
    • 예를 들어 아래와 같이 연결 인터페이스를 만들면,
      DB업체들은 해당 인터페이스를 구현하면, 사용할 수 있음
    • 구현 클래스(Driver class)라 함
    • DB 벤더에서 제공하는 JDBC Driver 클래스가 필요함
      • 구체적 구현 내용은 자바 개발자가 알 필요가 없음
  public interface Connection {
  // 접속동작
  	getConnection(String url, String userm String passwd);
 }
 
    // 예시, 실제로는 구현 내용을 드라이버 클래스를 받아야 함
    public class MySQL implements Connection {
      @Override
      public String getConnection(String url, String userm String passwd) {
      return "연결되었습니다";
    }
  • 하위 클래스의 동작 방식을 몰라도 DB를 연결할 수 있음
  • 다형성 구현된 예제임

인터페이스와 상속 관계

  • 인터페이스가 인터페이스를 상속받을 수 있다.
public interface A {
	public void m();
}
public interface B extends A{
	public void z();
}

// 두개를 구현해야 함
public class X implements B {
	public void m() {
    }
    public void z() {
    }
  }
  • 다중상속관계에 있는 클래스 구조
    • 인터페이스 여러개 포함 가능
public class Dog extends Animai implements Pet, Robots{

}

Object 클래스는 신이야!

  • 최상위 class, 동작 존재
    • toString : 객체가 가지고 있는 메모리 번지를 문자열로 출력
    • eqauls : 객체가 같은지 반환
    • () 부분이 기본적으로 생략됨
    (import java.lang.*;) // 기본적으로 생략
    public class A (extends Object) {
    // 기본 생성자 생략
    (
      public A() {
        super();
      }
    )
    // Object에서 display 출력 불가
    // 다운 캐스팅을 통해 출력 기능
    public void display() {
    	System.out.println("나는 A이다.");
    }
    // Object로 toString 출력하면 출력 가능(Object 클래스 내 toSting메서드를 재정의 했기 때문)
    @Override
    public String toString() {
    	System.out.println("재정의 메서드입니다.");
      }
    }

Object class의 활용

  • Object로 upcasting 하게 되면 반드시 downcasting
public class ObjectTest {
	public static void main(String args) {
    	display(new A());
        display(new B());
     }
     // A와 B 클래스 각각 go라는 메서드 있다고 할 때
     // 각각의 매개변수 A, B 2개로 만들 수 있지만 하나로 합칠 수 있음
     public void display(Object o) {
     // 사용할 때는 downcasting 해야한다.
     	if(o instanceOf A) {
        	((A)o).go();
        }
        else {
          ((B)o).go();
        }
    }
 }
  • 다형성 배열도 instanceof 키워드로 타입 확인 필요
    • if(o[i] instanceof A) 이런식

학습정리

  • 객체지향 프로그래밍의 3대 특징
    • 정보은닉
      • private
    • 상속
      • 클래스 수직적 구조 설계
      • 다형성을 사용하기 위해 필연적
    • 다형성
      • 상속관계에 있는 클래스에서 상위 클래스가 동일한 메세지로 하위클래스들을 서로 다르게 동작시키는 객체지향 원리
  • 다형성 전제조건
    • 상속관계
    • 객체 생성을 upcasting
    • 하위클래스가 반드시 재정의(override)해야 한다.
    • 동적바인딩을 통해 실현된다(실행 시점에서 메서드가 결정되는 바인딩, 프로그램의 속도를 떨어트리는 원인이 된다.)
  • 추상클래스와 인터페이스의 공통점
    • 다형성 보장하기 위해 등장
    • 객체를 생성할 수 없다.
    • 하위클래스에 의해 구현되어야 한다.
    • 부모의 역할로 사용한다(upcasting으로 객체를 생성)
    • 추상 메서드를 가진다.

package(패키지)가 뭐에요?

  • 패키지 : 기능이 비슷한 클래스를 모아서 관리하기 쉽게 하기 위해 묶어주는 것
    • 윈도우 폴더와 유사
    • package 외부에서 접근하는 것을 막을 때 사용
  • 클래스의 이름은 2가지이다.
    • 기본이름 : MyClass
    • 패키지를 포함한 이름(class full name) : kt.tpc.MyClass
  • 패키지 외부에서 접근하는 방법
    • class full name을 알아야 한다.(kt.tpc.MyClass)
    • 접근권한을 알아야 한다.(public)
      • 접근권한이 생략되면 기본적으로 default 접근 권한을 가짐(단어가 아닌 의미적으로 해결 - 패키지 안에 있는 클래스간 공유 가능)
      • default 권한은 패키지 밖에서 접근 못함
      • 보통 외부에서 접근 되게 public / 안되게 private 이런식으로 함
    • import 구문을 이해해야 한다.
      • 다른 패키지의 클래스 기본이름 사용하기 위해서 import 해줘야 함
      • 해주지 않으면 클래스 full name을 사용해야 함

자바에서 제공해주는 API 접근 및 활용

  • API를 만드는 사람도 패키지 구조로 클래스 구현 -> 배포
  • 어떤 패키지 구조로 되어있는지 알아야 사용할 수 있음
  • 클래스를 묶어서 배포하는 파일 형식 .jar
    • jrt-fs.jar : 자바 기본 API
      • java - lang : 기본 클래스(default)
        • String, System, Integer, .. 기본 자료형과 관련된 클래스
        • 클래스를 만들면 자동으로 import 된다.
      • util : 유틸리티 관련 ArrayList 등
      • io : 입출력 관련, stream 등
  • String 클래스의 이름은 2가지이다.
    • 기본이름 : String
    • 패키지를 포함한 이름 : java.lang.String

문자열이 객체라고요?

  • java.lang 패키지에 String Class를 활용
    • String 객체를 생성하고 이를 가르켜야 함
  • java에서 문자열은 쌍따옴표로 감싸면 된다.
  • 자바에서 문자열을 저장하는 기본 자료형(DataType)은 없다
  • 문자열은 여러가지 조작할 수 있기 때문에 별도의 클래스로 자료형을 만들어 두었다.
  • 자바에서 문자열을 객체로 취급한다.
// Heap Area에 객체 생성 메모리 영역에 "APPLE" 생성
// str1변수와 str2의 주소 번지는 달라짐(new 키워드로 각각의 객체를 생성했기에)
// new 키워드 하면 Heap Area에 생성됨
String str1 = new String("APPLE"); 
String str2 = new String("APPLE"); 

// no가 출력됨
if(str1==str2) {
	System.out.println("yes");
 }
 else {
 	System.out.println("no");
 }
 
 // yes가 출력됨
if(str1.equals(str2)) {
	System.out.println("yes");
 }
 else {
 	System.out.println("no");
 }

// Literal Pool : 문자열 상수(객체)가 생성되는 메모리 영역(재활용)
String str3 = "APPLE";
// 이미 만들어 진 "APPLE"을 가르킴
// 하나를 공통으로 가르킴
String str4 = "APPLE";

// yes가 출력됨
if(str3==str4) {
	System.out.println("yes");
 }
 else {
 	System.out.println("no");
 }
  • literal pool을 사용하는 경우만 ==이 참으로 나옴
    • 하지만 equals 메서드로 습관하 하기가 좋음!

내가 만든 최초 API

  • 배열 기본 동작의 이해
public class BasicArray {
	public static void main(String[] args) {
    	int[] a = new int[3];
        
        a[0] = 10;
        a[1] = 20;
        a[2] = 30;
        
        int v = a[1];
        int len = a.length;
        
        for(int  i = 0; i < a.length; i++) {
        	System.out.println(a[i]);
        }
    }
}
  • 위 배열 동작을 클래스(API)로
public class IntArray {
	private int count;
    private int[] arr;
    // 매개변수 없으면, 디폴트 생정자 호출
    // 기본 사이즈 10
    public IntArray() {
    	this(10); // 자기 자신을 가르키는 또다른 생성자 호출
    }
    // 배열 생성 동작
    public IntArray(int init) {
    	arr = new int[init];
    }
    // 추가 동작
    public void add(int data) {
    	arr[count++] = data;
    }
    // 얻는 동작
    public int get(int index) {
    	return arr[index];
    }
    // 배열크기
    public int size() {
    	return count;
    }
  }
  
  // 배열처럼 동작하는 API 적용
  public class BasicArray {
  	public static void main(String[] args) {
    	IntArray arr = new IntArray(3);
        arr.add(10);
        arr.add(20);
        arr.add(30);
        
        for(int i = 0; i<arr.size(); i++) {
        	System.out.println(arr.get(i));
         }
         
       }
     }
  • ArrayList와 유사한 API 형태

ArrayList 흉내내기(Object[])

  • Object 형태로만 변경하면 됨

  • 실제 ArrayList에서는 배열의 size가 넘치면 size를 증가시켜주는 등의 동작을 함

  • 하지만 이미 인터페이스에 구현되어 있으므로, 따라하는 정도로만 하기 위해 배열의 크기를 늘리는 방식은 구현하지 않았음

    
    public class ObjectArray {
    		private int count;
       private Object[] arr;
       // 매개변수 없으면, 디폴트 생정자 호출
       // 기본 사이즈 10
       public ObjectArray() {
       	this(10); // 자기 자신을 가르키는 또다른 생성자 호출
       }
       // 배열 생성 동작
       public ObjectArray(int init) {
       	arr = new Object[init];
       }
       // 추가 동작
       public void add(Object data) {
       	arr[count++] = data;
       }
       // 얻는 동작
       public Object get(int index) {
       	return arr[index];
       }
       // 배열크기
       public int size() {
       	return count;
       }
     }
     
       // 배열처럼 동작하는 API 적용
     public class TPC37 {
     	public static void main(String[] args) {
       	ObjectArray arr = new ObjectArray(3);
           arr.add(new A());
           arr.add(new B());
           arr.add(new A());
           
           for(int i = 0; i<arr.size(); i++) {
           // 배열에 넣을 때 upcasting
           // 나올때도 upcasting 이니깐 타입 검사 필요
             Object o = arr.get(i);
             if(o instanceof A) {
                 ((A)o).go();
              }else {
                 ((B)o).go();
              }
            }
        }
      }
  • 제네릭으로 타입 지정할 수도 있음

크기에 상관 없이 객체를 저장(List)

  • ArrayList 내부
    • Object[] 배열 / 사이즈 지정 안하면 기본 10
    • add(Object o) : 객체 추가
    • get(int index) : 인덱스 가져오기
    • size() : 크기
    • 바로 downcasting을 해줘야 함
      • 리스트에 들어갈 때 upcasting
      • 꺼낼 때 type으로 받아야 하니 downcasting
      • 제네릭으로 타입 지정 전에는 필수
    • 길이의 제약이 없다
import java.util.*;
// 사이즈 1이여도 자동으로 증가하므로 들어갈 수 있음
List list = new ArrayList(1);
list.add(new BookDTO(123));
list.add(new BookDTO(234));
list.add(new BookDTO(5123));

for(int i = 0; i<list.size(); i++) {
	Object o = list.get(i);
    BookDTO vo = (BookDTO)o;
    System.out.println(123123213);
 }
  • 위 처럼만 사용하면 리스트에 어떤 타입이든 넣을 수 있음

  • 하지만 보통 하나의 타입만 넣는것이 일반적

  • 제네릭으로 지정 할 수 있음

    • 배열에 들어갈 때 upcasting이 일어나지 않음

    • 꺼낼 때 downcasting이 필요없음

      import java.util.*;
       // 사이즈 1이여도 자동으로 증가하므로 들어갈 수 있음
       // Object[] -> BookDTO[]로 지정 가능
       // upcasting이 일어나지 않음
       List<BookDTO> list = new ArrayList<BookDTO>(1);
       list.add(new BookDTO(123));
       list.add(new BookDTO(234));
       list.add(new BookDTO(5123));
      
       for(int i = 0; i<list.size(); i++) {
           // Object o = list.get(i);
           // downcasting이 필요없음
           BookDTO vo = list.get(i);
           System.out.println(123123213);
        }

Wrapper 클래스란?

  • 기본 자료형을 객체 자료형으로 사용할 수 있도록 만들어 놓은 자료형(포장 클래스)
기본자료형객체자료형사용 예
intInteger1, new Integer(1)
floatFloat23.4f, new Float(23.4f)
charCharacter'A', new Character('A')
booleanBooleantrue, new Boolean(true)
  • Object <--> Integer(o) / 자식은 클래스여야 히니깐 감싸줄 필요 있음
    • 기본 자료형을 Object 타입과 부모 자식간 연동하여 사용하기 위함
  • 변수에 1을 저장하는 방법 2가지
  int a = 1;
  Integer b = new Integer(1); // 객체
  int v = b.intValue();  // 포장을 벗긴다
  • 박싱 / 언박싱 : 컴파일러가 자동으로 해준다.

    • 박싱 : 기본 자료형에서 Wrapper Class로 감싸줌
      • int -> Integer
    • 언박싱 : Wrapper Class -> 기본자료형
      • Integer -> int
      • int b = new Integer(10); // 오토 언박싱
        • int b = new Integer(10).intValue();로 해야 원래 맞음
  • 기본자료형을 Object[] 배열에 저장할 경우? Integer 클래스 활용하여 객체형태로 저장

Object[] obj = new Object[3];
// obj[0] = 1;도 에러가 나지 않음
// 오토 박싱이 되기에 에러가 나지 않지만 아래 코드가 정확
obj[0] = new Integer(1);  
obj[1] = new Integer(2);
obj[2] = new Integer(3);
int v1 = 100;
String.valueOf(v1); // v1을 String

마치며

  • part2도 거의 아는 내용이였지만, 세세하게 메모리 부분을 알 수 있어 좋았다.

  • String에서 String a = "abc"; 형태가 literal pool에 생겨서 == 로 대등 비교해도 된다는 것을 처음 안 것 같다.(아닌가 들어봤나..? 무튼)

  • 뭔가 깊은 부분의 내용을 좀 더 알 수 있던 3일간의 연휴동안 쭉쭉 달려왔다.

  • 자바 클래스, 상속 등 개념 부분이 확실하지 않은 사람들이 보기에 좋은 강의일 것 같다!

  • 17시간 44분이라니..! 고생했다!

  • 출처 : 인프런 - Java TPC(생각하고, 표현하고, 코딩하고

  • 강의 출처남기면 블로그 작성해도 된다고 하셨지만, 상세 실습코드는 작성하지 않았습니다. 강의를 통해 확인하세요!

profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글