2011. 1. 20. 16:17
JDBC개념과 역할
  * JDBC 구조
     - JDBC(Java Database Connectivity)
     - 데이터베이스 벤더와 상관없이 동일한 개발이 가능함

  * JDBC 드라이버
     - JDBC 드라이버는 사용하고자 하는 데이터베이스 벤더 별로 제공 된다.


(ojdbc14.jar)를 jar 파일로 추가



 * JDBC 프로그래밍 단계

1. JDBC 드라이버 로드
    : System.sepProperty()
2. 데이터베이스 연결
3. Statement생성
4. SQL 문 전송
    : java.sql.Statement -> [DB조회] excuteQuery(),   <-  Query를 넣어서...
                                      [DB변경]  excuteUpdate()
5. 결과 받기 [excuteQuery()의 경우]
   java.sql.ResultSet(state마다 하나씩밖에 없다.
6. 연결 해제
   java.sql.Connection -> close()   


> 코드보기(select문에 대한 sql문 처리)

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBTest {
 public static void main(String[] args) {
  
  //DB는 전부다 1521 포드로 연결
  //jdbc:oracle:thin:@117.17.93.103:1521:orcl
  String url = "jdbc:oracle:thin:@117.17.93.103:1521:orcl";
  String username="scott";
  String passwd = "tiger";
  
  //쿼리문 하나 만듦.
  String sql = "select * from customers";
  Connection con = null;
  Statement st = null;
  ResultSet rs = null;   //finally에서 사용하기 위해 Connection ~ ResultSet까지의 객체를 try~catch문 밖에 선언
  try {
   //[1.JDDB드라이버 로드]
   Class.forName("oracle.jdbc.driver.OracleDriver"); //예외처리
   
   //[2. 데이터 베이스 연결.. 드라이버 연결(connection 얻어오는 작업)]
   con = DriverManager.getConnection(url, username, passwd); //예외처리
   
   //3. Statement 생성 
   st = con.createStatement();
   //statement객체 쿼리를 담을 수 있는 객체, 쿼리를 제공하는 메소드가 담겨져 있는 클래스
   
   
   //4.SQL문 전송
   rs = st.executeQuery(sql);
   //쿼리한 결과가 ResultSet으로 반환됨.
   
   //5. 결과 받기
   //resultset은 처음에는 컬럼명에 있음..
   //rs의 위치는  rs-> name       phone           address
   //      rs.next()이순신    010-2222-1111     서울시 노원구 중계동
   //다음줄로 넘길려면 rs.next()
   System.out.println("customers 테이블 정보");
   System.out.printf("%-10s %-16s %-30s\n", "  이름", "|     전화번호", "|       주소");
   System.out.println("-----------------------------------------------------");
   while(rs.next()){
    System.out.printf("%-10s %-16s %-30s\n",
      rs.getString("name"), rs.getString("phone"), rs.getString("address"));
    //컬럼 이름으로 준것, index로 줘서 rs.getString(1) 도 동일
    //rs.getString(2)
    //rs.getString(3)
   }
   System.out.println("-----------------------------------------------------");
      
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally{
   //6. 연결끊기(해제) (가장 마지막에 만들어진 객체 부터.. 닫아줌)
   if( rs != null) try { rs.close();} catch (SQLException e) { e.printStackTrace();}
   if( st != null) try { st.close();} catch (SQLException e) { e.printStackTrace();}
   if( con != null) try { con.close();} catch (SQLException e) { e.printStackTrace();}
   
  }
 }
}
[console]
customers 테이블 정보
  이름       |     전화번호       |       주소                   
-----------------------------------------------------
김영숙        010-1112-2222    서울시 노원구 중계동                  
홍길동        010-2222-2222    서울시 노원구 중계동                  
이순신        010-3333-2222    서울시 노원구 중계동                  
장동건        010-4444-2222    서울시 노원구 중계동                  
-----------------------------------------------------



* 데이터 베이스 연결
- Connection conn = DriverManger.getConnection(JDBC_url, "아이디", "비밀번호");
- JDBC_URL 구성 = JDBC:orcle:thin:@IP주소:포트:SID
- 엑세스 DB인 경우 = JDBC:odbc:song

*statement 생성 및 쿼리 실행
- Statement 객체 생성후 SQL 문장을 변수 처리부와 함께 문자열로 구형
- 쿼리가 복잡해 질수록 성능저하 및 관리에 어려움이 있음
 //Statement객체 : 쿼리를 담는 객체 (가장 간편히 사용) static한 string을 받아서..(변동이 없는 쿼리물을 담음)
 //PreparedStatement (satement객체 상속받음) 쿼리문이 계속 바뀌는 경우
//CallofStatement(preparedStatement 객체 상속받음) 아주~~ 성능이 좋아야 하는 경우, 쿼리문을 DB가 갖고 있음.
                                                                          (쿼리문을 db에 proceduer로 등록시킴..)
-Statement stmt = conn.createStatement();
 쿼리 - 데이터변경 : executeUpdate()
       - 데이터읽기: executeQury()

*PreparedStament생성 및 쿼리 실행(insert나 add같은 경우)
 - PreparedStatement 객체 생성시 SQL 문장을 미리 생성하고 변수 부는 별도의 메서드로 대입하는 방식으로 성능과 관리 면에서 모두 권장되는 방식임
PreparedStatement pstmt = conn.prepareStatement("insert into test values(?,?)");
pstmt.setString(1,request.getParameter("username");
pstmt.setString(2,request.getParameter("email");
pstmt.executeUpdate();


* 결과받기
 ResultSet rs = pstmt.executeQuery();
- ResultSet은 커서 개념의 연결 포인터
- 기본적으로 next()메서드를 통해 로우 이동


* 연결해제
  - Connection 을 close()해 주지 않으면 사용하지 않은 연결이 유지됨
  - DB 자원을 낭비하게 됨. conn.close();
   


>customers에 insert하고, select * from customer 한것.. (sql문을 두개 사용)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public class DBTest {
 public static void main(String[] args) {
  
  //DB는 전부다 1521 포드로 연결
  //jdbc:oracle:thin:@117.17.93.103:1521:orcl
  String url = "jdbc:oracle:thin:@117.17.93.103:1521:orcl";
  String username="scott";
  String passwd = "tiger";
  
  String sql2 = "insert into customers values(?,?,?)";
  String sql = "select * from customers";
  Connection con = null;
  PreparedStatement st = null;
  PreparedStatement st2 = null;
  ResultSet rs = null;   //finally에서 사용하기 위해 Connection ~ ResultSet까지의 객체를 try~catch문 밖에 선언
  try {

   //[1.JDDB드라이버 로드]
   Class.forName("oracle.jdbc.driver.OracleDriver"); //예외처리
   
   //[2. 데이터 베이스 연결.. 드라이버 연결(connection 얻어오는 작업)]
   con = DriverManager.getConnection(url, username, passwd); //예외처리
   
   //3. PreparedStatement 생성
   st2 = con.prepareStatement(sql2); //sql문 넘겨받음
   st2.setString(1, "흐흐흐3"); //자바문법이기 때문에 표시를 " " 로 해 주어야
   st2.setString(2, "010-1234-5678");
   st2.setString(3, "서울시 몽땅 우리집");
   st2.executeUpdate();
   //새로운 레코드를 추가

   st = con.prepareStatement(sql); //sql문 넘겨받음
   rs = st.executeQuery(); //이미 쿼리문을 st가 갖고 있기에 (sql)할 필요 없다.
   //쿼리한 결과가 ResultSet으로 반환됨.
   
   //5. 결과 받기
   //resultset은 처음에는 컬럼명에 있음..
   //rs의 위치는  rs-> name       phone           address
   //      rs.next()이순신    010-2222-1111     서울시 노원구 중계동
   //다음줄로 넘길려면 rs.next()
   System.out.println("customers 테이블 정보");
   System.out.printf("%-10s %-16s %-30s\n", "  이름", "|     전화번호", "|       주소");
   System.out.println("-----------------------------------------------------");
   while(rs.next()){
    System.out.printf("%-10s %-16s %-30s\n",
      rs.getString("name"), rs.getString("phone"), rs.getString("address"));
    //컬럼 이름으로 준것, index로 줘서 rs.getString(1) 도 동일
    //rs.getString(2)
    //rs.getString(3)
   }
   System.out.println("-----------------------------------------------------");
      
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally{
   //6. 연결끊기 (가장 마지막에 만들어진 객체 부터.. 닫아줌)
   if( rs != null) try { rs.close();} catch (SQLException e) { e.printStackTrace();}
   if( st != null) try { st.close();} catch (SQLException e) { e.printStackTrace();}
   if( con != null) try { con.close();} catch (SQLException e) { e.printStackTrace();}
   
  }
 }
}


customers 테이블 정보
  이름       |     전화번호       |       주소                   
-----------------------------------------------------
김영숙        010-1112-2222    서울시 노원구 중계동                  
홍길동        010-2222-2222    서울시 노원구 중계동                  
이순신        010-3333-2222    서울시 노원구 중계동                  
장동건        010-4444-2222    서울시 노원구 중계동                  
kim        111-1111-1111    서울시 강북                       
하하하        010-1234-5678    서울시 몽땅 우리집                   
호호호        010-1234-5678    서울시 몽땅 우리집                   
흐흐흐        010-1234-5678    서울시 몽땅 우리집                   
흐흐흐2       010-1234-5678    서울시 몽땅 우리집                   
흐흐흐3       010-1234-5678    서울시 몽땅 우리집                   
-----------------------------------------------------
Statement 객체  //사용할 때 쿼리문을 준다.
Statement st = con.createStatement();
st.executeQuery("select * from customer");   //쿼리문은 쿼리 할 때 들어감
//st.executeUpdate("insert....   delete... update...);

PreparedStatement 객체  : 객체를 만들때 쿼리문을 줌
PreparedStatement ps = con.prepareStatment("select ~~~~ ");
ps.executeQuery();  //argument없이
ps.executeUpdate(); //처음에 con.prepareStatement(" ") 할때 insert, delete, update가 들어간 경우..

만약
PreparedStatement ps = con.prepareStatment("insert into table values(?, ?, ?)");
ps.setInt(1,100);
ps.setString(2, "kdkdkd");
ps.executeQuery();





>Prepared Statement 이용하여 데이터 추가하기 (코드)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBTest {
 public static void main(String[] args) {
  
  //DB는 전부다 1521 포드로 연결
  //jdbc:oracle:thin:@117.17.93.103:1521:orcl
  String url = "jdbc:oracle:thin:@117.17.93.103:1521:orcl";
  String username="scott";
  String passwd = "tiger";
  
  String sql = "insert into customers values(?,?,?)";
  Connection con = null;
  PreparedStatement st = null;
 

  try {
   Class.forName("oracle.jdbc.driver.OracleDriver");
   con = DriverManager.getConnection(url, username, passwd); 

   st = con.prepareStatement(sql); // prepareStatement 객체는 만들때 argument를 받는다.
   st.setString(1, "이름1");
   st.setString(2, "전화번호111");
   st.setString(3, "주소2222");
   st.executeUpdate();   //st.execute()해도 됨... 차이는
   //excupteUpdate 하면 integer값이 반환되고,
   //excute()하면 boolean이 반환됨
   
   
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally{
   //6. 연결끊기 (가장 마지막에 만들어진 객체 부터.. 닫아줌)
   if( st != null) try { st.close();} catch (SQLException e) { e.printStackTrace();}
   if( con != null) try { con.close();} catch (SQLException e) { e.printStackTrace();}
   
  }
 }
}

Quantun DB 에 가보면 제대로 insert 된 것을 확인할 수 있다.




>이름이 홍길동인 row 검색..
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBTest {
 
 public static void main(String[] args) {
  
  //DB는 전부다 1521 포드로 연결
  //jdbc:oracle:thin:@117.17.93.103:1521:orcl
  String url = "jdbc:oracle:thin:@117.17.93.103:1521:orcl";
  String username="scott";
  String passwd = "tiger";
  
  String sql = "select * from customers where name like ?"; //쿼리문 수행
  Connection con = null;
  PreparedStatement st = null;
  ResultSet rs = null; //쿼리문 이기에 결과를 받아야 한다.
  
  try {
   Class.forName("oracle.jdbc.driver.OracleDriver");
   con = DriverManager.getConnection(url, username, passwd); 
   st = con.prepareStatement(sql); // prepareStatement 객체는 만들때 argument를 받는다.
   st.setString(1, "홍길동%");
   st.executeUpdate();  
   rs = st.executeQuery();
   System.out.println("실행결과");
   while(rs.next()){
    System.out.println(rs.getString(1) + " : " + rs.getString(2) +
      " : " + rs.getString(3));
   }
       
   
  } catch (Exception e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } finally{
   //6. 연결끊기 (가장 마지막에 만들어진 객체 부터.. 닫아줌)
   if( rs != null) try { rs.close();} catch (SQLException e) { e.printStackTrace();}
   if( st != null) try { st.close();} catch (SQLException e) { e.printStackTrace();}
   if( con != null) try { con.close();} catch (SQLException e) { e.printStackTrace();}
   
  }
 }
}


실행결과
홍길동     : 010-2222-2222    : 서울시 노원구 중계동
name은 char(10)으로 정의되어 있으므로...
like와 "홍길동%"를 써줘야 .... 검색이 가능









DB만 전담하는 object를 만들자.
DAO(Database Access Object)
1) DB를 쓰고 싶으면 DAO를 통해서 하도록 하겠다.
(뒤에오는 DB의 규모가 얼마인지에 따라서 DAO의 규모를 한개로 할건지, 다중으로 할건지...)











Posted by Triany
2011. 1. 12. 21:15



[동아일보] 신청시기-자격요건 지정, 학교-홈피 통해 찾아야

대학 2학년이 되는 김모 씨는 ‘올해는 꼭 외부 장학금을 신청하겠다’는 각오를 다지고 있다. 지난해 학교 장학금을 신청했으나 탈락했던 기억을 떠올리면 지금도 아찔하다. 김 씨는 “장학금을 타지 않으면 350만 원이 넘는 등록금을 혼자 충당하기 어려워 끙끙댔다”고 회상했다. 그때 친구가 “다양한 외부 장학금을 노려 보라”고 조언했다. 그러나 김 씨는 대체 어디서 외부 장학금 정보를 찾아야 할지 몰라 우물쭈물하고 있다.

대부분의 대학생이 장학금을 몰라서 신청하지 못한다. 장학금은 학교에서 주는 것 말고도 국가 장학금, 재단 장학금, 기업 장학금 등 다양하다. 저소득층 장학금, 성적우수 장학금, 해외 유학생을 위한 장학금, 이공계 장학금 등 종류도 많아 그 수만 130개가 넘는 것으로 추정된다.

그러나 문제는 외부 장학금의 종류와 현황을 알 수 있는 곳이 없다는 점이다. 장학금 관련 정보를 얻기에 가장 좋은 곳은 학과 사무실이나 학생복지처다. 대부분 학과장이나 총장 추천을 받아야 해 관련 정보가 학과 사무실이나 학생복지처를 통해서만 공고되는 경우가 많기 때문이다. 적극적으로 스스로 정보를 찾아야 한다. 대부분 신청 시기와 자격이 정해져 있기 때문에 미리 알아두면 목표를 세우고 준비할 수 있어 유리하다.

○ 국가 장학금

‘미래드림 장학금’은 학생 명의의 수급자 증명서를 발급받을 수 있는 기초생활수급자 가정 대학생에게 주는 장학금이다. 입학금 및 수업료, 기성회비 등을 지원해 1인당 연간 450만원을 받는다." 한국장학재단 홈페이지(www.kosaf.go.kr)에서 온라인 신청한 뒤 대학에 수급자 증명서, 장학금 신청서 및 서약서, 성적증명서를 제출하면 대학의 심사 결과에 따라 장학금 지원 여부가 결정된다. 이달에 신청 공고가 날 예정이다.

‘희망드림 장학금’은 차상위 저소득층 가정 대학생에게 주는 장학금으로 올해 1학기 1인당 115만 원을 지원한다. 복지제도 증명서나 보험료 납부 확인서를 발급받고 온라인으로 신청한 뒤 역시 소속 대학에 신청서와 증빙서류를 내면 심사를 거쳐 선정된다. 이달에 신청 공고가 날 예정이다.

학부 성적우수 장학금도 있다. ‘이공계 국가장학생’은 이공계열 학과에 입학한 신입생 중 대학수학능력시험 성적 우수자와 대학별 입학 성적 우수자에게 지원된다. 한국장학재단 홈페이지(www.kosaf.go.kr)에서 신청서를 작성하고 증빙서류를 소속 대학에 제출하면 된다. 대학 4년간 학비 전액을 지원한다. 자세한 일정은 홈페이지를 참조하면 된다.

‘인문사회계 국가장학생’은 4년제 인문사회계열에 입학한 대학생 중 수능 성적 우수자와 대학별 입학 성적 우수자에게 제공한다. 한국장학재단 홈페이지(www.kosaf.go.kr)에서 신청서를 작성한 뒤 증빙서류를 소속 대학에 제출해야 한다. 최대 4년간 등록금 전액을 지원한다. 1666-5114

○ 기업 및 재단 장학금

‘미래에셋 박현주재단’은 성적이 우수하지만 경제적 여건이 어려운 상경(50%), 인문사회(30%), 이공계열(20%) 학부 재학생 300명을 선발한다. 직전 학기 또는 평균 평점이 3.5점 이상인 자로, 선발되면 1년간 등록금 전액을 받을 수 있다. 지원자는 1월 17∼28일 각 학교 장학담당 부서에 지원신청서, 자기소개서, 서약서, 성적증명서, 가족관계증명서, 부모 소득증빙자료 등을 제출하면 된다. 자세한 사항은 홈페이지(foundation.miraeasset.com) 참조.

‘삼성장학금’은 미래를 주도할 글로벌 인재 육성을 위해 2012년 해외 대학 진학 예정자 50명 내외에게 장학금을 지급한다. 장학생에게는 학부 과정부터 최대 박사 과정까지 학비와 현지 생활비를 지원한다. 8월 1∼31일 삼성장학회 홈페이지(www.ssscholarship.com)에 지원서, 자기소개서, 에세이를 제출한 뒤 성적증명서(SAT, GRE 등), 어학검정증명서(토플, JLPT 등), 전국 및 세계 규모 대회 수상 실적 증명서류, 논문과 연구실적, 고등학교 및 대학·대학원 성적증명서를 우편으로 제출하면 된다. 1차 합격자에 한해 면접을 보고 최종 선발한다. 02-2014-6790

‘한국고등교육재단’은 4년제 대학 1∼3학년 1학기에 재학 중인 학생들을 대상으로 대학특별장학생(40명)과 한학연수장학생(10명)을 선발한다. 졸업 때까지 매월 소정의 장학금을 지급한다. 2월 21일∼3월 11일 지원서와 추천서를 홈페이지(www.kfas.or.kr)에서 제출한 뒤 지원서 사본과 대학 성적증명서를 우편 또는 방문 제출해야 한다. 이후 1차 필기시험(3월 19일)과 2차 면접을 통해 선발한다. 02-552-3641

‘앨트웰민초 장학재단’은 4년제 대학 1학년에 재학 중이고 평균 평점 A 이상인 학생 중 향후 공직, 언론, 연구 및 기타 전문직 진출 희망자에게 장학금을 지원한다. 다음 해 1학기부터 졸업할 때까지 등록금 전액과 매월 35만 원의 면학보조금을 제공한다. 1차 서류심사(지원서, 자기소개서, 성적증명서, 수능 성적표, 고교 생활기록부 등) 합격자 중 2차 면접을 거쳐 선발한다. 대개 9월 말∼10월에 홈페이지(www.mincho.or.kr)를 통해 지원 공고한다. 02-508-2168

Posted by Triany
2011. 1. 11. 15:59
[핵심정리]!!!
!프로그램을 기준으로
① Source => 입력처리 스트림
   Destination -> 출력처리 스트림


② 처리되는 단위
    - byte(1byte) : byte 스트림
    - char(2byte) : char 스트림

③ 타겟으로부터 직접 읽거나/쓰는 스트림 => Node Stream
    -노드 스트림 객체는 반드시 하나 이상 있어야 한다.
    -노드 객체를 만드는 것은 파일 open을 의미
     노드가 될 수 있는 것 : File, 메모리(Array, Stream), pipe, socket
     [노드스트림] : 노드에 직접 연결되어 있는 스트림을 의미
     char : FileReader / FileWriter
     byte : FileInpuStream / FileOutputStream

④ 타겟으로부터 직접 읽거나/쓰는 것이 아닌 스트림 => Filter 스트림
 (중간처리는 모두 Filter 스트림이 함)







1. 자바 I/O 스트림 소개
 1) 스트림(Stream)이란?
    데이터의 순차적 흐름을 의미
    - 데이터가 출발하는 출발지 또는 근원지(Source)가 있다면 데이터가 도착하는 종착지(Destination)가 있습니다.
    - 데이터의 출발지와 종착지 사이의 데이터의 흐름을 스트림이라고 부릅니다.

 3)스트림 분류
java.io 패키지는 데이터를 읽고 쓰기 위해 필요한 스트링 클래스들을 모아놓고 있습니다.
 * 바이트스트림 : 주로 binary데이터를 처리  * 문자스트림: 주로 문자를 처리
 입출력 작업 단위 : 8비트
제공되는 API :  InputStream/OutputStream 계열
사용되는 경우 : 이미지 오디오와 같은 바이너리 데이터를 입출력 하고자 할 때
입출력 작업 단위 : 16비트
제공되는 API : Reader /Writer 계열
사용되는 경우 : 텍스트 데이터를 입출력 하고자 할 때 
- 대부분의 프로그램은 텍스트 데이터를 읽고 쓸 때 reader와 writer을 씁니다.



1)노드스트림

문자스트림

바이트스트림

파일

FileReader

FileWriter

FileInputStream

FileOutPutStream

메모리 : 배열

CharArrayReader

CharArrayWriter

ByteArrayInputStream

ByteArrayOutputStream

메모리 : 스트림

StringReader

StringWriter

파이프

PipedReader

PipedWriter

PipedInputStream

PipedOutputStream



2. 필터스트림: 가공하는 작업을 하는 스트림(0개 이상)
                     필요하면 집어 넣어 쓰세요.
  필터 스트림은 프로세싱 스트림이라고 함
  특정 기능을 수행하거나 그런 기능을 갖고 있는 메소드를 사용하기 위해서 기존 스트림을 감싸는 역할을 하는 스트림



File 클래스
File객체는 실제로 파일을 오픈하는 것이 아니고, 체크하는 작업을 한다.
(파일에 대한 정보를 보는 클래스)
File file = new File("파일명");
File file = new File("디렉토리명", "파일명");

import java.io.File;
import java.io.IOException;
public class FileTest {
 public static void main(String[] args) {
  File file = new File("c:/data/test.txt");
  System.out.println("파일명 : " + file.getName());
  System.out.println("파일 절대 경로 : " + file.getAbsolutePath());
  System.out.println("파일size : " + file.length());
  if( file.canExecute())
   System.out.println("실행할  수 있다.");
  if( file.canRead())
   System.out.println("읽을 수 있다.");
  if( file.canWrite())
   System.out.println("쓸 수 있다.");
  
  File file2 = new File("c:/data/hello.txt");
  if( file2.exists())
   System.out.println("파일이 존재합니다.");
  else{
   System.out.println("파일이 존재하지 않습니다");
   try {
    if(file2.createNewFile())
     System.out.println("파일이 성공적으로 생성하였습니다.");
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  } 
 }
}
[console]
파일명 : test.txt
파일 절대 경로 : c:\data\test.txt
파일size : 62
실행할  수 있다.
읽을 수 있다.
쓸 수 있다.
파일이 존재합니다.






FileReader/FileWriter 클래스

∎FileReader/FileWriter는 반드시 Exception처리를 해 주어야 한다.
∎FileReader객체와 FileWriter객체를 생성해 주었다면, 반드시 close시켜주어야 한다.

<Reader의 메소드>
* int read() 
 : 입력소스로부터 하나의 문자를 읽어 온다. char의 범위인  0~65535범위의 정수를 반환하며, 입력스트림의 마지막 데이터에 도달하면, -1을 반환한다.

* int read(char[] c)
: 입력소스로부터 매개변수로 주어진 배열 c의 크기만큼 읽어서 배열 c에 저장한다. 읽어 온 데이터의 개수 또는 -1을 반환한다..

*abstract void closd()
: 입력 스트림을 닫음으로써 사용하고 있던 자원을 반환한다.

<Writer의 메서드>
* void write(int b)
: 주어진 값을 출력  소스에 쓴다.

* abstract void close()
: 출력스트림을 닫음으로써 사용하고 있던 자원을 반환한다.

* abstract void flush()
: 스트림의 버퍼에 있는 모든 내용을 출력소스에 쓴다.(버퍼가 있는 스트림에만 해당됨)

 

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
public class FileReadTest {
 public static void main(String[] args) {
  File file = new File("c:/data/test.txt");
  FileReader in = null;
  FileWriter out = null;
  try {
   in = new FileReader(file);
   out = new FileWriter("c:/data/test.backup.txt");
   int ch = 0;
   while( (ch = in.read()) != -1)
    out.write(ch);
   
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }finally{
   if(in != null) try { in.close();} catch (IOException e) {e.printStackTrace();}
   if(out != null) try { out.close();} catch (IOException e) {e.printStackTrace();}
  }
 }
}

 




Copy클래스 만들기.. java simple.syeong.ch13.Copy args[0] args[1]







BufferedReader/BufferedWriter
라인단위로 읽고 쓰는 필터 스트림


public class Copy {
 public static void main(String[] args) {
  if( args.length < 2){
   System.out.println("사용법 : java simple.syeong.ch13.Copy args[0] args[1]");
   System.exit(2);
   //argument에러는 2로 처리.
   
  }
  
  File sfile = new File(args[0]);
  File tfile = new File(args[1]);
  
  if(! sfile.canRead()){
   System.out.println(args[0] + "파일은 읽을 수 없습니다.");
   System.exit(1);
   //error코드로 처리
  }
  
  if( tfile.exists()){
   System.out.println(args[1] + "이미 존재하는 파일입니다.");
   System.exit(1);
  }
  
  FileReader in = null; //입력노드스트림
  FileWriter out = null; //출력노드스트림
  BufferedReader br = null; //라인 단위로 읽을 수 있는 필터스트림
  BufferedWriter bw = null; //라인 단위로 쓸 수 있는 필터스트림
  
  try {
   //FileReader in = new FileReader(new File("c:/data/test.txt"));
   in = new FileReader(sfile); //char단위로 파일에서 읽기
   out = new FileWriter(tfile); //char단위로 파일에서 쓰기.
   br = new BufferedReader(in);
   bw = new BufferedWriter(out);
   String line = null;
   while( (line = br.readLine()) != null){
    bw.write(line);
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }finally{
   if(in != null) try { in.close();} catch (IOException e) {e.printStackTrace();}
   if(out != null) try { out.close();} catch (IOException e) {e.printStackTrace();}
  }
 }
  
}
위의 코드는 약간의 문제가 있다.
쓸데 없는 로컬변수는 in과 out을 썼기 때문이다. 이경우 코드를 다음과 같이 고쳐조는 것이 좋다.
public class Copy {
 public static void main(String[] args) {
  if( args.length < 2){
   System.out.println("사용법 : java simple.syeong.ch13.Copy args[0] args[1]");
   System.exit(2);
   //argument에러는 2로 처리.
   
  }
  
  File sfile = new File(args[0]);
  File tfile = new File(args[1]);
  
  if(! sfile.canRead()){
   System.out.println(args[0] + "파일은 읽을 수 없습니다.");
   System.exit(1);
   //error코드로 처리
  }
  
  if( tfile.exists()){
   System.out.println(args[1] + "이미 존재하는 파일입니다.");
   System.exit(1);
  }
  
  //FileReader in = null; //입력노드스트림
  //FileWriter out = null; //출력노드스트림
  BufferedReader br = null; //라인 단위로 읽을 수 있는 필터스트림
  BufferedWriter bw = null; //라인 단위로 쓸 수 있는 필터스트림
  
  try {
   //FileReader in = new FileReader(new File("c:/data/test.txt"));
   //in = new FileReader(sfile); //char단위로 파일에서 읽기
   //out = new FileWriter(tfile); //char단위로 파일에서 쓰기.
   br = new BufferedReader(new FileReader(sfile));
   bw = new BufferedWriter(new FileWriter(tfile));
   String line = null;
   while( (line = br.readLine()) != null){
    bw.write(line);
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }finally{
   if(br != null) try { br.close();} catch (IOException e) {e.printStackTrace();}
   if(bw != null) try { bw.close();} catch (IOException e) {e.printStackTrace();}
  }
 }
  
}





1.파일 객체를 생성합니다.
  File = fi = new File("a.txt");

2.FileInputStream 객체를 생성합니다.
  FileInputStream fi = new FileInputStream(file)

3. InputStreamReader (1바이트씩 들어오는 데이터를 2바이트로 묶는..)
   InputStreamReader isr = new InputStreamReader(fi);

4. BufferedReader 객체를 생성합니다.(line단위로 읽는)
   Buffered br = new BufferedReader(isr)

5. 파일에서 데이터를 읽음
(콘솔에서는 입출력이 byte이기에 이러한 작업을 함)









'Java' 카테고리의 다른 글

표현언어(Expression Language)  (0) 2011.01.27
java.util 패키지(유틸리티 API)  (0) 2011.01.11
static정리  (0) 2011.01.06
추상클래스 / 인터페이스  (0) 2011.01.06
instanceof연산자  (0) 2011.01.05
Posted by Triany
2011. 1. 11. 13:45

java.util 패키지는 사용자 프로그램에서 필요로 하는 편리한 기능들을 모아 둔 클래스들의 모임이다.

Date클래스
: Date 클래스는 날짜와 시간에 관한 정보를 표현한다.
그러나 JDK의 버전이 향상되면서 deprecate되는 메서드들이 많다.
Date보다는 Calendar클래스를 더 권장.





Calendar클래스(추상클래스)
Calendar 클래스도 Date클래스처럼 날짜와 시간에 관한 정보를 표혈할 때 사용한다.(Calendar클래스를 Date클래스보다 더 권장)
⊙Calendar 클래스는 추상 클래스로 생성자를 제공하지 않는다.
   - 따라서 Calendar 클래스의 객체를 생성하기 위해 new 연산자를 사용할 수 없다. 
  - 추상 클래스이므로 객체를 직접 생성할 수 없지만, 
     getInstance() 메서드를 이용하여 시스템의 날짜와 시간의 객체를 얻어올 수 있다
.

int get(int field)
//날짜에서 표현할 수 있는 값은 다 상수값으로 제공
//calendar 클래스는 날짜와 시간 표현을 위해 다양한 상수를 제공하고 있다.







'Java' 카테고리의 다른 글

표현언어(Expression Language)  (0) 2011.01.27
파일과 입출력 API  (0) 2011.01.11
static정리  (0) 2011.01.06
추상클래스 / 인터페이스  (0) 2011.01.06
instanceof연산자  (0) 2011.01.05
Posted by Triany
2011. 1. 6. 09:33

<객체와 상관 없이!! 객체 생성 이전에 로드되는!!>
-static  멤버들을 객체의 생성 없이 호출할 수 있는 것은 객체 생성 이전에 메모리가 할당되기 때문입니다.
-즉 객체 생성 이전에 클래스 로더에 의해 클래스가 로딩될 때 메모리에 올라가기 때문에 객체를 만들기 전에 클래스 이름만으로도 호출이 가능합니다.

그렇기 때문에 이미 메모리에 올라간 static 멤버가 아직 메모리에 올라가지 않은, static이 아닌 멤버를 호출하는 것은 불가능하다.


  ex)  Class A{
             int a; //
             static int c; //클래스 변수
             static void abc(){
                    int b = a;
             }  //Error! 불가능.
         }
ex)
System.out.println()  //System클래스에 있는 out이라는 객체를 가져와서, out이라는 객체의 println()이라는 함수를 쓰겠다.


1, static 메서드 - static 변수 OK
                         클래스 멤버변수 X

2. 클래스 멤버 메서드 - static 변수 OK
                                 class 멤버 변수 O.K


<static 키워드의 정리>

1. static 멤버는 클래스 변수, 클래스 메소드라고 불리웁니다.
2. 객체 생성없이 [클래스이름.멤버이름]으로 static 멤버를 호출할 수 있습니다.
3. 그 클래스로부터 만들어진 모든 객체들이 static 멤버를 공유합니다.
4. static 멤버는 객체 생성 이전에 클래스가 로딩될 때, 메모리에 먼저 올라갑니다.
5. static 멤버는 static이 아닌 멤버를 직접 호출할 수 없습니다.
6. this와 함께 쓰일 수 없습니다.
7. 부모 클래스의 static 메소드는 메소드 오버라이딩이 안됩니다.



main() 메소드
main()메소드가 static으로 정의되어져야 하는 이유
main()메소드는 JVM이 프로그램을 시작하는 시작점이기 때문에 main()을 가지고 있는 클래스가 객체를 생성하는 것과 상관없이 무조건 실행되어야 하기 때문입니다.

main()메소드의 접근 지정자가 public 인 이유
클래스가 어느 위치에 있건 간에 JVM에서 접근하려면 가장 넓은 범위의 접근 범위를 설정해야 하기 때문입니다.


static 이니셜라이저(Initializer)

static 이니셜라이저(Initializer)란, 메소드 바깥 쪽에 다음과 같은 형태로 static 코드 블록을 만드는 것을 의미합니다.

 public class MyClass {
   static {
      
   }
   //멤버 변수 정의
   //멤버 메소드 정의
}
 - static 코드 블록 안의 코드는 클래스가 로딩될 때 단 한번만 실됩니다.
-  static형식으로 초기화 됨.


'Java' 카테고리의 다른 글

표현언어(Expression Language)  (0) 2011.01.27
파일과 입출력 API  (0) 2011.01.11
java.util 패키지(유틸리티 API)  (0) 2011.01.11
추상클래스 / 인터페이스  (0) 2011.01.06
instanceof연산자  (0) 2011.01.05
Posted by Triany
2011. 1. 6. 00:21
추상:낱낱의 구체적 표상이나 개념에서 공통된 성질을 뽑아 이를 일반적인 개념으로 파악하는 정신 작용
 
추상화 - 클래스간의 공통점을 찾아내서 공통의 조상을 만드는 작업 
구체화 - 상속을 통해 클래스를 구현, 확장하는 작업
추상클래스? 왜 구현할까? 자식클래스에 반드시 구현해야 하기 때문에 사용.
1) fA(){}
2) abstract void fB(); =>규격

 2)번 함수는 상속받아야 하는 자식에이 반드시 구현을 해야 하는 함수이기에, abstract로 선언을 하여 강제성을 주어 상속받은 클래스가 "반드시 구현"할 것을 요구.
ex) 탈것이라는 부모클래스에 abstract 키워드를 사용한 연비계산 추상메소드를 만들고
이를, 자동차 배, 기차등이 상속하여 연비계산을 반드시 구현하도록 함.


1. 추상클래스 ( abstract class 클래스이름{} )

  - 추상클래스에도 생성자가 있으며, 멤버변수와 메서드도 가질 수 있다.
  - 추상메서드가 있으면 반드시 abstract.(추상메소드를 단 하나라도 가지고 있는 클래스를 의미한다.)
  - 추상메서드가 없는 완성된 클래스라 할 지라도 추상클래스로 지정되면 클래스의 인스턴스를 생성할 수 없다.
  - abstract class A -> 객체생성 못 (규격으로 쓰겠다.)
public abstract class Flyer{
   abstract public void takeOff();
   public void getSpeed(){
      System.out.println(" ");
   }
}
클래스를 설계도에 비유한다면, 추상클래스는 비완성 설계도에 비유할 수 있다. 미완성 설계도란, 단어의 뜻 그대로 완성되지 못한  채로 남겨진 설계도를 말한다.
추상클래스 자체로는 클래스로서의 역할을 다 못하지만, 새로운 클래스를 작성하는데 있어서 바탕이 되는 조상 클래스로서 중요한 의미를 갖는다. 새로운 클래스를 작성할 때 아무 것도 없는 상태에서 시작하는 것보다 완전하지 못하더라도 어느 정도 틀을 갖춘 상태에서 시작하는 것이 나을 것이다.


2. 추상메서드
- 선언부만 작성하고 구현부는 작성하지 않은 채로 남겨 둔 것.
- 추상클래스로부터 상속받는 자손클래스는 오버라이딩을 통해 조상인 추상클래스의 추상메소드를 모두 구현해중어야 한다.
  만일 조상으로 부터 상속받은 추상메서드 중 한라도 구현하지 않는다면, 자손클래스 역시 추상클래스로 지정해 주어야 한다.

[예제] - [추상클래스의 사용예와, inner class]
public abstract class ParentNode {
//The type ParentNode must be an abstract class to define abstract methods
 int age;
 String name;
 
 public abstract void display();
 //The abstract method display in type ParentNode can only be defined by an abstract class
 public void hello(){
  System.out.println(name + "님 안녕하세요");
 }
}
public class NodeTest {

public static void main(String[] args) {
  // TODO Auto-generated method stub
  //ParentNode pn = new ParentNode();
  //Cannot instantiate the type ParentNode
  
  
  NodeTest nt = new NodeTest();
  NodeTest.ChildNode cn = nt.new ChildNode();

  //multiple markers at this line
 }
 
 class ChildNode extends ParentNode{
  //The type NodeTest.ChildNode must implement the inherited abstract method ParentNode.display()
  @Override
  public void display() {
      // TODO Auto-generated method stub
   
  }
 }
}
내부클래스는, 해당 클래스 안에서만 쓸 수 있다.
내부 클래스를 사용 하기 위해서는,
NodeTest node = new NodeTest();
NodeTest.ChildNode pn = nod.new ChildNode();
의 식으로 선언한다.
 1)
 Class NodeTest{
     ......
 }
 Class ChildNode{
    .....
 }
 2)
 Class NodeTest{
    .....
    Class ChildNode{
       ...
    }
 }
 클래스 NodeTest와 클래스 ChildNode는 별개의 클래스다.
 NodeTest.java 파일을 컴파일하면,
 NodeTest.class와
 ChildNode.class 두 클래스 파일이 생성된다.
 [내부클래스이다.]
ChildNode를 쓸려면 NodeTest를 만들어야 가능하다.
컴파일 하면, NodeTest.class와
                  NodeTest$ChildNode.class 파일이 생성된다.
그냥 ChildNode cn = new ChildNode()로 선언하면 에러
=>해결법 ? static으로 클래스를 선언하든지,
   내부 클래스를 1)의 형식으로 해주면 OK.

 
# 인터페이스는 왜 사용하는가?
예)
  * 핸드폰과 핸드폰 충전기가 있을 때,
 - 핸드폰 종류별로 충전기가 다 다를 경우 외부 출장 등을 갔을 때 핸드폰 충전을 하기가 불편합니다.
 - 핸드폰 종류별 동일한 충전기를 사용할 수 있도록 하기 위해서는 핸드폰 제조 업체와 충전기 제조 업체 쪽에 동일한 인터페이스를 사용할 수 있도록 하기 위한 규약서를 만들어서 제공해야 합니다.
 - 이 규약서는 핸드폰과 충전기 사이의 인터페이스가 됩니다.
이러한 규약서를 자바 프로그래밍으로 표현할 때 인터페이스가 된다.

<인터페이스> : 규격을 정하는 용도로 사용(규약서)
- 인터페이스는 형태적으로 추상 클래스가 더욱 추상화된 형태로, 모든 메소드가 추상 메소드인 클래스를 의미합니다.
- 인터페이스는 일종의 추상클래스이다.
- 인터페이스는 추상클래스처럼 추상메서드를 갖지만 추상클래스보다 추상화 정도가 높아서,
   추상클래스와 달리 몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없다.
- 오직 추상메서드와 상수만을 멤버로 가질 수 있으며, 그 외의 다른 어떠한 요소도 허용하지 않는다.
- 접근제어자로 public 또는 default를 사용한다.
- 인터페이스는 인터페이스로부터만 상속받을 수 있으며, 
  클래스와는 달리 다중상속, 즉 여러 개의 인터페이스로부터 상속을 받는 것이 가능하다.

interface 인터페이스이름{
     public static final 타입 상수이름 = 값;
     public abstract 메서드이름(매개변수 목록);
     //static final과 abstract 생략가능 
}
public interface Flyer{
     public void takeOff();
     public void land();
     public void fly();
}
public class Airplane implements Flyer{
     public void takeOff(){
     /*                      구현                      */
     }
     public void land()(){
     /*                      구현                      */
     }
     public void fly()(){
     /*                      구현                      */
     }
}

 

일반적인 클래스의 멤버들과 달리 인터페이스의 멤버들은 다음과 같은 제약사항을 가지고 있다.
- 모든 멤버변수는 public static final 이어야 하며, 이를 생략할 수 있다.
    -> 상수값만 가능. (멤버 변수x)
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
    ->인터페이스에 추상 메소드 선언 시 abstract이라는 키워드를 사용하지 않습니다. 왜냐하면 인터페이스는 추상메소드만 가질 수 있기 때문입니다.
[참고] 인터페이스에 정의된 모든 멤버에 예외없이 적용되는 사항이기 때문에 제어자를 생략할 수 있는 것이며, 편의상 생략하는 경우가 많다. 생략된 제어자는 컴파일 시에 컴파일러가 자동으로 추가해준다.


*인터페이스 구현
class 클래스이름 implements 인터페이스이름 {
   //인터페이스에 정의된 추상메서드를 구현해야 한다.
}
만일 구현하는 인터페이스의 메서드 중 일부만 구현한다면, 추상클래스로 선언되어야 한다.


예제소스1)
public interface Flyer {
 public void takeOff();
 public void land();
 public void fly();
}
public class Airplane implements Flyer {
 @Override
 public void takeOff() {
  System.out.println("앞바퀴부터 떨어짐.");
 }
@Override
 public void land() {
  System.out.println("뒷바퀴부터 닿음");
 }
 @Override
 public void fly() {
  System.out.println("쌩하고 날라감");
 }
}
public class Bird implements Flyer {
 @Override
 public void takeOff() {
  System.out.println("열심히 뛰어서 날아오름");
 }
 @Override
 public void land() {
  System.out.println("바람을 타고 내려옴.");
 }
 @Override
 public void fly() {
  System.out.println("훨훨 날아다님");
 }
 public void eat(){
  System.out.println("부리로 쪼아서 먹음.");
 }
}
public class TestFlyer {
 public static void main(String[] args) {
  Flyer airplane = new Airplane();
  Flyer bird = new Bird();
        //Flyer flyer = new Flyer();//error
  //Cannot instantiate the type Flyer
  System.out.println("\n비행기========");
  airplane.takeOff();
  airplane.land();
  airplane.fly();
  
  
  System.out.println("\n\n새========");
  bird.takeOff();
  bird.land();
  bird.fly();
  //bird.eat(); //error. Flyer로 선언된 bird는 eat()메소드에 접근하지 못함
  if(bird instanceof Bird)
  {
   Bird b = (Bird)bird;
   b.eat();
  }
 }
}
[console]
비행기========
앞바퀴부터 떨어짐.
뒷바퀴부터 닿음
쌩하고 날라감


새========
열심히 뛰어서 날아오름
바람을 타고 내려옴.
훨훨 날아다님
부리로 쪼아서 먹음.
[인터페이스를 자료형으로 사용]
Flyer airplane = new Airplane();
Flyer bird = new Bird();

[형변환]
if ( bird instanceof Bird)
    Bird b = (Bird)bird;



[클래스 상속, 인터페이스 구현 클래스]
클래스는 상속(extends)과 구현(implement)을 동시에 할 수있다.
순서 중요!!!!! (extends가 먼저 쓰여지고 뒤에 implement를 써야 함.)
public interface Human {
}
public interface Flyer {
}
public class Bird implements Flyer {
}

public class SuperMan2 extends Bird implement Human {
}

public class 클래스명 extends 부모클래스명 implements 인터페이스명1, 인터페이스명2 { }


[비교] abstract클래스와 interface의 용도를 비교하여 설명.
 * abstract
    1) 일부기능은 제공, 일부기능 규격을 제공
    추상메서드를 한개이상 가지고 있는 클래스
    단일상속만 된다.

 * interface
    1) 규격을 제공
    모든메서드가 추상메서드인 클래스
    다중상속이 가능하다.



 인터페이스의 장점
- 개발시간을 단축시킬 수 있다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
- 독립적인 프로그래밍이 가능하다.

'Java' 카테고리의 다른 글

표현언어(Expression Language)  (0) 2011.01.27
파일과 입출력 API  (0) 2011.01.11
java.util 패키지(유틸리티 API)  (0) 2011.01.11
static정리  (0) 2011.01.06
instanceof연산자  (0) 2011.01.05
Posted by Triany
2011. 1. 5. 22:49
참조변수가 참조하고 있는 인스턴스의 실제 타입을 알아보기 위해 사용한다. 주로 조건문에 사용되며, instanceof의 왼족에는 참조변수를 오른쪽에는 타입(클래스명)이 피연산자로 위치한다. 그리고 연산의 결과로 boolean값인 true, false 중의 하나를 반환한다.
instanceof를 이용한 연산결과로 true를 얻었다는 것은 참조변수가 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.
[참고] 값이 null인 참조변수에 대해 instanceof연산을 수행하면 false를 결과로 얻는다.

void dowork(Car c){
     if ( c instanceof FireEngine) {
          FireEngine fe = (FireEngine)c;
          fe.water();
     }
    else if( c instance of Ambulance) {
          Ambulance a = (Ambulance)c;
          a.siren();
    }

  . . . . . . .
}




참조변수와 인스턴스의 연결
-메서드 : 조상클래스의 메서드를 자손의 클래스에서 오버라이딩 한 경우에도 참조변수의 타입에 관계없이 항상 실제 인스턴스의 메서드(오버라이딩된 메서드가 호출됨)

멤버변수의 경우 참조변수의 타입에 따라 달라짐
-멤버변수가 조상 클래스와 자손 클래스에 중복으로 정의된 경우,
조상 타입의 참조변수를 사용했을 때 조상 클래스에 선언된 멤버변수가 사용되고,
자손타입의 참조변수를 사용했을 때는 자손 클래스에 선언된 멤버변수가 사용된다.

예1)
class Parent{
     int x = 100;
  
     void method() {
          System.out.println("Parent Method");
     }
}

class Child extends Parent {
     int x = 200;

     void method() {
          System.out.println("Child Method");
     }
 
}


Class BindingTest{
     public static void main(String[] args) {
          Parent p = new Child();
          Child c = new Chile();
          System.out.println("p.x = " + p.x);
          p.method();
          System.out.println("c.x = " + c.x);
          c.method();
     }
}      
[결과값]
p.x = 100;
Chiild Method
c.x = 200;
Child Method




예2)
public class Parent {
    public int su = 10;
    void pr(){
          System.out.println(su);
    }
}
public class Child extends Parent {
    public int su = 20;
    void pr(){
         System.out.println(su);
    }
}
public class TestParentChild { 
   public static void main(String[] args) {
  
       System.out.println("*Parent p1 = new Parent() *");
       Parent p1 = new Parent();
       System.out.print("Parent의 pr(): su = "); p1.pr();
       System.out.println("p1.su = " + p1.su);
  
       System.out.println("\n *Child c1 = new Child() *");
       Child c1 = new Child();
       System.out.print("Child의 pr() : su = "); c1.pr();
       System.out.println("c1.su= "+c1.su);
  
       System.out.println("\n *Parent p2 = new Child() *");
       Parent p2 = new Child();
       System.out.print("Child의 pr(): su = "); p2.pr();
       System.out.println("p2.su = " +p2.su);
   }
}
[Console]
*Parent p1 = new Parent() *
Parent의 pr(): su = 10
p1.su = 10

 *Child c1 = new Child() *
Child의 pr() : su = 20
c1.su= 20

 *Parent p2 = new Child() *
Child의 pr(): su = 20
p2.su = 10
마지막 선언 Parent p2 = new Child() 를 보면,
p2.su의 값을 출력해 보면 Parent클래스의 멤버변수 su값이 출력된다.
(조상타입의 참조변수를 이용하여 Child()클래스를 접근했으므로 참조 변수는 Parent의 su이다.)
하지만 참조메소드는 현재 인스턴스가 접근하는 클래스(Child())의 멤버 메소드 이므로,
void pr(){
         System.out.println(su);
    }
함수의 su가 this.su를 생략하고 있다고 보면, Child의 멤버변수 su의 값이 출력된다.



예3)
public interface Drawable {
    public int PLAIN_PEN = 1;
    public int BOLD_PEN = 2;
    public int ITALIC_PEN = 3;
    public void draw();
    public void move(int x, int y);
}
public class Shape1 {
    protected int x = 0;
    protected int y = 0;
    public Shape1() {
          this(0,0);
    }
    public Shape1(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
public class Circle1 extends Shape1 implements Drawable {
     protected int radius;
     public Circle1(int x, int y, int radius) {
          super(x, y);
          this.radius = radius;
     }
  
    @Override
    public void draw() {
          System.out.println("x = " + x + ",  y = " + y + "  radius = "+radius);
    }

    @Override
     public void move(int x, int y) {
          System.out.println("x = " + (this.x + x) + ",  y = " + (this.y+y) + "   radius = "+ radius);
     }
}
public class Rectangle1 extends Shape1 implements Drawable {
    protected int width;
    protected int height;
 
    public Rectangle1(int x, int y, int width, int height) {
         super(x, y);
         this.width = width;
         this.height = height;
    }

    @Override
    public void draw() {
         System.out.println("x = " + x + ",  y = " + y + "  width = "+ width + ",  height = " + height);
    }

    @Override
    public void move(int x, int y) {
          System.out.println("x = " + (this.x + x) + ",  y = " + (this.y+y) + "  width = "+ width + ",  height = " + height);
    }
}
public class InterfaceTest {
    public static void main(String args[]){
  Circle1 c = new Circle1(10,10,100);
  Rectangle1 r = new Rectangle1(20,20,50,50);
  c.draw();
  c.move(5, 5);
  r.draw();
  r.move(5, 10);
  
    }
}
[Console] InterfaceTest.java
x = 10,  y = 10  radius = 100
x = 15,  y = 15   radius = 100
x = 20,  y = 20  width = 50,  height = 50
x = 25,  y = 30  width = 50,  height = 50
public class InterfaceTestEx {
    public static void main(String args[])
   {
  Circle1 c = new Circle1(10,10,100);
  Shape1 s = new Circle1(20,20,200);
  Drawable d = new Circle1(30, 30, 300);
  c.draw();
  //s.draw();  //The method draw()is undefined for the type Shape1
  d.draw();
  System.out.println("x = " + c.x + ",  y = " + c.y);
  System.out.println("x = " + s.x + ",  y = " + s.y);
  // System.out.println("x = " + d.x + ",  y = " + d.y);
//  Multiple makers at this line
// -x cannot be resolved or is not a fild
// -y cannot be resolved or is not a file
    }
}
[Console] InterfaceTestEx.java
x = 10,  y = 10  radius = 100
x = 30,  y = 30  radius = 300
x = 10,  y = 10
x = 20,  y = 20
InterfaceTestEx.java 부분을 살펴보자
s.draw();는 error가 뜬다. 이유는, 참조변수 Shape1으로 선언한 s 객체는 Shape1이 draw() 함수를 갖고 있지 않기 때문에
 //The method draw()is undefined for the type Shape1 이라는 메시지가 뜨며 에러라고 표시된다.
마찬가지로 System.out.println("x = " + d.x + ",  y = " + d.y);도 error 메시지가 뜨게 되는데, Drawable 클래스는 x, y라는 멤버변수를 갖고 있지 않기때문에,  "Multiple makers at this line   -x cannot be resolved or is not a fild   -y cannot be resolved or is not a file" 라는 메시지가 뜨면서 에러가 뜬다.





'Java' 카테고리의 다른 글

표현언어(Expression Language)  (0) 2011.01.27
파일과 입출력 API  (0) 2011.01.11
java.util 패키지(유틸리티 API)  (0) 2011.01.11
static정리  (0) 2011.01.06
추상클래스 / 인터페이스  (0) 2011.01.06
Posted by Triany
2011. 1. 5. 14:37
미셸 푸코 [Michel Paul Foucault, 1926.10.15~1984.6.25]
요약
프랑스의 철학자. 정신의학에 흥미를 가지고 연구했으며 서양문명의 핵심인 합리적 이성에 대한 독단적 논리성을 비판하고 소외된 비이성적 사고, 즉 광기(狂氣)의 진정한 의미와 역사적관계를 파해쳤다.
국적 프랑스
활동분야 철학
출생지 프랑스 중서부 프와티에(Poitiers)
주요저서 《광기와 비이성(非理性)》(1961) 《앎[知]의 고고학》(1969)
본문
1926년 10월 15일 프랑스 중서부 프와티에(Poitiers)에서 출생하였다. 그의 아버지는 외과의사였다. 포스트구조주의의 대표자로 파리대학교 벵센 분교 철학교수를 거쳐 1970년 이래 콜레주 드 프랑스 교수를 지냈다. 대학에서 철학을 전공한 후 정신의학에 흥미를 가지고 그 이론과 임상()을 연구하였다. 인간의 지식은 어떤 과정을 거쳐 형성되고 변화하는지 탐구하였고 해답을 모색하였다. 그 과정에서 각 시대의 앎[]의 기저에는 무의식적 문화의 체계가 있다는 사상에 도달하였다. 또한 업압적인 권력의 구조를 예리한 통찰력으로 파헤쳤으며 정신병의 원인을 사회적 관계속에서 밝혀내려 하였다. 1961년 정신의학의 역사를 연구한 《광기()와 비이성()―고전시대에서의 광기의 역사》에서 서양문명의 핵심인 합리적 이성에 대한 독단적 논리성을 비판하고 소외된 비이성적 사고, 즉 광기()의 진정한 의미와 역사적관계를 파헤쳤다. 이 저술로 푸코는 세계에서 주목받는 철학자로 떠올랐다.

정신병과 사회적 관계를 밝힌《임상의학의 탄생》(1963) 을 저술하였으며 1966년에는 역사를 통해 지식의 발달과정을 분석한 《언어와 사물》을 저술하였다. 서구 지식의 역사는 두 번의 단절된 과정이 있었다고 주장하였고 지식을 연속성을 가진 발달과정으로 보는 기존의 입장을 착각으로 규정하였다. 1969년 《지식의 고고학()》에서는 전통적인 사상사를 비판하였다. 1970년대에 푸코는 부르주아 권력과 형벌제도에 대한 분석의 결과물인 《처벌과 감시》(1975)를 저술하였다. 이 저술에서 푸코는 역사적으로 지배계급이 체제를 유지하기 위해 이용한 법률과 억압적 통치구조를 파헤쳤다. 인간의 알고자 하는 의지와 이를 억압하는 권력과의 관계를 주요 주제로 삼았다. 푸코는 지식은 권력과의 관계를 맺고 있으며 모든 지식은 정치적이라고 주장하였다. 1984년 6월 25일 후천성면역결핍증(AIDS)으로 사망하였다.

Posted by Triany
2011. 1. 5. 13:16
노암 촘스키 [Avram Noam Chomsky, 1928.12.7~]
요약
미국의 언어학자로서 변형생성문법 이론으로 언어학에 큰 영향을 끼쳤다. 또한 1960년대부터 활발히 사회운동에 참여하여 미국을 대표하는 비판적 지식인으로 평가를 받고 있다.
별칭 언어학 혁신의 아버지
국적 미국
활동분야 어학
출생지 미국 펜실베이니아주(州) 필라델피아
주요저서 《언어 이론의 논리적 구조》(1955) 《통어론적 구조 Syntactic Structures》(1957) 《통어 이론의 제상 Aspects of the Theory of Syntax》(1965) 주요작품
본문
1928년 12월 7일 미국의 펜실베니아주() 필라델피아에서 유대계 러시아 이민자 가정의 2세로 태어났다. 그의 아버지(William Chomsky)는 저명한 히브리어 연구자였으며 촘스키언어학자가 되는 데 큰 영향을 끼쳤다. 그는 펜실베이니아 대학에서 언어학, 수학, 철학을 공부했으며, 1955년 언어학 박사 학위를 받았다. 1949년에 언어학자인 캐롤 슈워츠 촘스키(Carol Schatz Chomsky)와 결혼했으며, 1950년대에는 아내와 함께 이스라엘의 집단농장인 키부츠(qibbutz)에서 공동체 생활을 하기도 했다. 그는 1956년 매사추세츠공과대학(MIT)의 교수가 되었고, 1966년 석좌교수, 1976년부터는 연구교수가 되었다. 

그는 1951년부터 1955년까지 하버드대학교의 특별 연구원으로 선임되었는데, 이 기간에 《변형 분석 Transformational Analysis》이라는 제목의 박사 논문을 완성하였다. 이 과정에서 《변형생성문법 transformational generative grammar》이론의 기본 틀을 정립하였다. 그는 1955년 논문의 내용을 발전시켜 《언어학 이론의 논리적 구조 The Logical Structure of Linguistic Theory》라는 책을 집필하였고, 학계의 주목을 받기 시작했다(이 책은 등사판으로 유포되었다가 1975년에 정식 출간되었다). 그리고 《통사 구조 Syntactic Structures》(1957), 《통사론의 여러 측면 Aspects of the Theory of Syntax》(1965), 《생성문법 이론의 여러 문제 Topics in the Theory of Generative Grammar》(1966), 《영어의 음성양식 Sound Pattern of English》(1968, Morris Hall과 공저), 《언어와 정신 Language and Mind》(1968), 《언어지식 Knowledge of Language》(2000), 《최소주의 언어이론 The minimalist program》(2001) 등의 저작으로 변형생성문법 이론을 체계적으로 발전시키며 언어학의 혁명을 주도하였다.

촘스키는 현대 언어학의 발달에 혁명적 변화를 가져온 언어학자이다. 촘스키의 변형생성문법 이론은 개개의 언어수행(performance)에 앞서 존재하며 그것을 생성시키는 인간의 보편적인 언어능력(competence)과 언어규칙에 대한 탐구로 언어학의 영역을 확장시켰다. 이는 ‘촘스키 혁명’, ‘언어학 혁명’이라고 불릴 정도로 현대 언어학에 획기적 전환을 가져온 것으로 평가된다. 그리고 그의 언어 이론은 인지과학, 철학, 심리학 등 다양한 학문들에도 커다란 영향을 미쳤다.

하지만 촘스키는 언어학자로서만이 아니라 현실 비판과 사회 참여에 앞장서는 실천적인 지식인으로서도 널리 알려져 있다. 그는 1960년대 베트남전쟁 반대 운동을 기점으로 다양한 사회운동에 적극적으로 참여하였는데, 1967년에는 국방성과 국무성 앞에서 시위를 벌이다 투옥되기도 했다. 그는 저작과 강연, 대담, 영상물 등으로 미국의 제국주의적인 대외 정책과 정치·경제·매체를 장악한 권력을 비판해 왔으며, 직접 실천 행동에 참여하였다. 그리고 1990년대 이후에는 신자유주의 세계질서의 야만성에 대한 비판에도 앞장섰다. 이러한 활발한 사회 참여 때문에 그는 ‘미국의 양심’으로 불리기도 한다. 그의 이러한 활동은 인간이면 누구나 자기가 속한 사회에 대해 올바른 판단을 내리고 그것을 행동에 옮길 수 있어야 하며, 인간사에 중대한 의미를 갖는 문제에 대한 진실을 그 문제에 대해 뭔가를 해낼 수 있는 대중에게 알리려고 노력하는 것이 《지식인의 책무 Writers and Intellectual Responsibility》(1995)라고 주장했다.

한편 그는 언어학 이외에도 정치학, 철학, 심리학 등의 다양한 주제에 대해 80여 권의 저서와 1천여 편의 논문을 발표하였다. 특히 강대국의 패권적인 대외 정책과 언론, 지식인의 유착 등을 폭로하고 비판하는 활동에 앞장서, 《숙명의 트라이앵글 - 미국, 이스라엘, 팔레스타인 Fateful triangle : the United States, Israel and the Palestinians》(1983), 《여론조작―매스미디어정치경제학 Manufacturing Consent: The Political Economy of the Mass Media》(1988, 에드워드 허먼과의 공저), 《미국이 진정으로 원하는 것 What Uncle Sam Really Wants》(1996), 《그들에게 국민은 없다 Profit over people : neoliberalism and global order》(1999), 《507년, 정복은 계속된다 Year 501, The Conquest Continues》(2000), 《불량 국가 Rogue states》(2001) 등의 저작을 남겼다. 이러한 저작들과 강연, 대담 등을 통해 그는 다국적기업의 이익만을 중시하는 신자유주의적 세계화의 문제와 강대국의 대외 정책에서 나타난 폭력성, 이에 융합된 사회 내의 권력 등을 폭로하고 비판하는 활동을 펼쳤으며, 그의 글들은 세계 각국에서 번역되어 널리 읽히며 큰 영향을 끼쳤다. 

Posted by Triany
2011. 1. 1. 22:25

 이토록 마음편히, 느긋하게 책을 읽은것은 오랜만인 것 같다. 학기 중에 책을 읽을 때는 시간에 쫓겨 최대한 빨리, 최대한 많은 내용을 내 안에 담기 위해서 긴장감 속에 글을 읽었었다. 그와 더불어 '한국문학'에 대한 교양강좌를 들으면서, 편안한 마음보다는 무언가를 보기 위해 노력하는 과정에서 피로함을 느꼈었다.

 작가 신경숙은 p.15와 p.424에 "이 글은 사실도 픽션도 아닌 그 중간쯤의 글이 될 것 같은 예감이다. 하지만 그걸 문학이라고 할 수 있을 것인지. 글쓰기를 생각해본다, 내게 글쓰기란 무엇인가? 하고..."라는 말과 함께 글을 시작하고 끝맺음한다.

 그 시절, 그 상처를 글로 토로한다는 건 어떤 심정일까? 가장 잊고 싶은 시절, 잊을려고 노력하였던 16살에서 19살까지의 시절. 그 시절을 담담하게 말하는 그녀의 문체가 왠지 내 마음을 더 아리게 하였다. 이 글을 과연 성장소설이라고 할 수 있을련지... 만약 그녀가 내가 아는 사람이라 할 지라도, 그녀 앞에서 '외딴방'이라는 책을 잘 읽었다고 말할 수 없으리라. 그저 가슴에 묻어두겠지. 그녀의 이야기를.

희재언니, 그리고 그시절 그녀들...

"글쓰기, 내가 이토록 글쓰기에 마음을 매고 있는 것은, 이것으로만이, 나, 라는 존재가 아무것도 아니라는 소외에서 벗어날 수 있다고 생각하기 때문은 아닌지.."p.20

왜 책을 덮고도 이 문장이 내 안에 맴도는지 모르겠다.
그리고 이유는 모르겠지만, 내가 알지 못하는 그녀가 왠지 내 속에서 친숙해 진 느낌은 무엇이련지..
그녀의 책, 풍금이 있던자리, 엄마를 부탁해, 어디선가 나를 찾는 전호벨이 울리고 등을 읽을 때 느끼지 못했던 친숙함이, 어쩌면 그녀의 가장 어둡고, 가슴안에 감추어 두었던 그 시절의 이야기가 내게 친숙함을 주었을 련지도.......


외딴방, 나에게도. 외딴방이........... 나의 외딴방은.........
Posted by Triany