본문 바로가기

JAVA

자바 - 나무보다 숲을 보자(3)

상수
public class ConstantDemo {
    private final static int APPLE = 1;
    private final static int PEACH = 2;
    private final static int BANANA = 3;
    public static void main(String[] args) {
        int type = APPLE;
        switch(type){
            case APPLE://1
                System.out.println(57+" kcal");
                break;
            case PEACH://2
                System.out.println(34+" kcal");
                break;
            case BANANA://3
                System.out.println(93+" kcal");
                break;
        }
    }
}

enum
상수가 같은 이름을 가진다면? 접두사 붙이기? FRUIT_APPLE / COMPANY_APPLE
인터페이스 사용 -> 무조건 public static final 속성
interface FRUIT{
    int APPLE=1, PEACH=2, BANANA=3;
}
interface COMPANY{
    int GOOGLE=1, APPLE=2, ORACLE=3;
}
 
public class ConstantDemo {
     
    public static void main(String[] args) {
        int type = FRUIT.APPLE;//COMPANY.APPLE로 해도 같은 결과가 나온다
        switch(type){
            case FRUIT.APPLE:
                System.out.println(57+" kcal");
                break;
            case FRUIT.PEACH:
                System.out.println(34+" kcal");
                break;
            case FRUIT.BANANA:
                System.out.println(93+" kcal");
                break;
        }
    }
}

//// enum : enumerated type 열거형
enum Fruit{//enum~~클래스
    APPLE, PEACH, BANANA;
}
enum Company{
    GOOGLE, APPLE, ORACLE;
}
 
public class ConstantDemo {
     
    public static void main(String[] args) {
        /*
        if(Fruit.APPLE == Company.APPLE){
            System.out.println("과일 애플과 회사 애플이 같다.");
        }
        컴파일 에러 -> 다른 enum 그룹과 비교하지 못함
        */
        Fruit type = Fruit.APPLE;
        switch(type){
            case APPLE:
                System.out.println(57+" kcal");
                break;
            case PEACH:
                System.out.println(34+" kcal");
                break;
            case BANANA:
                System.out.println(93+" kcal");
                break;
        }
    }
}

enum Fruit 선언은 
class Fruit{
    public static final Fruit APPLE  = new Fruit();
    public static final Fruit PEACH  = new Fruit();
    public static final Fruit BANANA = new Fruit();
    private Fruit(){}//생성자 접근 제어자 private: Fruit를 인스턴스로 만들 수 없음
}
과 같음

enum의 사용 이유 - 코드가 단순해짐. 인스턴스 생성과 상속 방지. 열거의 의도

enum의 생성자
enum Fruit{
    APPLE, PEACH, BANANA;
    Fruit(){//private만 허용
        System.out.println("Call Constructor "+this);
    }
}
 
enum Company{
    GOOGLE, APPLE, ORACLE;
}
 
public class ConstantDemo {
     
    public static void main(String[] args) {
     
        /*
        if(Fruit.APPLE == Company.APPLE){
            System.out.println("과일 애플과 회사 애플이 같다.");
        }
        */
        Fruit type = Fruit.APPLE;
        switch(type){
            case APPLE:
                System.out.println(57+" kcal");
                break;
            case PEACH:
                System.out.println(34+" kcal");
                break;
            case BANANA:
                System.out.println(93+" kcal");
                break;
        }
    }
}
/////
enum Fruit{
    APPLE("red"), PEACH("pink"), BANANA("yellow");//상수 선언 & 생성자 호출
    public String color;
    Fruit(String color){
        System.out.println("Call Constructor "+this);
/*
Call Constructor APPLE
Call Constructor PEACH
Call Constructor BANANA
*/
        this.color = color;
    }
}
 
enum Company{
    GOOGLE, APPLE, ORACLE;
}
 
public class ConstantDemo {
     
    public static void main(String[] args) {
        /*
        if(Fruit.APPLE == Company.APPLE){
            System.out.println("과일 애플과 회사 애플이 같다.");
        }
        */
        Fruit type = Fruit.APPLE;
        switch(type){
            case APPLE:
                System.out.println(57+" kcal, "+Fruit.APPLE.color);
                break;
            case PEACH:
                System.out.println(34+" kcal"+Fruit.PEACH.color);
                break;
            case BANANA:
                System.out.println(93+" kcal"+Fruit.BANANA.color);
                break;
        }
    }
}
메소드도 가질 수 있다.
String getColor(){
        return this.color;
}

멤버 전체를 열거하는 기능 -> Fruit.values()
for(Fruit f : Fruit.values()){
            System.out.println(f+", "+f.getColor());
}

 

참조
int a = 1;
int b = a;//변수 b에 변수 a의 값이 복제됨
b = 2;//b의 값만 변경되고 a의 값은 1로 그대로


        A a = new A(1);
        A b = a;//a의 주소를 복사함
        b.id = 2;//a의 위치로 가서 a에 대한 작업을 함
//a.id도 2로 변경됨


int a = 1; // int형
A a = new A(1); //A형
new 사용 -> 참조 데이터형!! 

참조 데이터형과 매개변수
-매개변수로 받아서 원본 객체를 참조하고 변경할 수 있다

제네릭: 클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법

class Person{
//타입 T는 외부에서 정해짐
    public T info;
}
 
public class GenericDemo {
 
    public static void main(String[] args) {
        Person p1 = new Person();
//p1의 데이터 타입 정의 & 인스턴스 생성
        Person p2 = new Person();
    }
}

타입 안전성
구조의 중복, 생성자 매개변수가 Object일 때 모든 객체가 될 수 있는 문제

제네릭화
class StudentInfo{
    public int grade;
    StudentInfo(int grade){ this.grade = grade; }
}
class EmployeeInfo{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
}
class Person{
    public T info;
    Person(T info){ this.info = info; }
}
public class GenericDemo {
    public static void main(String[] args) {
        Person p1 = new Person(new EmployeeInfo(1));
        EmployeeInfo ei1 = p1.info;
        System.out.println(ei1.rank); // 성공
         
        Person p2 = new Person("부장");
        String ei2 = p2.info;
        System.out.println(ei2.rank); // 컴파일 실패
    }
}
//컴파일 단계 오류 검출, 중복 제거와 안전성 추구

제네릭은 참조 데이터 타입에서만 사용할 수 있다.
class EmployeeInfo{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T, S>{
    public T info;
    public S id;
    Person(T info, S id){ 
        this.info = info;
        this.id = id;
    }
}
public class GenericDemo {
    public static void main(String[] args) {
        EmployeeInfo e = new EmployeeInfo(1);
        Integer i = new Integer(10);//wrapper 클래스 - 참조형으로 변환
        Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
        System.out.println(p1.id.intValue());
    }
}

제네릭의 생략
EmployeeInfo e = new EmployeeInfo(1);
Integer i = new Integer(10);
Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
Person p2 = new Person(e, i);//동일한 코드

메소드에 적용
class EmployeeInfo{
    public int rank;
    EmployeeInfo(int rank){ this.rank = rank; }
}
class Person<T, S>{
    public T info;
    public S id;
    Person(T info, S id){ 
        this.info = info;
        this.id = id;
    }
    public  void printInfo(U info){
        System.out.println(info);
    }
}
public class GenericDemo {
    public static void main(String[] args) {
        EmployeeInfo e = new EmployeeInfo(1);
        Integer i = new Integer(10);
        Person<EmployeeInfo, Integer> p1 = new Person<EmployeeInfo, Integer>(e, i);
        p1.printInfo(e);
        p1.printInfo(e);
    }
}

제네릭의 제한
class Person{ 
Info 클래스의 자식으로 제한
class EmployeeInfo implements Info{
인터페이스도 가능

 

 

배열과 컬렉션즈 프레임워크
배열 - 처음에 정한 크기를 변경할 수 없다.
ArrayList al = new ArrayList();//크기를 미리 지정하지 않음
al.add("one");
al.add("two");
al.add("three");//크기에 자유롭다

for(int i=0; i<al.size(); i++){//배열의 길이는 size 메소드로 구한다
System.out.println(al.get(i));//인덱스 번호 .get(번호)
}

add는 인자를 Object 형식으로 받는다.
for(int i=0; i<al.size(); i++){
    String val = (String)al.get(i);//형변환
System.out.println(val);
}//이전의 방식

ArrayList al = new ArrayList();
al.add("one");
al.add("two");
al.add("three");
for(int i=0; i<al.size(); i++){
    String val = al.get(i);
System.out.println(val);
}//제네릭 사용

컬렉션즈 프레임워크 (컨테이너)
List-중복 허용
Set-중복 불가
Iterator ai = al.iterator();
while(ai.hasNext()){
System.out.println(ai.next());
}

Set : 집합 - 순서X 중복X 집합 연산
Map : key와 value 쌍으로 값을 저장

'JAVA' 카테고리의 다른 글

JAVA 플레이 그라운드  (0) 2019.06.22
자바 - 파일 입출력  (0) 2019.05.30
자바 - 나무보다 숲을 보자(3)  (0) 2019.05.22
자바 - 나무보다 숲을 보자(2)  (0) 2019.05.21
자바 - 나무보다 숲을 보자(1)  (0) 2019.05.19