본문 바로가기
코스웨어/11년 내장형하드웨어

[내장형] 일일보고서(11년 8월 16일) 황세선

by 알 수 없는 사용자 2011. 8. 16.
728x90
반응형
자바의 OOP
자바는 코드의 재활용이 좋다고 한다. 아직 우리 레벨 에서는 이해 할수 없는 말이지만 이쪽 분야로 계속 일을 하게 된다면 언젠가는 느끼고 이해하게 될것 같다. OOP 를 활용하면 30 % ~ 최대 50% 까지의 코드 재활용이 가능하다~!!!?

오드로이드(회사)


처음에 선생님 께서 오드로이드 라고 했을때 안드로이드 짝퉁? 이라는 느낌을 강력하게 받았다. 나만 그랬던 걸까?; 그건 그렇고 선생님 께서 이 짝퉁 같은 오드로이드 회사의 제품을 하나 소개 시켜 주셨다. 이것이 뭐하는 것인지 정확히 모르겠지만 아이패드 혹은 갤럭시 텝과 비슷한 용도로 사용되는 것 같다. 가만 보니 전화도 되는것 같다. 위 제품은 우리가 궁극 적으로 이뤄 내야할 목표가 아닌가 싶다. 그림에 보면 빨간 줄을 그어 놓았는데 그것들을 어떻게 좀 마스터하면 요런 제품을 만들어 낼수 있지 않을까 싶기도 하다.

Calendar 클래스
저번 시간에 이어 요번 시간에도 Calendar 클래스에 대해서 배웠다. 일단 이것을 왜 배워야 하는지 잠깐 생각해 보았다. 음.. 생각해 본 결과 이 클래스는 악세서리와 같은게 아닐까 생각한다. 이유는 만약 내가 멋진 안드로이드용 게임 어플을 만들었다고 하자. 지하철 안에서 나의 게임을 즐기는 사람들이 나의 게임에 시간 가는줄 모를지도 모른다. 그럴때 게임안에 이런 클래스를 이용하여 시간을 표시해 주면 사용자를 진정으로 배려하는 완벽한 프로그램이 되지 않을까 생각해 봤다.

자..나의 생각은 이쯤에서 접어 버리고 이제 오늘 작성한 소스를 분석해 볼 시간이다. 이 소스는 Calendar 클래스를 이용하여 월,일,시,분,요일 을 출력해 보는 그런 예제다. 아래는 그 소스다.

package kr.ac.busanit.time;
import java.util.Calendar;
import java.util.GregorianCalendar;

public class TimeTest1 
{
  public static void main(String[] args) 
  {
    //Calendar cal = Calendar.getInstance();
    //Calendar cal = new GregorianCalendar();
    GregorianCalendar cal = new GregorianCalendar();
    
    System.out.print((cal.get(Calendar.MONTH) + 1) + "월");
    System.out.print(cal.get(Calendar.DATE) + "일");
    System.out.print(cal.get(Calendar.HOUR) + "시");
    System.out.print(cal.get(Calendar.MINUTE) + "분");
    switch(cal.get(Calendar.DAY_OF_WEEK))
    {
    case 1 :
      System.out.print("일");
      break;
    case 2 :
      System.out.print("월");
      break;
    case 3 :
      System.out.print("화");
      break;
    case 4 :
      System.out.print("수");
      break;
    case 5 :
      System.out.print("목");
      break;
    case 6 :
      System.out.print("금");
      break;
    case 7 :
      System.out.print("토");
      break;
      
    }
    System.out.print("요일");
  }
}


그리고 출력 결과다.


먼저 import java.util.Calendar; 부분은 C 언어로 볼때 #include <뭐뭐뭐.h> 와 같은 역할을 한다. 그 아래도 마찬가지다.
메인함수로 진입하면 바로

//Calendar cal = Calendar.getInstance();
//Calendar cal = new GregorianCalendar();
GregorianCalendar cal = new GregorianCalendar();

요런 것들이 보인다. 선생님 말씀으로는 저 3가지 객체 생성은 같다고 하신다. 실제로 주석을 바꿔서 하나씩 풀어 보아도 아래의 결과는 잘 나왔다.
다음으로 넘어가자. 다음소스는

System.out.print((cal.get(Calendar.MONTH) + 1) + "월");
System.out.print(cal.get(Calendar.DATE) + "일");
System.out.print(cal.get(Calendar.HOUR) + "시");
System.out.print(cal.get(Calendar.MINUTE) + "분");

요렇게 되어 있다. 우리는 위에서 cal 이라는 Calendar 객체를 생성하였고 그 객체를 이용해서 월,일,시,분 을 구하고 있는데 어떻게 구했냐 하면 객체를 가지고 메소드를 호출 하였다. C 언어로 본다면 그저 함수 호출 한 것 뿐이다. 저게 print 안에 들어가 있어서 헷갈리는데 저걸 밖으로 빼보면 아래와 같다.

cal.get(Calendar.DATE)

잘보면 그것이다. 메소드 호출! 그리고 get 메소드 안에 Calendar.DATE 요게 들어가 있는데 요것을 자바 문서로 찾아보니 public static final int DATE; 로 되어 있다. 나름 분석해 보면 일단 public 이라 누구나 쓸수 있을것 같다. 그리고 static 이다. 이건 왜 썼는지 모르겠다. 그리고 final 이다. 이것은 DATE 에 값을 한번 지정하면 절대로 안바꾸겠다는 것이다. int 형이고 이름은 DATE 다. 참 길기도 한데 이것을 C 언어로 비유해 본다면 요런게 아닐까 싶다.

#define  DATE    1

C 언어로 그저 상수를 좀더 보기 좋게 정의 한 것이다. 결국 이런 식이라면 함수 는 아래와 같이 될것이다.

cal.get(1)

많이 간단해 졌다. 괄호 안에 1이라고 적었는데 저 값이 아닐것이다. 그것까지는 찾아보지 못했다. 결국 get 함수는 무엇인가를 얻어 오는데 1 이라는 값에 해당하는(1-> 예를 든 값) 날짜 정보를 얻어 온다. 잘 보면 위 코드 들은 모두 이런 형식이다. 좀 특이한건 System.out.print((cal.get(Calendar.MONTH) + 1) + "월");
요것 인데 보면 다른것과 달리 + 1 을 해주고 있다. 우리가 생각하는 월을 1월에서 12월 이다. 하지만 이 클래스를 설계한 사람은 좀 특이하다. 0월 에서 11월을 12개월로 보고 있다. 개인 적인 생각이지만 보통 프로그래머 들은 우리의 상식과 틀리게 0 을 초기 값으로 카운터를 한다. 이 Calendar 클래스도 이런 관습때문에 그러지 않았을까 생각한다.

말이 길어 졌다. 다음 소스를 보자.

switch(cal.get(Calendar.DAY_OF_WEEK))
    {
    case 1 :
      System.out.print("일");
      break;


너무 길어서 앞 부분만 때왔다. 보면 스위치 문이다. 잘 알고 있을 것이다. 또 뭔가를 get 해온다. 그리고 DAY_OF_WEEK 를 보면 요일을 구해 주는것 같다. 아니 요일을 구해준다. 요일을 구하는데 뭔 switch 문이냐 하겠지만은 위에서도 그랬듯이 모든 날짜 및 시간은 int 형 값으로 돌려줬다. 요일도 마찮가지다. int 형 정수로 돌려준다. 우리는 일,월,화,수,목,금,토 순으로 카운터를 하고 얘들은 1,2,3,4,5,6,7 순으로 카운터 한다. 그렇다면 오늘은 화요일 이니 분명 get 해온 값은 3일것이다. 그래서 우리는 이 3을 누구나 딱봐도 알수 있는 "화"라는 출력을 얻기위해 사용한 것이다. 그리고! 요번엔 왜 1부터 카운터 했는지 참 의문이다. 위에서 생각해 봤던게 틀린것 같다는 생각이 막 밀려오고 있다.;

다음 소스로 넘어가자.

System.out.print("요일");

끝이다. 화 + 요일 = 화요일

GregorianCalendar 클래스
요 클래스는 위의 소스에 주석에도 나와있다. 그래서 간단하게 짚고 넘어간다.  요건 선생님 말씀으론 양력달력이라고 한다. 그럼 그냥 Calendar 은 음력 달력인가? 잘 모르겠다. 어쨌든 날짜는 어떤것을 써도 똑바로 잘 나온다. 요 클래스는 세계 시간을 구할때 쓸수 있다고 잠깐 언급하셨는데 일단 ppt 내용을 긁어 왔다.



보면 GregorianCalendar 객체로 setTimeZone 이라는 메소드를 호출 하는것이 보인다. 요 함수가 하는 일은 저 메소드 인자 안에 어떠한 값을 넣으면 내가 만든 객체는 그 지역에 대한 날짜 및 시간 정보를 가지게 된다. 사용법 도 긁어와 보았다.



요건 인자를 만들기 위해 하는 작업인것 같다. 보면 유럽/런던 이 보인다. 윗줄에서 가장 튀는 영어다. 대충 생각해 보면 저렇게 timeZone 을 설정하면 이제 나의 달력 객체는 유럽 및 런던 날짜와 시간으로 맞춰진다. 꼭 손목 시계의 시간을 조절하는것 같은 기분이다. 이걸 합쳐서 아래와 같이 쓰면 된다고 한다.

Calendar calendar = new GregorianCalendar();
TimeZone timeZone = TimeZone.getTimeZone("Europe/London");
calendar.setTimeZone(timeZone);


객체를 만들고, 유럽/런던 시간대를 구해, 설정해 주고있다. 요렇게 하고 쓰는법은 위의 긴 소스와 동일하다.

Math 클래스
자. 학교다닐때 그토록 싫어 했던 수학! 클래스다. 하지만 요 클래스는 싫어 하지 않아도 된다. 왜냐면 복잡한 계산을 이 클래스가 대신 다 해준다. 요것도 문서를 찾아보니 눈에 보이는건 abs, log. exp, sqrt, sin, cos, tan, 그리고 random? 이다. 대충 이런것들을 알아서 계산해 주는가 보다. 그리고 우리가 많이 봐오던 rand 와 비슷한 random 도 보인다. 문서에는 이렇게 나와있다.

random()
          Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0.

해석에는 자신이 없어 그냥 넘어간다.ㅠㅠ

아래는 Math 클래스를 이용하여 사용하는 예제! 한줄만 보고 넘어가자.

System.out.print(Math.max(35));

이것의 출력 결과는 5가 나온다. 누가 봐도 3, 5 중 큰수는 5 이고 5가 출력되었으니 두수중 큰값을 리턴한다고 알수 있다.  또한 중요한 점이 하나더 있는데 잘보면 클래스를 가지고 바로 메소드를 호출하고 있다. 보통 메소드의 호출은 객체를 통해서 이루어지는데 이 경우는 좀 특이하다. 결론을 말하자면 저 max 라는 메소드는 static 으로 되어 있다. 선생님 말씀으론 static 으로 정의되어 있는 함수는 바로 호출하여 사용가능 하다고 하신다.

static 맴버 변수
마지막 이다. 선생님께서 작성해 주신 소스는 좀 복잡해 보여서 다시 작성해 보았다.

package kr.ac.busanit.time;
class A
{
  static int a = 0;
  int b = 0;
}
public class TimeTest2 
{
  public static void main(String[] args) 
  {
    A obj1 = new A();
    A obj2 = new A();
    A obj3 = new A();
    
    ++obj1.a;
    ++obj1.b;
    ++obj2.a;
    ++obj2.b;
    ++obj3.a;
    ++obj3.b;
    
    System.out.println("obj1 a = " + obj1.a + " obj1 b = " + obj1.b);
    System.out.println("obj2 a = " + obj2.a + " obj2 b = " + obj2.b);
    System.out.println("obj3 a = " + obj3.a + " obj3 b = " + obj3.b);
  }
}


자. 소스를 해석해 보자.
class A
{
  static int a = 0;
  int b = 0;
}

일단 클래스가 보인다. 안에는 맴버 변수가 딸랑 두개 있다. a, b ! 둘다 int 형인데 a는 특이하게 static 이 붙어 있다. 요것이 키포인트? 둘다 0으로 초기화 되어 있다. 다음으로 넘어가자.

A obj1 = new A();
A obj2 = new A();
A obj3 = new A();

A 클래스를 이용해서 객체 3개를 만들고 있다. 셋쌍둥이 처럼 이름또한 비슷하다. 쉽게 1번 2번 3번 객체라고 봐도 될듯. 다음으로 넘어가자.

++obj1.a;
++obj1.b;
++obj2.a;
++obj2.b;
++obj3.a;
++obj3.b;


어렵지 않다. 잘보면 1번 객체 2번 객체 3번 객체가 각각의 a 및 b 맴버 변수들을 ++ 시켜 주고 있다. 그리고 지금 이 문장이 가능한 이유는 a, b 변수들이 디폴트로 public 속성을 가지고 있고 이 때문에 외부에서 맴버 변수를 바로 접근 가능하기 때문이다..  어쨌든 중요한건 ++ 이다. 다음 으로 넘어가자.

System.out.println("obj1 a = " + obj1.a + " obj1 b = " + obj1.b);
System.out.println("obj2 a = " + obj2.a + " obj2 b = " + obj2.b);
System.out.println("obj3 a = " + obj3.a + " obj3 b = " + obj3.b);


이 문장은 그저 1번 2번 3번 객체의 a 와 b 값을 찍어주고 있다. 바로 실행 결과를 확인하자.



짜잔~ 예상 했었던가? a 가 3으로 나올줄......이야. 잘 생각해보면 세 객체 모두 a 가 1, b 도 1 이 나와야 정상인것 같다. 하지만 결과는 좀 이상하다. 짐작 하건데 저 위에서 특이하다고 했던 A 클래스의 static 맴버가 이런 일을 벌인 주범일 것이다. 자.. 위 소스의 속사정을 그림으로 보자.



자 이 그림은 무엇을 뜻하는가? 그렇다! 붕어빵 과 붕어빵 틀이다. 클래스와 객체 사이의 관계를 묘사하기위해 이런 예를 들어 보았다. 그림이 좀 이해 안가는 면이 있지만.. 일단 설명부터 해보겠다.
붕어빵 틀을 잘 보자. 이건 바로 A 클래스다. A 클래스에서 붕어빵 3개를 찍어냈는데 그게 obj1 붕어빵, obj2 붕어빵, obj3 붕어빵 이다. 또 유심히 들여다 보자. 붕어빵 3형제(뜬금없이)는 모두 int b 라는 맴버를 각자 가지고 있다. 그런데 static int a라는 맴버 변수는 없다. 그게 어딧는지 잘 찾아보자. 찾기 쉬우라고 티나게 적어 두었다. 바로 붕어빵 틀 아래에 빨간색으로 예쁘게 적어 두었다.
이제 좀 그림이 이해 가는지 모르겠다. 결론 부터 말하자면 static 이라고 적어둔 저 int 형 a 클래스 맴버는 단 한개만 존재하며 그 1개는 이후 만들어지는 붕어빵들에게 공유 당한다. 다 바로 이것 때문이다.  정확한 이해를 위해 그럼 몇장 더 넣어 본다.









연속 총 4장의 그림이다. 잘 보면 3장까지 붕어빵 틀 아래에 있는 static int a 맴버 변수는 붕어빵 삼형제 에게 공유 당해 버렸다. 결국 4번째 그림까지 가서는 static int a 는 3이 되어 버렸고, 각자 가지고 있던 int b 는 1이 된 것이다.

일단 이번 static int a 붕어빵 삼형제에게 공유당한 사건은 여기서 마무리 짓는다. 그리고 이런식의 사용은 어디서 활용해 볼수 있을까 생각해 본다. 그러나! 생각이 없다.;; 왜 쓰는지 잘 모르겠다. 한가지 경험에 따르면 C 언어 에서도 이처럼 static 변수를 함수에서 쓰게 되면 이와 비슷한 효과를 보게 된다. 원래 함수는 두번 호출 되든 세번 호출되든 함수내에 있는 변수들은 언제나 호출시 에는 신선한? 상태가 된다. 하지만 이 static 변수를 쓰게 되면 더이상 신선하지 않다.
예를 들어 test 함수안에 static in a 가 있는데 첫번째 호출에서 이 값을 1 로 바꾸고 나왔다. 그리고 두번째 호출에서는 이 값에 5를 더하고 나왔다. 그리고 세번째 호출에서 이 값을 읽어 보았다. 결과는 6이 나온다. 1 + 5 는 6 이기 때문이다. 이러한 특성을 이용하면 함수가 호출된 횟수를 저장할수도 있다. 실제로 함수가 호출된 횟수를 가지고 무엇을 할수 있는지는 잘 모른다. 어설 프게 생각해 보면 만약 MakeCharacter 라는 함수가 있는데 이 함수 안에서 static 변수가 있어 호출 될때마다 1식 카운터 하고 그 값을 리턴한다고 생각해 보자. 이 함수의 역할이 캐릭터를 만들어 주는 함수라면 리턴값을 가지고 캐릭터가 몇개나 생성되었는지 알수 있게 된다. 글이 길어 졌다.....ㅠ

728x90