[1]enum(상수값들의 집합)

 - 프로그램에서 미리 정해놓아야할 값들(상수들)이 존재할 때, 사용한다.

 - 문법 형식 : 


 public enum FoodMenu {

  PIZZA("피자"), KIMCHI("김치), CHIKEN("치킨");

 }

  그외에, 필드 와 생성자를 내부에 가질 수 있다.


 - 실제로는 java.lang.Enum 클래스의 자식 클래스로 생성된다. 많이 쓰는 메소드로 enum변수.name(), ordinal()이 가장 많이 쓰인다.

 - 자동적으로 제공되는 메소드 :  values() - return 타입 : E[]에다가 안에 있는 상수들을 다 뽑아 낼 수 있다 valueOf(String name) - E 타입 하나를 뽑아 낼 수 있다

 - 사용은 Enum명.상수명 을 이용해서 불러와, Enum변수에다가 집어넣어서 --> 보통 swtich -case문에 많이 사용한다. 

    FoodMenu f = FoodMenu.KOREAN

f.na



[2] 가변형 인자(var args) (String... a)

 - 인자값(파라미터, argumen)의 개수를 정하지 않는 것

 - 배열과 같게 취급이 되어, 확장for문  for(String s : a) 형식으로 사용된다.

 - 문법 형식 : 

   public void method(String... a){

for(String s : a) {

System.out.println(s);

}

   }

  인자값이 1개가 됬든, 10개가 됬든, String형 배열에 담겨서 그것들을  확장for문으로 뽑아낼 수 있다.

 - 반드시 마지막 인자값으로 가변형 인자가 들어가야한다. (String a, int b, String... c)


[3] 추상 클래스(abstract Class)

 - class이지만, 객체를 생성할 수 없다. 불완전한 설계도이므로 상속받는 자식클래스에서 객체를 생성해야한다.

 - 추상메소드를 가지는 것은 인터페이스와 동일하다. 하지만 , 필드와 일반메소드들도 가질 수 있는 점에서 인터페이스와 차이가 난다.

 - 목적미리 만들어진 메소드를 자식클래스가 반드시 오버라이딩해서 가지도록 하기위해서이다.(인터페이스가 더 추상적이라 설계적인 측면에서 선호된다)

 

[4] 중첩 클래스(nested class)  : 3가지가 존재한다.

 - 클래스안에 클래스가 들어간다는 의미이다. 

   만약 클래스안의 클래스인데, static이 붙어있으면, static-nested class라 한다.

   만약 클래스안에 들어간 클래스가 static이 없으면, inner class라고 부른다.

   만약, 클래스이름이 없고, 인터페이스를 상속(new Runnable(){})해서 바로 body{}만 있는 것이라면, anonymous - inner class라 부란다




   my) 클래스는 객체를 생성하기 위한 것이다. 만약 static이 붙어서 클래스의 것이 되면, 외부에서 객체생성 못한다.

         대신 클래스 내에서는 객체생성이 가능하다.


  래스안에 클래스(중첩클래스)가 존재하는 것은 3가지 경우이다.

1) static이 붙은 중첩클래스 : 스태틱이 붙어 있으므로, 클래스의 것 => 클래스 내부에서만 객체생성이 가능하다.

2) static이 안붙은 이너클래스스태틱이 안붙어 있으므로, 객체의 것 => 어디서든 객체를 생성해서 사용한다.

3) 클래스의 이름이 없이 인터페이스를 상속한 new Runnable() { } 클래스 : 어노니머스-이너클래스 => 클래스이름이 없고 바로 내부에 실행매쏘드를 가진다.


 - 목적 : 오로지 한 클래스 안에서만 필요한, 클래스(외부에서 객체를 만들필요가 있을 경우)가 필요할 때 사용한다.

  encalsulation이 강화된다. 프로세스가 돌아갈 때, 안쪽 한군데서만 돌아가도록 하고, 메소드를 통해서, 통신만 하도록 하게 하는 것이 강해진다.

 - 가장 많이 쓰이는 곳 : Swing(ui), android에서 이벤트 처리용으로 많이 사용한다.

 

 static-nested class의 static은 소유제한자이며, class의 것이다. 클래스에서 객체를 생성해서 사용한다.

 

public class Outer {

private static class StaticNested { } : static이 붙은 [ 중첩클래스 ]이며, 클래스내에서만 객체가 생성 가능하다.

private class Inner{ } : static이 안붙어 있는, 클래스안의 클래스를  [ 이너클래스 ]라고 한다. static이 안붙었기 때문에, 객체의 것이므로, 객체를 생성해서 사용해야한다.

private Runnable run = new Runnable(){ } : [anonymous - inner class]로, java.lang.패키지에 있는 Runnable이라는 인터페이스이다.

}

- new Runnable( ) { } 이라는 것이 Runnable이라는 인터페이스의 객체를 생성하는 것 처럼 보이지만, 사실은 인터페이스를 상속하고 있는 또다른 클래스를 만드는 과정이다. 그래서 {  }안에는 필드와 메소드가 들어간다. 

  - 인터페이스를 상속받고 있는 클래스이지만, 이름이 없다.

 


 -  중첩클래스의 객체를 생성하는 문법 형식

1)static-nested class(스태틱- 중첩클래스) :  <클래스 내부에서> 클래스명.중첩클래스명  변수 = new 클래스명  .중첩클래스명();

2)inner class(이너 클래스) :   클래스명.이너클래스명  변수 = new 클래스명(). new 이너클래스명(); 

   [ Outer객체 > Inner클래스 ] -- [ Inner객체 ]

3)anonymous-inner class(어노니머스-이너클래스 ) : 인터페이스명  변수 = new 인터페이스명() { 오버라이딩 메소드 };

   - 인터페이스 객체를 생성하는 것이 아니라 인터페이스를 상속하는 어노니머스 이너클래스를 만드는 과정



[5] annotation(애노테이션)

 - 프로그램에 대한 정보를 제공하는 것이다.

 - 목적 : 컴파일러에게 정보제공 / 컴파일 시 자동으로 소스를 만들어줌  /  xml을 생성기능 / 실행시에 검사하기 위해서

 - 활용 : Spring 프레임워크에서 많이 사용된다.


 - 컴파일러에게 정보제공 할 때 쓰이는 방식

  @Deprecated : 더이상 쓰지 말아야할 곳에 쓴다

  @Override : 반드시 오버라이딩 해야할 곳

  @SuppressWarnings : Generics( )를 제대로 사용하지 않았거나, Deprecated된 메소드를 사용할 때 Warning이 발생하는 곳에 막아주는 기능


[6] final

 - 변수 앞에 붙어서 상수로 만들어준다

 - 메소드 앞에 붙어서 자식이 오버라이딩(재정의) 못하게 한다

 - 클래스 앞에 붙어서 자식이 상속할 수 없게 한다.



[7] 실습


1. 메인메소드를 가진, package enumpack, public class TestEnum 를 만들어준다.

(1) 중첩클래스처럼, 내부에 enum을 만들어준다.

     public class TestEnum {

public enum Language{

}

(2) 대문자로 상수를 만들어준다.

KOREAN, ENGLISH, JAPANESE;


(3)[  ctrl+space ] 를 눌러서 생성자를 넣어준다. (사용은 안할 것이다)


(3) 보통 메인함수에서 참조형 변수를 생성한 뒤에 Language.상수명을 넣은 다음, 변수를  switch case문에 넣어서 사용한다.

public static void main(String[] args) {


Language l = Language.ENGLISH;

switch(l) {

case KOREAN : System.out.println("한글입니다."); break;

case ENGLISH : System.out.println("영어입니다 " + Language.ENGLISH); break;

}

}

(4) 이제 enum명. values()를 이용해서 선언한 상수들을 모두 배열에 넣은다음, 확장for문을 이용해 하나씩 꺼내보자.

     for문안에서는 사용된 변수.name()을 상수명을, 변수.ordinal()을 이용해서 index순서도 같이 찍어주자.


for(Language lang : Language.values()) {

System.out.println(lang.name() +"은 "+ lang.ordinal()+"번째 상수입니다.");

}


2. abs패캐지, abstract 클래스를 만들자. 메인함수도 넣어주자.

(1) class앞에 abstract를 추가해주자.

(2) 메소드를 만드는데 반환형 앞에다가 abstract를 넣어줘야한다. 순서바뀌면 안됨.

(3) 인터페이스와는 다르게, 일반메소드도 넣어줄 수 있다. 


package abs;

public abstract class TestAbs {

public abstract void test() ;

 

public void test2() {

System.out.println("추상클래스안의 일반메소드");

}

 

public static void main(String[] args) {


}


}



(4) abs패키지안에, 추상클래스를 상속받을 자식클래스를 만들어주자. [browse]를 눌러서 부모클래스를 TestAbs를 선택해주자. 메인함수도 포함시키자

 - 부모클래스가 추상클래스이므로, 자식클래스가 반드시 오버라이딩 해야하는 매쏘드가 , 자동으로 작성되어있다.


public class TestAbsSub extends TestAbs {


@Override

public void test() {

// TODO Auto-generated method stub


}

(5) 메인메소드에서 사용해보자. 

*** 나는 객체를 생성해서, 변수에 넣고, 변수.메소드()를 호출하지만 , 변수 없이 바로 객체생성후.메소드()를 호출 할 수 있다.

클래스의 메소드를 사용하는 것은 [ new 생성자() ] 의 객체가 메소드를 사용해서 통신


public static void main(String[] args) {


//객체를 생성해서 변수에 넣고 이용하는 방법

TestAbsSub tab = new TestAbsSub();

tab.test();

//객체 생성하자마자 바로 메소드를 이용하는 방법

new TestAbsSub().test();

//부모인 추상클래스의 일반 메소드를, 자식이 사용하기

new TestAbsSub().test2();

}



3. 중첩클래스를 만들어보자.

(1) 클래스안에,  Runnable인터페이스를 상속받는 [이너클래스]를 만들자. -> Runnable인터페이스안의 추상메소드를 상속해야한다.

(2) run()함수안에는 for문으로 0부터 9까지 출력시키는 코드를 넣어주자.


//이너클래스

private class Target implements Runnable {


@Override

public void run() {

for(int i=0;i<10;i++) {

System.out.println("i : "+i);

}

}

}


(3) 메인메소드에서 Target클래스의 객체를 만들자. 하지만 이너클래스는 static 이너클래스인 메인메소드 안에 바로 들어갈 수 없다.

    바깥쪽 TestOuter객체를 만들고 그것을 이용해야한다.

   ***** 이너클래스의 객체는 바로 생성하지 못한다 ==> 현재 바깥 클래스의 객체를 만들고 난 뒤, 변수를 선언할 때는, 클래스명. 을 / 객체를 생성할 때는, 객체명. 을 써서 생성한다.

   ***** [바깥 클래스명].[이너클래스명]  변수명    =    [바깥 클래스 객체]. new [이너클래스명](); 

    왜냐면, 변수 선언은   [설계도 클래스명]이 앞에 오고 / 객체 생성은, [객체]에서 비롯 되기 때문이다.

public static void main(String[] args) {


TestOuter out = new TestOuter();

TestOuter.Target t = out.new Target(); 

}


(4) 쓰레드를 하나 만들어고, 파라미터에는 Runnable인터페이스를 상속한 클래스의 변수를 넣어준다.

    - Runnable 인터페이스의 run()메소드는 쓰레드의 파리미터에 넣어서 실행된다. 그것을 상속한 자식의 run()메소드도 쓰레드에서 실행된다.


Thread th = new Thread(t);

th.start();


(5) anonymous-inner class를 메인함수에서 바로 만들어주자.

     먼저 쓰레드 객체를 생성하고, 파라미터에는 new Runnable() {  }을 만들어준 다음, ctrl+space로 run()매소드를 오버라이딩 하자.


//어노니머스 이너클래스

Thread th2 = new Thread(new Runnable() {

@Override

public void run() {

for(int i=0;i<10;i++) {

System.out.println("i : "+i);

}

}

});

th2.start();


+ Recent posts