2008. 8. 23. 16:10

Part 6. AWT - II 컴포넌트의 이벤트 처리(1)

이벤트, 이벤트 소스, 이벤트 핸들러란?
이벤트(event) : 프로그램과 사용자간의 상호작용을 위해서 사용자가 키보드나 마우스 등의 장치를 통해서 응용 프로그램에 어떤 요구를 하는 사건을 말합니다.
이벤트 리스너(event listener) : 이벤트를 기다렸다가 이벤트가 발생하게 되면 전달되어오는 이벤트 소스 객체로 적당한 처리를 하게 되는 객체를 말합니다.
이벤트 소스(event source) : 버튼(Button)이나 스크롤바(Scrollbar)와 같이 이벤트가 발생한 컴포넌트 객체를 말합니다.

이벤트 처리 방법
1. 이벤트 패키지 임폴트 : import java.awt.event.*;
2. 처리할 이벤트에 대한 이벤트 리스너의 설계
public class ButtonListener implements ActionListener {
}
ActionListener는 이벤트 처리를 담당하는 이벤트 리스너 인터페이스
ButtonListener는 ActionListener 인터페이스를 구현하여 만든 이벤트 리스너 클래스
이벤트 리스너 클래스(ButtonListener)는 인터페이스를 구현한 것이므로 인터페이스 내부의 추상 메서드를 오버라이딩 해서 구현해야 한다.
ActionListener 인터페이스는 actionPerformed 메서드 한개만 추상 메서드로 가진다.
이 메서드는 버튼에 이벤트가 발생하면 호출되는 메서드이다.
3. 이벤트 리스너 객체를 생성한다.
4. 이벤트를 받아들인 컴포넌트 객체에 리스너를 등록한다.

아래는 레드,블루 버튼을 클릭하는 이벤트가 발생하면 배경이미지가 바뀌는 이벤트 처리
소스이다.
===================================================================================
package pack05;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
// FrameEx가 두가지 역할(프레임으로서, 이벤트처리객체로서)을 하도록
class FrameEx extends Frame implements ActionListener{
 Button redBtn, blueBtn ;
 // actionPerformed의 전달인자인 ActionEvent가 이벤트소스에 정보를 갖고 있다.
 public void actionPerformed(ActionEvent e){
  System.out.println(e.getActionCommand()+"버튼이 눌림");
  if(e.getActionCommand().equals("빨간색")){
   setBackground(Color.RED);
  }
  else if(e.getActionCommand().equals("파란색")){
   setBackground(Color.BLUE);
  }
 }
 FrameEx(){
  // 배치관리자로 플로우 레이아웃 지정
  // 빨간색 버튼을 redBtn으로
  // 파란색 버튼을 blueBtn으로 생성
  // 프레임 크기를 300,200으로 설정
  // 눈에 보이도록 한다.
  setLayout(new FlowLayout());
  redBtn=new Button("빨간색");
  blueBtn=new Button("파란색");
  // 이벤트 소스인 버튼과 이벤트처리객체를 연결해 주어야 한다.
  redBtn.addActionListener(this);
  blueBtn.addActionListener(this);
  add(redBtn);
  add(blueBtn);
  setSize(300,200);
  setVisible(true);
 }
}
public class Ex01 {
 public static void main(String[] args) {
  new FrameEx();
 }
}
===================================================================================
윈도우 창에 X버튼을 누르면 창이 닫히도록 하기(윈도우리스너 인터페이스로 구현)
package training;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
// [닫기]버튼이 눌리면 창이 닫히도록 WindowListener 인터페이스 상속 받음
class FrameEvent extends Frame implements ActionListener, WindowListener{
 public void windowActivated(WindowEvent arg0) {  
 }
 public void windowClosed(WindowEvent arg0) {
 }
 // [닫기]버튼이 눌러졌을 때 호출되는 메소드
 public void windowClosing(WindowEvent arg0) {
  dispose();
  System.exit(0);
 }
 public void windowDeactivated(WindowEvent arg0) {
 }
 public void windowDeiconified(WindowEvent arg0) {
 }
 public void windowIconified(WindowEvent arg0) {
 }
 public void windowOpened(WindowEvent arg0) {
 }
 public void actionPerformed(ActionEvent e) {
  System.out.println(e.getActionCommand()+"버튼이 눌림");
  Object o=e.getSource();
  if(o==redBtn){
   setBackground(Color.RED);
  }
  else if(o==blueBtn){
   setBackground(Color.BLUE);
  }
 }
 // 클래스 내의 멤버(필드)로 버튼에 대한 레퍼런스 변수를 선언해야 한다.
 Button redBtn, blueBtn;
 FrameEvent(){
  setLayout(new FlowLayout());
  redBtn=new Button("빨간색");
  blueBtn=new Button("파란색");
  // 이벤트 소스인 버튼과 이벤트 처리 객체와 연결
  redBtn.addActionListener(this);
  blueBtn.addActionListener(this);
  // 이벤트 소스인 프레임과 이벤트 처리 객체와 연결
  this.addWindowListener(this);
  add(redBtn);
  add(blueBtn);
  setSize(400,300);
  setVisible(true);
 }
}
public class Ex01 {
 public static void main(String[] args) {
  new FrameEvent();
 }
}
===================================================================================
윈도우 어댑터 클래스를 통한 구현
package pack01;
import java.awt.Button;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
class FrameEvent extends Frame implements ActionListener{
 public void actionPerformed(ActionEvent e) {
  System.out.println(e.getActionCommand()+"버튼이 눌림");
  Object o=e.getSource();
  if(o==redBtn){
   setBackground(Color.RED);
  }
  else if(o==blueBtn){
   setBackground(Color.BLUE);
  }
 }
 // 클래스 내의 멤버(필드)로 버튼에 대한 레퍼런스 변수를 선언해야 한다.
 Button redBtn, blueBtn;
 FrameEvent(){
  setLayout(new FlowLayout());
  redBtn=new Button("빨간색");
  blueBtn=new Button("파란색");
  // 이벤트 소스인 버튼과 이벤트 처리 객체와 연결
  redBtn.addActionListener(this);
  blueBtn.addActionListener(this);
  add(redBtn);
  add(blueBtn);
  setSize(400,300);
  setVisible(true);
  SubClass sc=new SubClass();
  addWindowListener(sc);
 }

 // 창이 닫히도록 하기 위해서 필요한 메소드 : WindowClosing();
 class SubClass extends WindowAdapter{
  public void windowClosing(WindowEvent e) {
   dispose(); // 창(프레임)을 소멸
   System.exit(0); // 프로세스 죽임
  }
 }
} // Frame 클래스의 끝
public class Ex01 {
 public static void main(String[] args) {
  new FrameEvent();
 }
}
===================================================================================
외부 클래스와 내부 클래스
package pack01;
class Outer{ // 외부클래스
 int data=100;
 class Inner{ // 내부클래스 : 외부클래스의 모든 멤버를 가져다 사용할 수 있다.
  int b=200;
  public void printData(){
   System.out.println(data);
  }
 } // inner 클래스의 끝
} // outer 클래스의 끝
public class Ex02 {
 public static void main(String[] args) {
 
 }
}
===================================================================================
package pack01;
import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
class FrameExit extends Frame{
 FrameExit(){
  setSize(400,300);
  setVisible(true);
  // 이벤트 소스와 이벤트 처리 객체와 연결되어야 함
  this.addWindowListener(
   // WindowAdapter를 슈퍼로 갖는 서브클래스 설계 시작
   new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
     System.out.println("WindowClosing 메소드 호출");
     dispose();
     System.exit(0);
    }    
   } // 클래스 설계 끝
  ); // addWindowListener 메소드 호출
 }

}
public class Ex03 {
 public static void main(String[] args) {
  new FrameExit();
 }
}
===================================================================================

2008. 8. 21. 15:41

Part 6. AWT - I AWT를 이용한 GUI 작성

자바에서는 AWT로 GUI컴포넌트(버튼, 체크박스 등)을 제공하며 AWT를 사용하기 위해서
import java.awt 를 해야합니다.
아래는 awt의 계층도 입니다.

사용자 삽입 이미지
Container 클래스
자바는 GUI 컴포넌트를 컨테이너 내부에 배치하는데 컨테이너의 종류에는 Window, Frame, Panel, Dialog 등이 제공됩니다. 오늘은 Frame과 Panel 에 대해서 살펴봅니다.

Frame 클래스에서 사용되는 메서드입니다.

생성자

public Frame ( )

기본 생성자입니다.

public Frame (String title)

타이틀바의 문자열을 지정합니다.

메서드

public String getTitle()

타이틀바의 문자열을 가져옵니다.

public boolean isResizable()

창의 크기 변경 여부를 알아냅니다.

public void setMenuBar(MenuBar mb)

프레임에 메뉴를 등록합니다.

public void setResizable(boolean b)

창의 크기 변경 여부를 지정합니다.

public void setTitle(String title)

타이틀바의 문자열을 지정합니다.

================= 프레임 객체를 생성하고 사이즈와 보임을 지정하여 창을 출력 ==========
package training;
import java.awt.Frame;
public class Ex01 {
 public static void main(String[] args) {
  Frame f=new Frame("Frame Demo"); // 프레임 객체 생성
  f.setSize(300, 200); // 사이즈 지정 후,
  f.setVisible(true); // 보여지도록
 }
}
===================================================================================
배치관리자(Layout Manager)
프레임에 컴포넌트를 어떤 식으로 추가할 것인지 레이아웃(Layout)을 관리하는 클래스
FlowLayout, BorderLayout, GridLayout 세개를 살펴보도록 하겠습니다.

컨테이너마다 디폴트로 제공하는 배치관리자가 아래의 그림처럼 다릅니다.
Frame과 Dialog는 BorderLayout 이고 Panel과 Applet은 FlowLayout 입니다.
사용자 삽입 이미지
===================================================================================
컨테이너에게 배치관리자를 지정하는 절차
1. 객체 생성 : FlowLayout f = new FlowLayout();
2. 프레임에 지정
    Frame f = new Frame();
    f.setLayout(layout);
3. add 메소드로 프레임에 컴포넌트를 추가
    Button bt01 = Button01();
    f.add(bt01);
============== 프레임의 배치관리자로 플로우 레이아웃 설정하기 ======================
플로우 레이아웃 : 컨테이너 안에 가로 방향으로 물 흐르듯이 배치할때 사용
package pack01;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
class FrameEx extends Frame{
 FrameEx(){
 방법 1. /*FlowLayout f1=new FlowLayout();// 배치관리자 객체 생성
  setLayout(f1); */ // 프레임에 해당 배치관리자를 설정*/
  /*방법 2.*/ setLayout(new FlowLayout()); // 배치관리자 객체 생성하여 프레임에 설정
  // 컴포넌트를 생성해서 프레임에 추가
  add(new Button("버튼1"));
  add(new Button("버튼2"));
  add(new Button("버튼3"));
  add(new Button("버튼4"));
  add(new Button("버튼5"));
  setSize(300,200); // 크기 설정
  setVisible(true); // 보여지도록 해야 한다.
 }
}
public class Ex01 {
 public static void main(String[] args) {
  new FrameEx();
 }
}
============= 프레임의 배치관리자로 보더 레이아웃 설정하기 ==========================
보더 레이아웃 : 컴포넌트의 위치를 동,서,남,북,센터로 배치할 때 사용
add 메서드를 통해 컴포넌트를 컨테이너에 추가할 때 동,서,남,북,센터 위치를 지정한다.
package pack02;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Frame;
class FrameEx extends Frame{
 FrameEx(){
  /*FlowLayout f1=new FlowLayout();// 배치관리자 객체 생성
  setLayout(f1);// 프레임에 해당 배치관리자를 설정*/
  setLayout(new BorderLayout()); // 배치관리자 객체 생성하여 프레임에 설정
  // 컴포넌트를 생성해서 프레임에 추가
  add(new Button("버튼1"), BorderLayout.NORTH);
  add(new Button("버튼2"), BorderLayout.WEST);
  add(new Button("버튼3"), BorderLayout.CENTER);
  add(new Button("버튼4"), BorderLayout.EAST);
  add(new Button("버튼5"), BorderLayout.SOUTH);
  setSize(300,200); // 크기 설정
  setVisible(true); // 보여지도록 해야 한다.
 }
}
public class Ex01 {
 public static void main(String[] args) {
  new FrameEx();
 }
}
============= 프레임의 배치관리자로 그리드 레이아웃 설정하기 ========================
그리드 레이아웃 : 행의 개수와 열의 개수를 지정하여 행렬의 구조로 컴포넌트를 배치
package pack03;
import java.awt.Button;
import java.awt.Frame;
import java.awt.GridLayout;
class FrameEx extends Frame{
 FrameEx(){
  /*FlowLayout f1=new FlowLayout();// 배치관리자 객체 생성
  setLayout(f1);// 프레임에 해당 배치관리자를 설정*/
  //setLayout(new GridLayout()); // 배치관리자 객체 생성하여 프레임에 설정
  //setLayout(new GridLayout(3,2)); // 원하는 행,렬을 지정할 수 있다.
  //setLayout(new GridLayout(2,3));
  setLayout(new GridLayout(1,5));
  // 컴포넌트를 생성해서 프레임에 추가
  add(new Button("버튼1"));
  add(new Button("버튼2"));
  add(new Button("버튼3"));
  add(new Button("버튼4"));
  add(new Button("버튼5"));
  setSize(300,200); // 크기 설정
  setVisible(true); // 보여지도록 해야 한다.
 }
}
public class Ex01 {
 public static void main(String[] args) {
  new FrameEx();
 }
}
========================== Panel 컨테이너 =========================================
Panel 클래스는 여러 개의 컴포넌트들을 그룹별로 모을때 주로 사용하는 프레임과 같은 일종의 컨테이너로서 그룹 단위로 한꺼번에 이벤트를 처리할 수 있다.
또한 컴포넌트들을 그룹별로 모아 둔 패널을 Frame과 같은 다른 컨테이너에 붙여야 한다.
package pack04;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Panel;
// Frame의 상속을 받는 서브 클래스를 생성한 후에
// 생성자를 추가하여 프레임의 크기 설정한 후, 보여지도록
class FrameTest extends Frame {
 Panel p1,p2,p3; // 패널 레퍼런스 변수 선언(컨테이너)
 Button b1,b2,b3,b4,b5;
 FrameTest(){
  p1=new Panel();// 생성자 안에서 인스턴스 생성
  p2=new Panel();
  p3=new Panel();
  //p1.setBackground(Color.YELLOW);
  //p2.setBackground(Color.PINK);
  //p3.setBackground(Color.BLUE);
  setBackground(Color.RED);
  // p1 북쪽, p2 가운데, p3 남쪽에 배치
  add(p1, BorderLayout.NORTH);
  add(p2, BorderLayout.CENTER);
  add(p3, BorderLayout.SOUTH);
  b1=new Button("버튼1");
  b2=new Button("버튼2");
  b3=new Button("버튼3");
  b4=new Button("버튼4");
  b5=new Button("버튼5");
  // 패널도 컨테이너이기에 버튼을 붙일 수 있다.
  p1.add(b1); p1.add(b2);
  p2.add(b3);
  p3.add(b4); p3.add(b5);
  b1.setVisible(false); b2.setVisible(false);
  p3.setVisible(false);
  // setSize(300,200); // 크기를 임의 설정
  pack(); // 크기 자동 설정
  setVisible(true);
 }
}
public class Ex01 {
 public static void main(String[] args) {
  new FrameTest();
 }
}
===================================================================================
2008. 8. 20. 14:35

Part 5. 자바에서 자주 사용되는 클래스 IV - 컬렉션 클래스와 제네릭

/*배열은 원소의 자료형태가 결정
int []s=new int[5];
String []name=new String[5];

컬렉션 클래스의 설계 원리
- 자료구조(알고리즘) - 해쉬 테이블 혹은 ArrayList가 일반화되어 정의
- 원소들을 자바의 최상위 클래스 Object 형으로 저장하도록 설계
- 원소가 추가되는 순간에 업캐스팅

ArrayList []s=new ArrayList(); // 점수를 저장하기 위한 용도 : 원소가 Object형
ArrayList []name=new ArrayList(); // 이름을 저장하기 위한 용도 : 원소가 Object형
[1.4버전까지의 컬렉션 클래스의 단점]
1. 하나의 ArrayList 객체의 원소 자료형이 혼합되어서 사용될수 있다는 단점
2. 원소를 추출한 후에는 다운캐스팅을 위한
   명시적인 형변환을 해야함(캐스트 연산자로)
   name.add("이강국");
   name.add(10); // 원소의 자료형이 혼합되어 사용 됨
   String str=(String)name.get(0); // Object 형이므로, 다운캐스팅이 필요하다.

제너릭 클래스 : 컬렉션 클래스에서 사용되는 JDK5.0에서 새롭게 나온 개념
하나의 클래스가 알고리즘을 적용받을 수 있는 원소의 자료형을 다양하게 하기 위해서
제너릭 클래스란 개념을 5.0에서 가져다 사용
제너릭 클래스는 로직만 구현하고 원소들의 자료형태에 대해서는 언급하지 않음

객체를 생성할 때에는 자료형을 언급해야 함.
ArrayList<Integer> []s=new ArrayList<Integer>(); // 원소 : Integer
ArrayList<String> []name=new ArrayList<String>(); // 원소 : String
name.add("조현상");
name.add(10); // 에러 남 : 원소의 자료형이 혼합되어 사용되지 못함
String str=name.get(0); // 다운캐스팅이 필요없다.*/

// 문자를 가져다가 대문자로 출력하기
package training;
import java.util.ArrayList;
public class Ex01 {
 public static void main(String[] args) {
  // JDK 1.4에서 사용되던 컬렉션 클래스
  ArrayList list = new ArrayList();
  list.add("apple"); // 내부적으로 저장될때에는 Object 형으로 업캐스팅됨 
  list.add("banana");
  list.add("orange");
  list.add("3"); // 단점 : 원소들의 자료형이 혼합되어 사용
  // list에 저장된 원소들을 갖다가 대문자로 출력하기
  for(int i=0;i<list.size();i++){
   System.out.println(list.get(i)+" ");
   // 대문자로 변환하기 위한 메소드로 toUpperCase가
   // String 클래스에서 제공된다.
   // 단점 : 다운 캐스팅을 위해 캐스트 연산자를 기술해야 한다.
   String item=(String)list.get(i);
   System.out.println(item.toUpperCase());
  } 
 }
}
===============점수 5개로 총점과 평균을 구하기 1. 배열 ==============================
// 배열 : 배열의 크기가 변경되지 않는다. 배열에 원소를 추가하거나 삭제할 수 없다.
// ArrayList : 배열의 크기가 변경 되고 배열에 원소를 추가하거나 삭제할 수 있다.
public class Ex03 {
 public static void main(String[] args) {
  int [] a={90, 85, 70, 80, 95};
  int tot=0;
  for(int i=0;i<a.length;i++){
   System.out.println(a[i] + " ");
   tot+=a[i];
  }
  System.out.println("\n 총점 : " + tot);
  System.out.println("\n 평균 : " + tot/a.length);
 }
}
===============점수 5개로 총점과 평균을 구하기 2. ArrayList===========================
import java.util.ArrayList;
public class Ex04 {
 public static void main(String[] args) {
  ArrayList list=new ArrayList();
  System.out.println("원소의 갯수 : "+list.size());
  list.add(90);
  list.add(85);
  list.add(70);
  list.add(80);
  list.add(95);
  System.out.println("원소의 갯수 : "+list.size());
  int tot=0;
  for(int i=0;i<list.size();i++){
   System.out.println(list.get(i) + " ");
   tot=tot+(Integer)list.get(i);
   // tot=tot+list.get(i);
  }
  System.out.println("\n 총점 : " + tot);
  System.out.println("\n 평균 : " + tot/list.size());
 }
}
===================================================================================
package training;
import java.util.ArrayList;
public class Ex01 {
 public static void main(String[] args) {
  // JDK 1.4에서 사용되던 컬렉션 클래스
  ArrayList list = new ArrayList();
  list.add("apple"); // 내부적으로 저장될때에는 Object 형으로 업캐스팅됨 
  list.add("banana");
  list.add("orange");
  list.add("3"); // 단점 : 원소들의 자료형이 혼합되어 사용
  // list에 저장된 원소들을 갖다가 대문자로 출력하기
  for(int i=0;i<list.size();i++){
   System.out.println(list.get(i)+" ");
   // 대문자로 변환하기 위한 메소드로 toUpperCase가
   // String 클래스에서 제공된다.
   // 단점 : 다운 캐스팅을 위해 캐스트 연산자를 기술해야 한다.
   String item=(String)list.get(i);
   System.out.println(item.toUpperCase());
  } 
 }
}
===================================================================================
package training;
import java.util.ArrayList;
public class Ex02 {
 public static void main(String[] args) {
  // 단점 : 원소들의 자료형이 혼합되어 사용되지 않도록
  // 단점 : 다운 캐스팅하지 않도록
  // JDK5.0부터 컬렉션 클래스를 제너릭 클래스 형태로 제공
  // 객체 생성 시, 원소의 자료형들을 결정하기
  // 제너릭_컬렉션 클래스 <원소의 자료형>
  ArrayList<String> list = new ArrayList<String>();
  list.add("apple");  
  list.add("banana");
  list.add("orange");
  // list.add(3); // 원소들의 자료형이 혼합되어 사용되지 않도록
  for(int i=0;i<list.size();i++){
   System.out.println(list.get(i)+" ");  
   String item=list.get(i);
   // String형으로 다운캐스팅 하지 않아도 된다.
   System.out.println(item.toUpperCase());
  } 
 }
}
===================================================================================
package training;
import java.util.Enumeration; // import를 하기 위해서 <ctrl>+<shift>+o(영문)
import java.util.Hashtable;
public class Ex03 {
 public static void main(String[] args) {
  // key, value를 쌍으로 저장하는 해쉬 테이블
  // "이강국" 65.5
  Hashtable<String, Double>ht=new Hashtable<String, Double>();
  ht.put("이강국", 63.5);
  ht.put("김재필", 68.5);
  ht.put("김경윤", 70.5);
  System.out.println(ht.get("이강국"));
  // 해쉬 테이블에 저장된 모든 정보를 얻어오기
  Enumeration<String> name=ht.keys();
  while(name.hasMoreElements()){
   String key=name.nextElement();
   Double weight=ht.get(key);
   System.out.println(key + " : " + weight);
  }
 }
}
===================================================================================

2008. 8. 3. 01:40

자바 공부에 좋은 사이트 1

javachobo.com

에 가면 소스를 내려 받을 수도 있고 강의 동영상 내려 받을 수도 있다.

좋은 자료야..

잘 보고~~

또 플래쉬로 된 자바의 메모리 구조나 이런 것들은 그 카페에 공유 되어 있으니 참조 바람~

그럼 수고~
2008. 7. 24. 00:13

chapter 8. 인터페이스와 추상 클래스

다형성을 제대로 사용하려면 100% 추상클래스인 인터페이스가 필요하다.
추상 클래스(abstract class)란 인스턴스를 만들 수 없는 클래스이다.

클래스를 추상 클래스로 만드는 방법은 클래스를 선언할 때 앞에 abstract 만 붙여주면 된다.
abstract class Canine extends Animal {
    public void roam() {
    }
}
추상 클래스란, 아무도 그 클래스의 새로운 인스턴스를 만들 수 없는 클래스를 의미한다.

abstract class Canine extends Animal {
    public void roam() {
    }
}
==============================================================
public class MakeCanine {
    public void go() {
        Canine c;           <- 상위클래스가 추상클래스인 경우에도 하위클래스 객체를 상위클래스 레퍼런스에
        c = new Dog();        대입하는 것은 가능하기 때문에 이 부분은 문제가 없다
        c = new Canine(); <- Canine 클래스는 추상클래스기 때문에 컴파일시 에러가 난다.
        c.roam();
    }
}

추상 클래스는 확장하지 않으면 쓸모가 없다.
추상 클래스를 만들었을 때 실제 실행 중에 일을 처리하는 것은 그 추상 클래스의 하위 클래스 인스턴스이다.
추상 클래스가 아닌 것을 구상클래스라고 한다. 상속트리의 맨 마지막 클래스들

추상 메소드
추상 클래스가 반드시 확장해야 하는 클래스라면 추상 메소드는 반드시 오버라이드 해야하는 메소드이다.
추상 메소드에는 몸통이 없다.
public abstract void eat();  <- 메소드 몸통이 없으므로 세미콜론으로 끝내면 된다.
추상 메소드를 만들 때는 클래스도 반드시 추상 클래스로 만들어야 한다.
추상 메소드를 만드는 이유는 실제 메소드 코드를 전혀 집어넣지는 않았더라도 일련의 하위클래스를 위한
규약(protocol)의 일부를 정의하기 위해서이다.
추상 메소드는 다형성을 활용하기 위해 "이 유형에 속하는 모든 하위클래스 유형에는 이 메소드가 있어야 한다"는
것을 지정하기 위해 필요하다.

"추상 메소드를 반드시 구현해야 한다"는 의미는 추상 메소드에서 선언한 리턴 유형과 호환가능한 리턴 유형을 가진 추상 메소드가 아닌 메소드를 만들어야 한다는 의미이다.

자바에서 모든 클래스는 Object라는 클래스를 확장한 것이다.
명시적으로 다른 클래스를 확장하지 않은 클래스는 자동으로 Object를 확장한 클래스로 정의됩니다.

Object 클래스를 대략 살펴보자.
equals(Object o) <- 두 객체를 '같은'것으로 볼 수 있을지 판단하는 메소드
getClass() <- 어떤 클래스의 인스턴스인지 알 수 있도록 그 객체의 클래스를 리턴한다.
hashCode() <- 그 객체에 해당하는 해시코드(고유 ID)를 출력한다.
toString() <- 클래스명과 몇가지 별로 잘 쓰이지 않는 숫자가 포함된 String 메시지 출력

Object를 추상 클래스로 선언하지 않는 이유는 모든 클래스에서 무조건 오버라이드할 필요 없이 그대로 사용할 수 있는 메소드를 구현해놓은 코드가 들어있기 때문이다.
Object 유형의 객체를 만들 수는 있지만, 실제로 그렇게 할 일은 별로 없다.
Object 클래스의 두가지 용도
1. 임의 클래스에 대해 어떤 작업을 하는 메소드를 만들 때 다형적 유형으로 사용하는 경우
2. 자바에 있는 모든 객체에서 실행 중에 필요한 진짜 메소드 코드를 제공하기 위해서

Object 유형의 다형적 레퍼런스를 쓸 때 나오는 객체(ArrayList<Object>)는 실제 객체의 유형이나 목록에 객체를 추가했을 때의 레퍼런스 유형하고는 상관 없이 무조건 Object 유형의 레퍼런스로 나오게 된다.

컴파일러에서 어떤 메소드를 호출할 수 있는지 결정할 때는 실제 객체 유형이 아닌 레퍼런스 유형을 기준으로 따진다.

ArrayList<Object>에 객체를 집어넣으면 그 객체는 원래의 유형과는 무관하게 Object로만 처리할 수 있다.
ArrayList<Object>로부터 레퍼런스를 받아오면 그 레퍼런스는 항상 Object유형입니다.

어떤 객체인지 모를 경우에는 instanceOf 연산자를 써서 확인한다.
if (d instanceOf Dog) {
    Dog d=(Dog) o;
컴파일러에서는 레퍼런스가 참조하는 실제 객체의 클래스가 아닌 레퍼런스 변수를 선언할 때 지정한 유형의 클래스를 확인하다.

인터페이스(interface)
인터페이스를 정의하려면 public interface Pet {...} <- class 대신에 interface 키워드를 사용한다.
인터페이스를 구현하려면 public class Dog extends Canine implements Pet {...} <- implements 뒤에 인터페이스 명을 지정해줍니다.

public interface Pet {
    public abstract void beFriendly() ;   <- 인터페이스에 들어있는 모든 메소드는 추상메소드므로 반드시
    public abstract void play() ;            <- 세미콜론으로 끝나야합니다.
}

서로 다른 상속 트리에 속한 클래스에서도 같은 인터페이스를 구현할 수 있습니다.
또한 한 클래스에서 인터페이스 여러 개를 구현할 수도 있습니다.

어떤 클래스를 하위클래스로 만들지, 추상 클래스로 만들지, 아니면 인터페이스로 만들지를 어떻게 결정하는가!
클래스를 새로 만들려고 할 때 그 클래스가 (Object를 제외) 다른 어떤 유형에 대해서도 'A는 B다' 테스트를 통과할 수 없다면 그냥 클래스를 만듭니다.
어떤 클래스의 더 구체적인 버전을 만들고 어떤 메소드를 오버라이드하거나 새로운 행동을 추가해야 한다면 하위클래스를 만듭니다(클래스를 확장합니다.)
일련의 하위클래스에서 사용할 틀(template)을 정의하고 싶다면, 그리고 모든 하위클래스에서 사용할 구현코드가 조금이라도 있다면 추상 클래스를 사용합니다. 그리고 그 유형의 객체를 절대 만들 수 없게 하고 싶다면 그 클래스를 추상 클래스로 만듭니다.
상속 트리에서의 위치에 상관없이 어떤 클래스의 역할을 정의하고 싶다면 인터페이스를 사용하면 됩니다.

핵심정리
1. 클래스를 만들 때 인스턴스를 만들 수 없게 하고 싶다면 abstract 키워드를 사용해서 추상 클래스로 만든다.
2. 추상 클래스에는 추상 메소드와 추상 메소드가 아닌 메소드 모두를 집어넣을 수 있다.
3. 클래스에 추상 메소드가 하나라도 있으면 그 클래스는 추상 클래스로 지정해야 한다.
4. 추상 메소드에는 본체가 없으며 선언 부분은 세미콜론으로 끝납니다(중괄호를 쓰지 않는다)
5. 상속 트리에서 처음으로 나오는 구상 클래스에서는 반드시 모든 추상 메소들르 구현해야 합니다
6. 자바에 들어있는 모든 클래스는 직접 또는 간접적으로 Object(java.lang.Object)의 하위클래스입니다.
7. 메소드를 선언할 때 인자, 리턴 유형을 Object로 지정해도 됩니다.
8. 어떤 객체에 대해서 메소드를 호출하려면 그 객체를 참조하는 레퍼런스 변수 유형의 클래스(또는 인터페이스)에 그 메소드가 있어야만 합니다. 객체의 실제 유형하고는 무관합니다. 따라서 Object 유형의 레퍼런스 변수로는 Object 클래스에 정의되어 있는 메소드만 호출할 수 있습니다. (레퍼런스가 참조하는 객체의 유형과는 무관)
9. Object 유형의 레퍼런스 변수는 캐스팅을 하지 않고는 다른 유형의 레퍼런스에 대입할 수 없습니다. 한 유형의 레퍼런스 변수를 하위 유형의 레퍼런스 변수에 대입하고 싶다면 캐스팅을 이용할 수 있습니다. 하지만 힙에 들어있는 객체가 캐스팅 호환 가능한 유형이 아니라면 실행 중에 캐스팅에 실패할 수도 있습니다.
10. 자바에서는 다중 상속을 허용하지 않습니다. 클래스는 단 하나만 확장할 수 있습니다. (직속 상위 클래스는 하나밖에 없다)
11. 인터페이스는 100% 추상 클래스이고 추상 메소드만 정의한다 정의는 interface로 하고 구현은 implements로 한다.
12. 클래스는 여러 개의 인터페이스를 구현할 수 있다.
13. 인터페이스의 모든 메소드는 자동으로 public 메소드, 그리고 abstract 메소드가 되기 때문에 인터페이스를 구현하는 클래스에서는 인터페이스에 들어있는 모든 메소드를 구현해야 한다.
14. 하위클래스에서 어떤 메소드를 오버라이드했는데, 상위클래스 버전을 호출하고 싶다면 super라는 키워드를 사용하면 된다. ex : super.runReport();
2008. 7. 22. 23:20

chapter 7. 상속과 다형성

상속이란 하위클래스가 상위클래스의 멤버(인스턴스 변수, 메소드)를 물려 받는 것
하위클래스는 별도의 메소드와 인스턴스 변수를 추가할 수 있고 상위클래스의 메소드를 오버라이드 할 수 있다.
그러나 인스턴스 변수는 오버라이드 하지 않는다. 인스턴스 변수가 특별한 행동을 정의하지 않기 때문에...

상속 트리의 설계
1. 공통적인 속성과 행동이 들어있는 객체를 찾는다.
2. 공통적인 상태와 행동을 나타내는 클래스를 설계한다.
3. 특정 하위클래스 유형에만 적용되는 행동(메소드 구현)이 필요한지 결정한다.
4. 공통적인 행동이 필요한 하위클래스를 두 개 이상 찾아서 추상화의 개념을 더 폭넓게 활용할 수 있는지 찾는다.
5. 클래스 계층 구조를 완성한다.

하위클래스에서 상위클래스에 있는 버전의 메소드와 새로 오버라이드한 버전의 메소드 둘 다 사용하고 싶을 경우에는 먼저 상속 받은 메소드를 실행시킨 후, 하위클래스에서만 실행할 메소드를 처리한다.

상속을 활용하여 설계할 때의 주의점
어떤 클래스가 다른 클래스(상위클래스)를 더 구체화한 형식이라면 상속을 활용한다.
같은 일반적인 형식에 속하는 여러 클래스에서 공유해야 하는 어떤 행동(구현된 코드)이 있다면 상속을 활용한다.
그러나 객체지향 프로그래밍에 있어서 상속의 핵심 기능 가운데 하나지만 행동을 재사용하는 데 있어 무조건 최선의 방법이 아니라는 점을 주의해야 한다.
상위클래스와 하위클래스 사이의 관계가 위에 있는  두 가지 규칙에 위배된다면 어떤 코드를 다른 클래스에서
재사용할 수 있다는 이유만으로 상속을 사용하면 안된다.
하위클래스와 상위클래스 사이에서 'A는 B이다' 관계가 성립하지 않는다면 상속을 사용하지 않는다.

상속의 주요 특징
자바에서는 하위클래스가 상위클래스를 확장한다고 한다.
하위클래스는 상위클래스에 있는 모든 public으로 지정한 인스턴스 변수와 메소드를 상속하지만 private로 지정한 인스턴스 변수와 메소드는 상속하지 않는다.
메소드는 오버라이드 가능하지만 인스턴스 변수는 오버라이드 하지 않는다.
'A는 B이다' 라는 관계를 확인한다.(한방향으로만 작동한다.)
하위클래스에서 메소드를 오버라이드하고 하위클래스의 인스턴스 변수에 대해 그 메소드를 호출하면 오버라이드된 버전의 메소드가 호출된다.(맨 밑에 있는것이 호출 됨)
B라는 클래스가 A라는 클래스를 확장하고 C는 B를 확장한다면 클래스 B는 클래스 A이고 클래스 C는 클래스 B이고 클래스 C는 클래스 A이다.

상속의 장점
코드가 중복되는 것을 방지할 수 있다.
(그러나 특정 메소드의 인자나 리턴 형식, 메소드명과 같이 상위클래스에 있는 것 가운데 하위클래스에서 반드시 필요로 하는 것을 변경하면 심각한 문제가 생길 수 있다.)
일련의 클래스를 위한 공통적인 규약(protocol)를 정의할 수 있다.

다형성의 이해
객체 선언과 대입의 세 가지 단계
Dog myDog = new Dog();
    1.          2.      3.
1. 레퍼런스 변수를 선언한다.
2. 객체를 만든다.
3. 객체와 레퍼런스를 연결한다.
주요사항은 레퍼런스 유형과 객체 유형이 똑같아야 한다는 점이다.

하지만 다형성을 활용하면 레퍼런스와 객체가 다른 유형이어도 됩니다.
Animal myDog = new Dog();

다형성을 사용하면 레퍼런스 유형을 실제 객체 유형의 상위클래스 유형으로 지정할 수 있다.

Animal[] animals = new Animal[5];
animals [0] = new Dog();
animals [1] = new Cat();
animals [2] = new Wolf();
animals [3] = new Hippo();
animals [4] = new Lion();

for (int i = 0 ; i < animals.length ; i++ ) {
  animals[i].eat();
  animals[i].roam();

의문사항
인자와 리턴 유형에 대해서도 다형성을 적용할 수 있다.


대부분의 상속계층은 넓지만 깊지는 않다.
클래스의 소스코드를 직접 접근할 수 없지만 어떤 클래스의 메소드가 작동하는 방식을 바꾸고 싶을 때는 클래스를 확장한 후 메소드를 오버라이드해서 더 나은 코드를 만들면 된다.
상속이 안되는 경우.
클래스를 private로 지정할 경우
클래스를 final로 지정할 경우
내부 클래스(inner class)인 경우
오버라이드할 수 없도록 만들고 싶은 경우에는 final 클래스를 사용한다.

상위클래스의 메소드를 오버라이드할 때이 규칙
1. 인자는 동일해야 하고, 리턴 유형은 호환 가능해야 한다.
2. 메소드를 더 접근하기 어렵게 만들면 안된다(public 메소드를 오버라이드해서 private 메소드를 만드는 등등)

메소드 오버로딩이란 이름이 같고 인자 목록이 다른 메소드 두 개를 만드는 것.
오버로딩을 활용하면 호출하는 쪽의 편의를 위해 같은 메소드를 서로 다른 인자 목록을 가진 여러 버전으로 만들 수 있다. 오버로드하는 메소드에서는 상위클래스에서 정의한 다형성 계약을 이행하지 않아도 되기 때문에 메소드 오버로딩은 훨씬 더 융통성이 좋다고 할 수 있다.
규칙 & 장점
1. 리턴 유형이 달라도 된다.
2. 리턴 유형만 바꿀 수는 없다.(인자 목록을 반드시 변경해야 한다.)
3. 접근 단계를 마음대로 바꿀 수 있다.
2008. 7. 22. 20:45

2장 미션임파서블 - 객체지향을 이해하라.

구조적 방법론에서는 작은 단위로 나누어서 해결하는 '나누어서 정복한다(divide and conquer)' 모토로 운영이 된다. 하지만 객체지향 방법론에서의 문제 해결은 추상화(abstraction), 캡슐화(encapsulation), 모듈성(modularity), 계층성(hierarchy)이라는 4가지 개념으로 요약할 수 있다.
객체지향 방법론이 구조적 방법론과 배타적인 개념을 강조하는 것이 아니라 구조적 방법론의 장점을 포함하는 것이다.

추상화는 보다 중요하고 필수적인 사항을 다루려고 하는 것이며 이때 중요한 것은 무엇이 중요한지, 무엇이 덜 중요한 것인지를 직관적으로 판단할 수 있어야 한다는 것이다.
캡슐화는 말 그대로 중요하고 세부적인 구현 방법에 대한 자세한 사항을 캡슐 안에 꼭꼭 숨겨놓는 것이다.
캡슐화는 데이터 감추기(data hiding)라고도 한다.
모듈성이란 크고 복잡한 것을 좀 더 작고 관리할 수 있는 조각으로 나누어, 이들 조각을 독립적으로 개발할 수 있게 하는 것이다. 객체로 명명한다.
계층성이란 보편적인 것을 상위에 두고 특수한 것을 하위에 두는 것을 말한다. 등급이나 순서에 따라 계층적인 구조로 조각들을 배열하는 것을 말한다.

객체란 애플리케이션에서 명확한 한계와 의미를 갖는 사물이나 개념 또는 추상화로서, 특성과 행위 그리고 정체성을 하나의 단위로 포함하여 캡슐화하는 것을 말한다.
특성 : 해당 객체에 저장되어 있는 정보
행위 : 해당 객체가 행동하거나 반응하는 방법을 결정
정체성 : 해당 객체를 다른 객체와 구별 짓게 하는 식별 값
2008. 7. 21. 00:28

1장 객체지향 - 이것이 무엇에 쓰는 물건인고

객체지향 언어가 사용된 스몰토크(Smalltalk)에서는 MVC(model-view-controller) 패턴이 사용되었는데
MVC 패턴이란 데이터를 관리하는 놈(model), 데이터를 보여주는 놈(view), 프로그램의 흐름을 좌지우지하는 놈(controller)으로 구성되어 있다.
요즘 나오는 대부분의 소프트웨어 아키텍처(software architecture)들은 이러한 유형을 따르고 있다.
ex : C++, 윈도우 DNA 아키텍처, 자바 등
3계층의 구성 요소들 사이의 프로토콜 즉 통신 방법에는 여러가지가 있다.
ex : COM/DCOM/COM+, COBRA, EJB, XML 등

소프트웨어 개발방법
1. 구조적 방법 : 대표언어 C이며 하나의 프로그램이나 시스템은 잘게 쪼개진 여려 개의 세부적인 것으로 구성되어 있는 것으로 간주되는 개념이다. 피라미드 형식이나 그물과 같은 구조의 형식을 지칭한다.
구조적 언어의 단점 중 하나는 프로그래밍 언어가 프로그램의 실행 흐름 즉, 절차에 치중한다는 것이다.
하지만 프로그램에서 중요한 것은 절차만이 아니며 중요정도에서는 데이터가 더 큰 비중이 있다고 할 것이다.
그러나 절차적 프로그래밍 언어에서는 데이터와 그것을 처리하는 절차를 구분시켜 놓으므로써, 데이터를 소홀히 하는 단점이 있다.
이것의 결과로 데이터와 그 데이터를 처리하는 절차가 분리되어 있어서 코드가 복잡해 지거나 조금 더 편리해지기 위해 보다 중요한 데이터를 전역 변수로 정의하여 권한이 없는 다른 함수에서도 접근할 수 있게 하는 문제점을 노출하기도 한다.
2. 객체지향 방법의 핵심은 데이터와그 데이터를 처리하는 절차를 하나의 단위로 묶어 놓는데에 있다. 또 같은 단위에 속해있는 절차 즉, 코드를 통해서 데이터에 접근하게 함으로써 보다 중요한 데이터를 보호할 수 있게 한다.

C++이 객체지향 개념을 포함하며 본격적인 객체지향 언어로 입지를 굳혔으나, 인터넷의 특징을 손쉽게 활용할 수 있는 자바언어가 대두되게 되었다.
자바 언어에서 모든 객체는 포인터 대신에 레퍼런스(reference)를 통해 접근하게 되며, 객체의 소멸은 자바 가상 머신(Java virtual machine) 안에 있는 가비지 컬렉터(garbage collector)가 대신 처리해주므로 프로그래머는 delete 연산자를 사용하지 않아도 되게 되었다.

객체지향 방법은 하나의 소프트웨어 시스템을 여러 개의 객체로 구성된 것으로 간주한다. 각 객체는 독립적으로 고유한 기능과 서비스를 제공하며, 전체 소프트웨어 시스템을 구성하는 하나의 논리적인 구성 요소가 된다.
각 객체가 전체에 포함된 일부로서가 아니라 독립적인 것으로 간주되기 때문에 해당 객체의 기능르 독립적으로 향상시킬 수도 있고 다른 소프트웨어 시스템에도 재사용할 수 있으며, 또한 사용자의 요구 사항이 변경되는 경우에도 손쉽게 대응할 수 있다는 이점을 갖게 된다.

용어 설명
1. 애플릿(applet) : 웹 서버에서 다운로드된 후에는 웹 서버의 자원을 사용하지 않고 사용자와 상호작용하며 작업을 수행하는 자바 언어로 만든 작은 애플리케이션
2. 모델링 언어 UML(Unified Modeling Language) : 설계자와 사용자가 서로 의사 소통을 하는데 사용하는 말을 모델링 언어라 하며, 객체지향 방법론에서는 주로 UML이라는 모델링 언어를 사용한다.
UML이란 소프트웨어 시스템을 시각화하고 명세화하고 구축하고 문서를 작성하는데 사용하는 그래픽으로 표현되는 언어(a graphical language for visualizing, specifying, constructing, and documenting the artifacts of a software-intensive system) 라고 정의된다.

P.S 객체지향 이야기는 한장씩 읽어나가야 하는데 첫장을 포스팅 하기 너무 힘들었다. 왜냐고??? 좀 읽다가 졸았기 때문에... ㅋㅋ 아무튼 이 시간에 포스팅을 시작해서 좋다. ^0^
2008. 7. 20. 23:01

chapter 6. 자바 API를 알아봅시다.

자바에는 클래스 수백 개가 내장되어 있습니다. 우리는 필요한 것을 찾는 방법을 알아내어 자신의 애플리케이션에서 사용할 부분만 새로 만들면 됩니다.

자바 API에서 클래스는 패키지 단위로 묶여 있습니다.
API에 들어있는 클래스를 사용하려면 그 클래스가 어떤 패키지에 들어있는지 알아야합니다.
자바 패키지의 종류는
java.lang : 필수 요소
java.util : 자바 유틸리티
java.swing : 스윙 클래스

어떤 클래스를 사용하려면 클래스의 전체 이름을 알아야합니다.
ArrayList 는 java.util 패키지에 들어있으며 java.util.ArrayList 로 쓰면 됩니다.

패키지의 클래스를 사용할지 알려주는 방법은 아래와 같습니다.
1. import 선언문을 쓰는 경우
소스 코드 파일 맨 위에서 import 선언문을 사용합니다.
import java.util.ArrayList;
public class MyClass {...}
2. 일일이 입력합니다.
코드에서 일일이 전체 이름을 입력합니다. 언제,어디서나 직접 타이핑을 해야한다는 단점이 있네요.
객체를 선언하고 인스턴스를 만들 때:
java.util.ArrayList<Dog> list = new java.util.ArrayList<Dog>;
인자 유형으로 사용할 때 :
public void go(java.util.ArrayList<Dog> list) {}
리턴 유형으로 사용할 때 :
public java.util.ArrayList<Dog> foo() {}

ArrayList에 들어있는 메소드는 아래와 같습니다.
add(Object elem) : 객체 매개변수(elem)를 목록에 추가합니다. -> 뭔가를 집어넣을 때
romove(int index) : index 매개변수로 지정한 위치에 있는 객체를 제거합니다 -> 뭔가를 제거할 때
indexOf(Object elem) : 객체 매개변수(elem)의 인덱스 또는 -1을 리턴합니다 -> ArrayList에 들어있는 어떤 것의 위치를 확인하거나 알고 싶을 때
isEmpty() : 목록에 아무 원소도 없으면 '참'을 리턴합니다 -> ArrayList가 비어있는지 확인할 때
size() : 현재 목록에 들어있는 원소의 개수를 리턴합니다 -> ArrayList의 크기(원소의 개수)를 알고 싶을 때
length : 일반 배열의 길이(원소의 개수)를 알고 싶을 때
cotains(Object elem) : 객체 매개변수(elem)에 매치되는 것이 있으면 '참'을 리턴합니다.
get(int index) : 주어진 index 매개변수 위치에 있는 객체를 리턴합니다.

1. ArrayList는 필요에 따라 그 크기가 동적으로 바뀝니다. 객체가 추가되면 커지고, 제거되면 작아집니다.
2. ArrayList에 저장할 객체 유형은 유형 이름을 <>안에 집어넣은 형태의 유형 매개변수(type parameter)로 선언합니다. ex : ArrayList <Button> 은 Button(또는 Button의 서브클래스) 유형의 객체만 넣을 수 있는 ArrayList
3. ArrayList에는 원시 유형의 값은 저장할 수 없고 일반 객체만 저장할 수 있지만, 컴파일러에서 원시값을 Object 객체로 감싸고 그 객체를 원시 유형이 아닌 ArrayList에 저장하는(또는 그와 반대로 가는) 일을 자동으로 처리해줍니다.
4. java.lang을 제외한 다른 패키지에 들어있는 클래스를 사용하려면 전체 이름을 알려줘야 합니다.

ArrayList와 일반 배열의 차이점
1. 기존의 일반 배열은 만들어질 때부터 유형과 이름이 정해지지만, ArrayList에서는 ArrayList 유형의 객체만 만들면 됩니다. 객체를 추가하거나 제거하면 자동으로 커지거나 작아지므로 크기를 따로 지정할 필요가 없어요.
ex : new String[2]
      new ArrayList <String>{}
2. 객체를 일반 배열에 집어넣을 때는 위치를 지정해야 합니다.(즉 0이상, 배열의 길이에서 1을 뺀 숫자 이하의 인덱스를 지정해야 합니다) ex : myList[1] = b;
ArrayList는 add(정수,객체) 메소드를 써서 인덱스를 지정하거나 그냥 add(객체)라고만 하면 자동으로 새로 추가된 객체가 들어갈 자리가 만들어집니다. ex : myList.add(b);
3. 배열을 쓸 때는 자바의 다른 부분에서는 쓰지 않는 배열 전용 문법을 써야 합니다.
하지만 ArrayList는 일반 자바 객체기 때문에 특별한 전용 문법을 쓸 필요가 없습니다.
ex : myList[1] -> 배열전용 대괄호([])는 배열에서만 쓰이는 특별한 기호입니다.
4. 자바 5.0에서는 배열이 매개변수화되어 있습니다.
ArrayList<String> : <>안의 String은 "유형 매개변수(type parameter)"입니다.

초강력 부울 표현식
'AND'와 'OR' 연산자 '&&' , '||'
1. 가격이 300달러 이상, 400달러 미만이면 X를 선택한다
if (price >= 300 && price <=400 ) {
camera = X;
}
2. 카메라 브랜드가 총 열개 있는데 그 중 브랜드 몇개에 대해 어떤 작업을 하고 싶을 경우
if (brand.equals("A") || brand.equals("B")) {
A 브랜드 또는 B 브랜드에만 적용할 내용
}
같지 않음 ( != , ! )

P.S 소스 코드를 이해하는 부분은 2차 개정판에서 다룰 예정입니다.
Heas First 자바를 두번이상 읽을수 있는 시간을 꼭 내겠습니다. ^^;

2008. 7. 16. 19:11

chapter 5. 프로그램 만들기

클래스 개발 일반론

1. 클래스에서 어떤 것을 해야 하는지 파악한다.
2. 인스턴스 변수와 메소드 목록을 작성합니다.
3. 메소드를 만들기 위한 준비 코드를 만듭니다.
4. 메소드에 대한 테스트 코드를 만듭니다.
5. 클래스를 구현합니다.
6. 메소드를 테스트합니다.

각 클래스별로 준비 코드, 테스트 코드, 실제 코드
준비 코드 : 논리 위주의 유사코드를 표현한다. (어떻게 해야할지가 아니라 무엇을 해야할지를 기술한다.)
테스트 코드 : 실제 코드를 테스트하고 작업이 제대로 처리되는지 확인하기 위한 클래스 또는 메소드(준비 코드를 기준으로 작성한다.)
실제 코드 : 클래스를 실제로 구현한 코드

익스트림 프로그래밍 방법(XP)
조금씩, 하지만 자주 발표한다.
사이클을 반복해서 돌리면서 개발한다.
스팩에 없는 것은 절대 집어넣지 않는다.
테스트 코드를 먼저 만든다.
모든 테스트를 통과하기 전에는 어떤 것도 발표하지 않는다.
조금씩 발표하는 것을 기반으로 하여 현실적인 작업 계획을 만든다.
모든 일을 단순하게 처리한다.
두 명씩 팀을 편성하고 모든 사람이 대부분의 코드를 알 수 있도록 돌아가면서 작업한다.
효과
야근을 안한다. 항상 정규 일과 시간에만 작업을 할 수 있다.
기회가 생기는 족족 언제 어디서든 코드를 개선 할 수 있다.

for 순환문

for ( int i=0 ; i < 100 ; i++ ) { }
이 코드는 정수형 변수 i를 0으로 초기화하고 i가 100보다 작을 경우 i를 후증가연산자로 계속해서 순환하라는 뜻

int i = 0
초기화 : 변수를 선언하는 부분
i < 100
부울 테스트 : 조건 테스트가 들어가는 자리(부울값을 리턴하는 메소드가 들어가는 경우도 있다.)
i++
반복 표현식 : 순환문이 한 번 반복될때마다 실행할 내용이 들어감

for와 while의 차이점
while 순환문은 부울 테스트만 들어갈 수 있다. 초기화 및 반복 표현식을 내장 시킬 수 없다.
반복 횟수를 알 수 없을 때 어떤 조건이 만족되는 동안 계속 반복하는 경우에 유용하다.

for 순환문은 반복 횟수를 알고 있을 경우 유용하다.

++ , -- : 선/후 증가/감소 연산자
변수의 앞 뒤에서 쓰일 경우 변수 +1, -1 의 효과를 가져온다.
int x = 0 ; int z = ++x ;
int x = 0 ; int z = x++ ;

향상된 for 순환문
" String[] nameArray = { " ", " ", " " }; "
for (String name : nameArray) { }
위 코드는 nameArray에 들어 있는 각 원소에 대해서 각각의 원소를 name 변수에 저장한 다음 순환문을 실행시킨다.

String name : 선언된 변수(nameArray) 유형인 String와 반드시 동일해야 한다.
: -> in의 의미
nameArray : 반복 작업의 대상이 되는 원소들의 컬렉션

String을 int로 변환하는 방법
Integer.parseInt("3")
Integer : 자바 클래스 라이브러리에 있는 클래스로 숫자를 나타내는 String을 받아서 그 문자열을 진짜 숫자로 변환 해 주는 기능이 있는 클래스
parseInt : String을 그 문자열이 나타내는 int로 '파싱하는' 방법을 알고 있는 Integer 클래스 안에 들어있는 메소드