Tumgik
coffee-mark · 11 years
Text
ANDROID 이벤트 처리 - 리스너 인터페이스 구현
 실습 테스트 환경
 OS : Windows XP
 Eclipse :  Android Developer Tools Build: v22.0.5-757759
 Project Build Target : Android 4.12 API Level 16
 Emulator API Level : 본문 참조
    Overview
  대부분의 시스템은 이벤트에 반응하도록 설계되어 있다. 여기서 이벤트란 사용자가 마우스로 버턴을 클릭하거나 키보드의 키를 누르는 행위 등을 말한다. 이러한 시스템에 맞게 프로그램하는 방법을 event driven programming(이벤트 기반 프로그래밍)이라고 한다. 
안드로이드는 이벤트 처리를 위해  "콜백메서드"와 "리스너 인터페이스"를  제공하는데 여기서는 리스너 방법만을 설명하고 콜백메서드는 다음에 설명한다.
안드로이드의 리스너 인터페이스는 이벤트를 처리하는 인터페이스이다. 안드로이드의 리스너는 개발자가 리스너 구현이 편하게(?) 그 이벤트를 일으킬 수 있는 객체 클래스의 내부 인터페이스로 정의 되어 있다.  
    [step1] File -> New -> Android Application Project
  [step2] res -> values -> strings.xml 파일 오픈(더블클릭) 다음과 같이 코드 추가
<?xml version="1.0" encoding="utf-8"?> <resources>
    <string name="app_name">event_test</string>     <string name="action_settings">Settings</string>     <string name="btn1">이벤트 테스트</string>
</resources>
      [step3] res -> layout -> activity_main.xml 파일 오픈(더블클릭) 다음과 같이 코드 추가
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent">
    <Button         android:id="@+id/btn1"         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:text="@string/btn1" />
</RelativeLayout>
- 코드설명
@+id : layout.xml파일 안의 view를 R.java 클래스의 id 내부클래스에 등록
@string : R.java 클래스의 string 내부클래스를 참조  
    [step4] src -> package -> MainActivity.java 파일 오픈(더블클릭)하여 다음과 같이 코드 추가
package zeroday.event_test;
  import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
  public class MainActivity extends Activity {
       Button btn1;
              @Override
       protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_main);
             btn1 = (Button)findViewById(R.id.btn1);
                          btn1.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                           Toast.makeText(MainActivity.this, "btn1 클릭", Toast.LENGTH_SHORT).show();
                    }
             });
       }
                    @Override
       public boolean onCreateOptionsMenu(Menu menu) {
             getMenuInflater().inflate(R.menu.main, menu);
             return true;
       }
}
-코드설명
view findViewById(int id) : R.java 클래스의 id 내부클래스의 view를 리턴
클래스명.this : 내부 클래스에서 외부클래스를 참조할때 외부클래스명.this 사용
Toast : 안드로이드 메세지 출력 객체
[step5] 실행
Tumblr media
0 notes
coffee-mark · 11 years
Text
ANDROID 화면 UI를 담당하는 VIEW 객체 - 컨트롤과 레이아웃
Overview
  뷰는 안드로이드의 UI를 구성하는 개체인데, 뷰는 입/출력이 가능한 컨트롤과, 다른 뷰를 담는 컨테이너 역활을 하는 레이아웃(뷰그룹)으로 나눌 수 있다.
Tumblr media
  [이미지출처] http://www.itcsolutions.eu/
    Sample
  앞단원에서 실행한 FirstApp프로젝트에서 화면UI를 담당하는 "res/layout/activity_main.xml"파일을 예로 보면 <RelativeLayout>이 레이아웃(뷰그룹)에 해당되고 RelativeLayout안의 <TextView>가 컨트롤에 해당된다.
Tumblr media
0 notes
coffee-mark · 11 years
Text
ANDROID 장비 용어설명, api문서 사용
1. 장비 관련 용어
Tumblr media
    홈버턴 : 홈스크린으로 이동.
백버턴 : 이전 화면으로 이동.
메뉴버턴 : 현재 실행중인 프로그램의 메뉴를 보여준다.
독바 : 자주 사용하는 아이콘 등록.
론처버턴 : 설치된 프로그램의 목록을 보여준다.
플리킹 : 좌우, 아래위로 스크롤(터치)하여 페이지를 이동하는 동작.
홀드다운 : 아이콘을 누른상태에서 잠시 기다리면(홀드다운) 아이콘이 커지면서 드래그 가능해진다.
    2. API 문서
  java도 마찬가지지면 android에서도 클래스나 메서드등을 외우기 보다는 레퍼런스를 잘 활용하자.
  http://developer.android.com/reference/packages.html 다음을 참조
Tumblr media
0 notes
coffee-mark · 11 years
Text
ANDROID 프로젝트 백업
[step1] exprot
  Project Explorer - 프로젝트 우클릭 - General - Archive File
Tumblr media Tumblr media
        [step2] import
  Project Explorer - 빈공간 우클릭 - Import - Existing Porjects into Workspace
Tumblr media Tumblr media
0 notes
coffee-mark · 11 years
Text
ANDROID 프로젝트 구조
1. 폴더 구조
Tumblr media
2. 각 폴더, 파일 관계
Tumblr media
0 notes
coffee-mark · 11 years
Text
1st android application project
실습 테스트 환경
 OS : Windows XP
 Eclipse :  Android Developer Tools Build: v22.0.5-757759
 Project Build Target : Android 4.12 API Level 16
 Emulator API Level : 본문 참조
   [step1] 안드로이드 프로젝트 시작하기 
  File - New - Android Application Project
Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media Tumblr media
  [step2] 안드로이드 앱 설치용 가상장치 만들기(안드로이드 스마트폰이 있다면 실장비로 테스트 가능)
  Window - Android Virtual Device Manager
Tumblr media Tumblr media Tumblr media
  [step3] 프로젝트 애뮬레이터에 설치후 실행 방법 4가지 
  ① 프로젝트(FirstApp) 우클릭 -> Run As -> 1 Android Application
② Run - Run As - 1 Android Application
③ 단축키 ctrl + f11
④ 툴바에 "Run As..." 버턴 클릭
Tumblr media
    ※ 실장비 안드로이드 스마트폰에서 테스트시 설정 사항
  ① 메뉴 - 시스템 설정 - 개발자 옵션 - 개발자 옵션 on - USB 디버깅 체크
Tumblr media
② pc에 장비 디바이스 드라이버 설치
③ usb 연결
④ Run - Run As - 1 Android Application
0 notes
coffee-mark · 11 years
Text
ANDROID 개발환경 구축
1. JDK 설치
  http://www.oracle.com 에서 다운로드
  2. SDK와 이클립스 기반의 개발툴 ADT 다운로드
  http://developer.android.com/sdk/index.html 에서 다운로드
    3. SDK Manager 실행하여 sdk 업데이트
  다운받은 파일을 압축을 풀고 SDK Manager.exe 실행하여 필요한 package 설치
  4. 개발툴(adt 이클립스) 실행
  압축 푼 폴더에 eclipse폴더 아래 eclipse.exe 실행
 ※ 사용하고 있는 이클립스가 있다면 adt플러그인을 설치후 사용해도 된다.
  5. Android Virtual Device 만들기
  Window - Android Virtual Device Manager
- AVD Name : 가상장비의 이름
- Device : 가상장비 하드웨어 선택
- Target : 가상장비의 안드로이드 버전을 결정(구글 맵서비스 사용시에는 Google APIs선택)
- Keyboard : PC키보드 사용여부(소프트키보드 사용을 위해 선택하지 않는것이 좋다)
- Skin : home키, menu키, back등 하드웨어 키를 배치
- Memory, Internal Storage, SD Card : 디폴트값으로 사용 or 개개인의 pc사양에 따라 적당히...
   해상도가 480*800이면 모니터의 해상도에 따라 화면 크기가 크게 보일수도 있다. Scale display to real size 체크 박스를 선택후 장비의 화면 크기와 모니터의 dpi값을 입력하여 축소된 화면 크기로 테스트 할 수 있다.
Wipe user data 체크박스 선택시 애뮬레이터에 설치된 앱들이 초기화 됨.
  애뮬레이터 부팅시 시스템에 따라 시간이 오래 걸릴수 도 있다.(10분내외)
0 notes
coffee-mark · 11 years
Text
ANDROID 소개
Overview
  안드로이드는 리눅스 기반의 모바일 전용 운영체제이다. 안드로이드OS는 "안드로이드"라는 동일 이름의 회사에서 개발을 시작하였으며, 2005년 구글이 ‘안드로이드(Android)’사를 인수후 2007년 11월에 안드로이드 첫 버전이 릴리즈 되었다.
안드로이드의 개발 언어로는 java가 많이 사용되며(c언어 개발 키트(NDK)도 제공), 개발툴로는 이클립스가 많이 사용된다.
    1. 안드로이드 history
  안드로이드 코드명은 살찌는 간식들로 a, b, c, ... 알파벳 순으로 명명된다.
Tumblr media
0 notes
coffee-mark · 11 years
Text
JAVA/SERVLET/JSP
1. 자바
  컴퓨터용 프로그램(어플리케이션)을 만들수 있는 언어는 여러가지가 있다. 그중 자바언어는 Sun Microsystems에서 만든 프래그래밍 언어이다.(지금의 주인은 oracle사 이다) 
자바언어에 대해 좀더 알고 싶다면 다음 링크를 참조하라. http://cafe.naver.com/jjdev/157
    2. 웹 어플리케이션의 구조(아키텍쳐)
  앞서 설명한 바와 같이 웹 어플리케이션의 구조는 경우 일반 어플리케이션의 구조와는 다르다. 클라이언트와 서버 방식으로 이루어져 있으며, 클라이언트가 요청(ex : 회원가입, 로그인, 계좌이체, 쇼핑몰결재,...등)을 하면 서버는 요청의 대한 결과를 응답하는 구조이다.
일반 어플리케이션과 웹 어플리케이션의 ���조가 다르다는 것은 그들의 프로그래밍하는 방법에도 차이가 있다는 것을 의미한다.
    3. 서블릿(servlet)과 JSP
  ① servlet
  서블릿은 Sun Microsystem사에서 자바언어를 이용하여 쉽게(?) 웹 어플리케이션을 개발하기 위해 만든 표준API(라이브러리, 클래스의 집합)이다.(정확히는 서블릿은 J2SE가 아닌 J2EE에 포함되어 있는 API이다) 이 규약에 따라(상속, 구현) 만든 클래스를 통상적으로 서블릿이라 부른다. 서블릿을 만들기 위해서는 자바 코드를 서블릿 규약에 맞게 작성하고, 코드를 컴파일 해서 클래스 파일을 만들어 웹 어플리케이션으로 실행될 수 있는(사용자가 요청할 수 있는) 위치에 배치(배포)하면 된다. 
  ② JSP
  JSP(Java Server Page)는 서블릿 기반의 "서버 스크립트 기술"이다. "스크립트 기술"이란 미리 약속된 규정에 따라 간단한 키워드 조합을 입력하면, 실행시점에 그 각각의 키워드에 맵핑되어 있는��어떤 코드로 변환 후에 실행되는 형태이다.
JSP의 경우 사용자가 요청을 하면 TOMCAT같은 WAS(웹 어플리케션 섭버)에 의해 내부적으로 서블릿으로 만들어져 실행되게 된다. (실제 a.jsp라는 파일을 만들어 배포하면 실행시점에 WAS에 의해 "a_jsp.java"가 만들어지고 a_jsp.class로 컴파일되어 실행된다)
JSP가 서블릿을 기반으로 하고 있기 때문에, JSP의 동작 방식을 이해하기 위해서는 서블릿에 대한 이해가 필요하다.
  ※ 웹 어플리케이션 서버 vs 웹 컨테이너
"웹 어플리케이션 서버"를 "웹 컨테이너" 라고도 부르는데, 바라보는 관점의 차이정도로 생각하면 된다. TOMCAT이 웹 어플리케이션 서비스를 하는 측면에서는  웹 어플리케이션 서버 라 부르면 되겠지만, TOMCAT이 내부적으로 자바의 객체를 만들어 객체를 실행하고 생명주기를 관리하는 측면에서 본다면 "웹 컨테이너"라 부를 수 있다. 구분해서 사용하면 좋겠지만 입문자의 경우 "용어"라는 것 자체가 엄청난 스트레스이니 일단은 같은 뜻으로 생각하자.
  ③ 서블릿과 JSP 비교
   servlet
 JSP
 - 자바 코드로 구현하고 컴파일하고 배포해야 한다.
 - html 태그로 문자열("") 스트림으로 처리하여야 한다.
 - 코드가 수정되면 다시 컴파일하고 배포하여야 한다.
 - 키워드가 태그화 되어 서블릿에 비해 배우기가 쉽다.
 - 자바 코드를 "<% %>"태그 안에 스크립트릿으로 처리하여야 한다.
    4. 서블릿과 JSP 각각의 역할
  설명대로 라면 servlet이나 JSP나 만드는 방법에 차이가 있을뿐 동일한 역할을 하게 된다는 결론인데 왜 이렇게 나누어 놓았을까?
초기의 자바 웹 개발은 서블릿을 이용한 개발이었다. 이후 JSP기술이 발표되면서 JSP 형태의 개발("모델 1"방식이라 부른다)이 유행(?)하게 되고 지금에 와서 각각이 역할을 나누어 서블릿+JSP 형태의 개발("모델 2"방식이라 부른다)이 이루어지고 있다.
JSP는 JSP기술의 장점을 최대한 활용할 수 있는 웹 어플리케이션 구조에서 사용자에게 결과를 보여주는 "프리젠테이션 층(Layer)"을 담당하고, 서블릿은 서블릿의 장점을 최대한 활용할 수 있는 사용자의 요청을 받아서 분석하고 "비지니스 층(Layer)"과 통신하여  처리하고, 처리한 결과를 다시 사용자에게 응답하는  "컨터롤러 층(Layer)"을 담당한다. -> 로직을 처리하는 자바 코드들은 sevlet에 코딩하고 JSP페이지에는 최소한의 자바 코드만 코딩하자. 반대로 html태그는 servlet에서 분리시켜 JSP에서만 코딩하자.
0 notes
coffee-mark · 11 years
Text
JSP/SERVLET 학습에 필요한 선행 기술
아래 선행 기술(지식) 리스트에서 자바 관련된 기술을 제외하고는(자바언어는 필수 지식이다. 자바를 모르면 시작도 하지마라!) 당장은 몰라도 jsp/servlet을 진행 하면서 같이 학습이 가능하다. 하지만 개발자가 당연히 알아야 할 기술(지식)들이고, 이러한 기술이나 지식이 바탕이 되지 못하면, 자칫 jsp/servlet 자체를 어렵게 느낄 수 도 있다.
가급적 깊이 있게는 아니라도 기본적인 개념만이라도 먼저 학습을 하고 jsp/servlet을 시작하자.
  ① java
자바 개발환경 설치 및 셋팅
자바 언어 기본 문법
자바 자료구조(배열, List, Set, Map등)
package, import
객체지향 개념(상속, 오버로딩, 오버라이딩, 인터페이스, 다형성)
예외처리
thread의 개념
java.lang 패키지 클래스의 사용경험
API를 참조하여 코딩
외부라이버러리 참조
  ② 네트워킹 관련 지식
인터넷/웹 환경에 대한 이해
http 프로토콜의 개념
  ③ 웹프로그래밍 과련 기술(지식)
웹브라우즈/웹서버/WAS 설치 및 셋팅
다른 서버OS(리눅스, 유닉스)의 경험
  ④ HTML
html 기본 태그, form 관련 태그
나모,드림워버 같은 위지윅(WYSIWYG) 에디터를 사용하지 않고 코딩
css
  ⑤ javascript
자바스크립트 문법
함수 사용
기본객체, 브라우저객체, DOM
이벤트 처리
  ⑥ database
테이블 생성 및 키에 대한 이해
SQL문
transaction 개념
  ⑦ JDBC
oracle, mysql 등 원격지 연결
jdbc 드라이버 셋팅
Connection, Statement, PreparedStatement, ResultSet
데이터 핸들링
  ⑧ XML
xml문서에 대한 기본 이해
DTD, 스키마
0 notes
coffee-mark · 11 years
Text
JDBC ResultSet으로 select쿼리 결과값 가져오기
select쿼리 실행 시 executeQuery() 메서드를 사용하며, 실행 결과로 java.sql.ResultSet형으로 리턴한다.
  * ResultSet에서 자주사용하는 메서드 
 메서드 설명 next() 다음행으로 커스를 이동(다음행이 없으면 false리턴) getXxx(int columnIndex) columnIndex번째 컬럼의 값을 Xxx타입으로 가져온다 getXxx(String columnName) columnName 컬럼의 값을 Xxx타입으로 가져온다 close() ResultSet객체를 반환
  ResultSet과 관련된 더 많은 메서드는 다음을 참조. http://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
    /* 
- table schema -
  CREATE TABLE member{
    no number(2),
    name varchar2(10),
}
  */
  import java.sql.*;
  public class PSTMTInsert{
    public static void main(String[] args) {
        String driver = "oracle.jdbc.driver.OracleDriver";
        String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
        String dbId = "scott";
        String dbPw = "tiger";
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{       
            Class.forName(driver);
            conn = DriverManager.getConnection(url,dbId,dbPw);
            String sql = "SELECT no, name FROM member";   
            pstmt = conn.prepareStatement(sql);  
            rs = pstmt.executeQuery(); 
            while(rs.next()){
                 System.out.print(rs.getInt("no")); //System.out.print(rs.getInt(1));
                 System.out.print(" ");
                 System.out.print(rs.getString("name")); //System.out.print(rs.getString(1));
            }
        }catch(ClassNostFounException e){
            // driver로딩 실패...
        }catch(SQLException e){
            // sql 예외...
        }finally{
            if(rs != null){ try{ rs.close(); }catch(SQLException e){} }
            if(pstmt != null){ try{ pstmt.close(); }catch(SQLException e){} }
            if(conn != null){ try{ conn.close(); }catch(SQLException e){} }
        }
    } 
  rs에 저장된 레코드의 값을 출력하기 위해서 while문을 이용한다. ResultSet의 next() 메서드로 커스를 이동시켜 다음행에 값이 있으면(리턴값이 true 이면) getXxx() 메서드를 이용해서 값을 가져온다.
  * ResultSet.next() 메서의 커스의 이동
0 notes
coffee-mark · 11 years
Text
JDBC PreparedStatement를 사용한 쿼리 실행
/* 
- table schema -
  CREATE TABLE member{
    no number(2),
    name varchar2(10),
}
  */
  import java.sql.*;
  public class PSTMTInsert{
    public static void main(String[] args) {
        String driver = "oracle.jdbc.driver.OracleDriver";
        String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
        String dbId = "scott";
        String dbPw = "tiger";
        Connection conn = null;
        PreparedStatement pstmt = null;
        try{       
            Class.forName(driver);
            conn = DriverManager.getConnection(url,dbId,dbPw);
            stmt = conn.createStatement();
            String sql = "INSERT INTO member(no, name) VALUES(?, ?)";   
            pstmt = conn.prepareStatement(sql);  
                         pstmt.setInt(1, 1); 
            pstmt.setString(2, "ace"); 
            int row = stmt.executeUpdate(); 
            System.out.println(row + "행 추가됨" );
                        pstmt.setInt(1, 2); 
            pstmt.setString(2, "ruppy"); 
            int row = stmt.executeUpdate(); 
            System.out.println(row + "행 추가됨" );
               }catch(ClassNostFounException e){
            // driver로딩 실패...
        }catch(SQLException e){
            // sql 예외...
        }finally{
            if(pstmt != null){ try{ pstmt.close(); }catch(SQLException e){} }
            if(conn != null){ try{ conn.close(); }catch(SQLException e){} }
        }
    } 
  먼저 쿼리를 PreparedStatement에 저장한다. 이 쿼리 문자에 바인딩 변수는 ?로 표시한다.  ?값을 세팅하기 위해서 setXxx() 메서드를 사용하며, 이 메서드는 위치번호와 위치 표시자에 들어갈 값을 매개변수로 갖는다. 쿼리 문장에 바인딩 변수값을 할당해주었다면 executeUpdate()나 executeQuery() 메서드를 사용해서 쿼리문을 실행하면 된다.
0 notes
coffee-mark · 11 years
Text
JBDC 데이터베이스 쿼리 실행
Connection 객체를 생성한 후에는 Connection으로 부터 쿼리 실행이 가능한 객체를 생성후 데이터베이스에 쿼리를 실행할 수 있다. 쿼리 실행 클래스에는 Statement, PreparedStatement, CallableStatement 3가지가 있다. 이번장에서는 3가지 클래스의 차이점만 설명하고 각 클래스의 사용방법과 자세한 설명은 뒷단원에서 예제와 함께 설명하겠다.
  1. Statement
  정적인 쿼리에 사용되며 하나의 쿼리를 사용하고 나면 더 이상 사용할 수 없다.
...
Connection conn = DriverManager.getConnection(url,id,pass);
Stirng name = "ace";
int age = 20;
  Statement stmt = conn.createStatement();
String sql = "insert into member values('" +name+ "'," +age+ ")";  
int r = stmt.executeUpdate(sql);  // 쿼리를 실행할때 입력한다
stmt.close();
  2. PreparedStatement
  동적인 쿼리에 사용되며 하나의 객체로 여러번의 쿼리를 실행할 수 있다.
sql문장에 정해지지 않은 값을 물음표(?)로 표시하는 바인딩 변수를 사용할 수 있다. 바인딩 변수에 값을 할당하기 위하여 setXxx()메스드를 사용하며, 이 메서드는 물음표의 위치(첫번째 물음표면 1) 값과 실제 할당될 값을 매개변수로 갖는다. 
...
Connection conn = DriverManager.getConnection(url,id,pass);
String sql = "insert into member(name, age) values (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql); //쿼리가 실행전에 미리 만들어져야 한다
  pstmt.setString(1, "ace");
pstmt.setInt(2, 20);
pstmt.executeUpdate();
  // pstmt객체를 재활용도 가능하다
pstmt.setString(1, "ruppy");
pstmt.setInt(2, 18);
pstmt.executeUpdate();
pstmt.close();
  3. CallableStatement
  데이터베이스 내의 스토어드 프로시저(Stored Procedure)를 호출할 때 사용한다.
Connection conn = DriverManager.getConnection(url,id,pass);
CallableStatement cs = conn.prepareCall("{call 프로시저이름(?,?,?)}"); 
//입력용
cs.setString(1,"ace"); 
cs.setInt(2, 20);
//출력용
cs.registerOutParameter(3, java.sql.Types.VARCHAR);   
cs.execute(); 
cs.close();
0 notes
coffee-mark · 11 years
Text
JAVA OOP-추상클래스와 인터페이스
1. 추상 클래스
  상속관계에서 "자동차"라는 클래스를 상속받은 "그랜져"와 "모닝"이라는 클래스가 있다.
구현되는 코드에서는 그랜저 객체나 모닝 객체만을 사용한다고 했을때 자동차라는 객체를 만들지 못하게 하는 방법은 없을까? 
자바언어에서는 클래스 선언시 abstract class라고 해주면 그 클래스의  객체를 만들 수 없다.
  abstract class Car{}
class Grandeur extends Car{}
class Morning extends Car{}
  Car c = new Car(); // 컴파일 에러!
  추상클래스는 객체를 만들수는 없지만 "Car c = new Grandeur();"같이 부모클래스형으로  참조변수(레퍼런스)로는 사용될 수 있다.(다형성)
이것이 추상클래스의 가장 중요한 역할 이기도 하다.
    2. 추상 메서드
  완성되지 못한 메서드. 구현부({...})가 없는 메서드를 말하며 형식은 다음과 같다. abstract 키워드를 사용한다. 실행할 내용이 없으므로 호출될 수도 없다. 추상 메서드의 존재 목적은 "오버라이딩" 이다! 
abstract 리턴타입 메서드이름(....);
    3. 추상 메서드를 가지는 추상 클래스
  추상메서드를 가지는 클래스. 추상클래스는 호출되지 못하는 메서드(추상메서드)를 가지고 있어 객체를 만들 수 없다.
public abstract Person
{
public abstract void move(); 
}
Person p = new Person(); // p.move()를 호출하면 뭘 실행? --> 컴파일 에러! 
추상클래스는 하위클래스를 만들기 위해 존재하고 추상클래스를 상속받은 하위클래스에서 상위클래스의 추상메서드를 오버라이딩 하지 않으면 그 클래스 또한 추상클래스가 된다.
추상 클래스는 확장하지 않으면(서브 클래스를 만들지 않으면) 의미가 없다. 추상 클래스가 있을때 최종적으로 실행되는 코드는 그 추상 클래스의 하위 클래스 객체이다.(물론 객체가 실행되는건 아니고 객체의 메서드가 실행된다)
  public abstract Student extends Person
{
}
public Student2 extends Person
{
public void move(){....} // 오버라이딩
}
    4. 인터페이스
  인터페이스는 클래스의 또 다른 이름이다. 자바의 경우 클래스의 다중 상속은 문법적으로 안되는 것으로 명시되어있어 인터페이스를 이용하여 다중상속의 효과를 낸다.
다중 상속에서 발생하는 문제는 A,B클래스 두개의 클래스를 상속받은 C가 있다고 할때 A,B에 동일한 이름의 메서드를 가지고 있을때 문제가 발생한다.(동일한 이름의 멤버변수도 마찬가지다) 하지만 만약에  A클래스가 추상메서드만을 가지고 있는 경우라면 C입장에서는 중복이 되는 메서드를 가지고 있어도 오버라이딩 해야 하기때문에 다중상속이 가능해진다. 하지만 자바는 다중상속을 지원하지 않으므로 이런 A같은 클래스(추상메서드만 가지는 클래스)를 인터페이스라는 다른 이름으로 정의한다. 인터페이스는 상속이 아닌 구현되어 지면 클래스가 된다.
public interface Testable
{
void test(); 
/* 인터페이스내 모든 메서드는 오버라이딩 되어어야 하는 추상메서드이므로public abstract가 생략한다. */ 
}
public class MyTest implements Testable
{
// 오버라이딩
public void test()
{
System.out.print("myTest");
}
}
- 인터페이스를 이용한 다중상속의 효과
인터페이스는 클래스의 또 다른 이름이지만 문법적으로는 클래스라는 명칭을 사용하지 않고 extends라는 키워드를 사용하지 않기때문에 다음과 같은 방법이 가능하다.
// A클래스는 B클래스를 상속받고 I 인터페이스를 구현한 클래스이다.
public class A extends B implements I
{
....
}
- 인터페이스 내 멤버변수
인터페이스 내에는 static상수(변환지 않는 수)도 올 수 있다. (어차피 하위클래스단에서 값을 바꿀수도 없고 static상수는 클래스명이나 인터페이스명으로 접근하니까...)
public interface Testable
{
int x = 100;
/* static상수 x를 의미하는것으로 public static final int x;의 의미다. public static final는 생략한다. 변할수 없는 상수이므로 초기화도 같이 하는것이 좋다 */
void test(); 
/* 인터페이스내 모든 메서드는 오버라이딩 되어어야 하는 추상메서드이므로 public abstract가 생략한다. */ 
}
외부에서 참조할때는 System.out.print(Testabel.x); 형태로 참조하면 된다.
    5. 인터페이스의 다형성
  인터페이스 클래스이다.(100%의 추상클래스 라고 할까...)
구현된 클래스의 부모형이라 할수 있다. 다형성이 적용된다.
  interface CarInterface{...}
class Eclass implenents CarInterface{...}
CarInterface ci = new Eclass();
  그럼 상속과 구현을 동시에 한 다음과 같은 클래스의 경우는 어떨까?
  interface A{
    void testA();
}
  class B {
    viod testB(){...}
}
  class C extends B implenents A{
    void testA(){...} // 오버라이딩
    void testC(){...}
  class MainTest{
    public static void main(String[] args){
        A a = new C(); // a.testA()만 호출가능
        B b = new C(); // b.testB()만 호출가능
        C c = new C(); // c.testA(), c.testB(), c.testC() 모두 호출 가능 
         // 물론 a와 b의 경우도 강제형변환 후에 호출은 가능하다.
        (C)a.testC();
}
0 notes
coffee-mark · 11 years
Text
JAVA OOP-다형성(polymorphism)
1. 다형성(polymorphism)
  다형성이란 상위 클래스의 타입의 참조변수로 하위클래스의 객체를 참조하는 것을 말한다.
추상클래스나 인터페이스도 상위클래스에 해당한다. 추상클래스를 상속한 클래스의 객체나 인터페이스를 구현한 클래스의 객체를 상위 추상클래스 형이나 인터페이스 형 변수로 참조 가능하다. 추상클래스와 인터페이스는 뒤에 단원에서 설명한다.
  class Person
{
int x;
}
  class Student extends Person
{
int y;
}
Person p = new Student(); // 다형성
// p가 참조할 수 있는 멤버는 Student가 다 가지고 있기에 문제가 없다.
Student s = new Person(); // X compile error!
// s가 참조할 수 있는 멤버가 Person보다 많기에 에러 발생
2. 참조변수의 형변환
  (데이터타입) : 형변환 연산자
ex) (int)2.7 , (String)s, .....
  모든 참조변수는 변수에 객체의 참조값이 들어오기에 강제 형변환이 가능하다. 강제형변환을 하여도 변수가 변한 것이지 객체자체가 변화한 것이 아니므로 실행시 예외가 발생할 수도 있다. 
  Person p = new Person();
Student s = (Student)p; // p변수를 강제로  Student로 형변환 , 정상적으로 컴파일
s.y = 10;
// 실행시 에러! , s가 가르키는 실체 객체는 new Person()으로 만들어 졌기때문에 y가 없다.
  3. 매개변수의 다형성
  abstract class Car
{
abstract void powerOn(); // 추상메서드
}
class Spark extends Car
{
void powerOn()
{
System.out.println("스파크 시동켜다");
}
}
class Morning extends Car
{
void powerOn()
{
System.out.println("모닝 시동켜다");
}
}
class Ray extends Car
{
void powerOn()
{
System.out.println("레이 시동켜다");
}
}
  운전자는 위의 차들을 움직이기 위해서는 오버로딩된 메서드 3개가 필요하다.
  class Driver
{
void carMove(Spark spark)
{
spark.powerOn();
}
void carMove(Morning morning)
{
morning .powerOn();
}
  void carMove(Ray ray)
{
ray.powerOn();
}
}
  하지만 다형성을 이용하면 다음과 같이 하나의 메서드로 가능하다.
class Driver
{
void carMove(Car car)
{
car.powerOn();
}
}
  Car형 car변수는 Spark, Morning, Ray 객체를 다 참조 가능하다. 
다형성을 활용하면 새로운 하위클래스 형식을 프로그램에 추가 하더라도 코드를 굳이 바꿀 필요가 없다. 
    4. instanceof 연산자
  객체 instanceof 클래스이름 : 객체가(객체변수, 참조변수) 뒤의 클래스형으로 참조가 가능하면 true 불가능하면 false
Car c = new Car();
Ray r= new Ray();
if( c instanceof Ray){....} // if조건 false
if( r instanceof Car){....} // if조건 true
※ 메모리 생성 형태로 다형성 이해하기
다형성을 의미론적으로 설명하면 위의 예에서 "학생은 사람이다"와 "사람은 학생이다"에서 문맥상 앞의 문장이 맞는 표현이다.(부모형에 자식형이 들어가는게 맞는 표현이다) 
그럼 메모리에 생성되는 형태로는 어떻게 설명되는가?
다음과 같은 상속관계의 클래스가 있다.
class A{
    int x;
    int y;
    void testOne(){}
    void testTwo(){}
}
class B extends A{
    int y;
    int z;
    void testTwo(){}
    void testThree(){}
}
new A() 실행시 메모리에 참조될 수 있는 A객체의 멤버는 다음과 같다.(최상위 클래스인 Object클래스의 멤버는 당연히 참조되지만 이 설명에서는 생략한다 )
this.x
this.y
this.testOne()
this.testTwo()
new B() 실행시 메모리 참조될 수 있는 B객체의 멤버는 다음과 같다.(하위클래스의 생성자에서 상위 클래스의 생성자를 호출한다고 생성자 부분에서 설명했다. 그 의미를 알고 있다면 아래의 결과가 이해하기 쉬울것이다)
super.x
super.y
super.testOne()
super.testTwo()
this.y
this.z
this.testTwo()
this.testThree()
B클래스의 내부에서는 super, this키워드를 이용하여 동일한 x변수나 testTwo()메서드를 구분하여 호출이 가능하겠지만, B클래스 아닌 다음과 같은 예에서는 B클래스의 객체에 대해서 super나 this같은 키워드 사용이 불가하다.
class C{
    B b = new B();
    // b.super.testTwo(); //이런 형태의 호출은 자바 문법에서는 제공하지 않는다. 
    // b.this.testTwo(); //이런 형태의 호출은 자바 문법에서는 제공하지 않는다.  
    // 만약에 위와 같은 형태의 표현을 자바언어가 지원했다면 자바언어가 좀더 유연해졌을까?
    // 아님 그냥 좀더 배우기 힘든 언어가 되었을까?
    b.testTwo();
}
그럼 위의 testTwo()는 둘중 어떤 메서드를 호출하는가? 자바언어는 다른클래스에서 객체를 생성후 멤버메서드 호출시 this.메서드가 있으면 this.메서드를 호출하고, 없을때만 super.메서드를 호출한다. -> 오버라이딩 
A a = new B(); 되는 이유는 a변수가 참조할 수 있는 x, y, testOne(), testTwo()를 new B()객체(super.x, super.y, this,y, super.testOne(), super.testTwo()(존재는 하지만 오버라이딩때문에 외부에서는 호출불가능) ,this.testTwo())가 다 가지고 있기에 가능한 것이고(다형성), B b = new A();의 경우는 b변수가 참조할 수 있는 x, y, z, testOne(), testTwo(), testThree()를 new A()객체가 다 가지고 있지 않기때문에 오류가 발생한다.
  class A{
    int x = 1;
    void test(){System.out.println("A실행")}
}
  class B extends A{
    int x = 2;
    void test(){System.out.println("B실행")};
}
  class MainTest{
    public static void main(String[] args){
        A a = new B();
        System.out.println(a.x); // 1출력 - 변수는 오버라이딩이 안된다. 부모참조변수로 호출하면 super.x가 호출된다.
                                    // 변수는 오버라이딩 대상이 아니니 부모와 동일한 이름의 변수는 사용금지!
        a.test(); // "B실행"출력 -  메서드 오버라이딩에 의해 super.test()가 아닌 this.test()가 호출된다.   }
    - 부모와 동일한 이름의 변수를 사용하는 것 -> 잘못된 습관
- 부모와 동일한 이름의 메서드를 사용하는 것 -> 잘된 습관(객체지향의 오버라이딩을 사용하는 습관)
0 notes
coffee-mark · 11 years
Text
JAVA OOP-final, static,
1. final 제한자
  final은" 마지막 값이다. 변경 될수 없다"는 의미로
클래스 앞에 붙으면 더 이상 상속될수 없다.
메서드 앞에 붙으면 더 이상 오버라이딩 될 수 없다.
변수(멤버, 지역, static) 앞에 붙으면 더 이상 값을 변경할 수 없다.(상수가 됨) 
    2. static final / final static (final과 static은 순서와 상관없다)
  final 변수는 그 값을 절대 바꿀 수 없다. 그럼 static과 final이 함께 붙어있으면?
보통 pulbic 접근제어자와 함께 사용되어 어떤 코드에서든지 접근 가능한 상수를 만들때 public static final 변수를 사용한다.
다음 클래스의 MAX_GRADE변수는 객체를 생성하지 않아도 어떤 코드에서도 School.MAX_GRADE 형태로 호출이 가능하다
public class School{
    public static final int MAX_GRADE = 6; // 정적변수의 이름은 대문자와 "_"를 보통 사용한다.
}
public class MainTest{
    public static void main(String[] args){
        System.out.println(School.MAX_GRADE);
    }
}
    3. final로 지정된 static 변수 초기화 방법
  public class School{
    public static final int MAX_GRADE = 6;
}
  public class School{
    public static final int MAX_GRADE;
    // 정적변수도 선언만하고 초기화 하지 않으면 이 클래스의 생성자가 호출되어야지만
    // 객체변수와 마찬가지로 타입에 따라 디폴드값인 0, 0.0, false, null로 초기화된다.
}
  그럼 다름과 같은 형태의 정적변수를 초기화 하는 방법은?
  public class Data{
    pulbic static final int[] GRADE = {1,2,3,4,5,6};
    public static final int[] OTHRE_NUM = ? // 0~99 까지의 100개의 배열값 이라면?
    public static final double RANDOM_VALUE = ?; // 정해지지 않은 형태의 상수값 이라면?
}
  자바언어에는 static블럭 이라는 클래스 로딩시점에 실행되는 코드 블럭이 있다. 사용방법은 다음과 같다.
  public class Data{
    public static final int[] OTHRE_NUM = ? // 0~99 까지의 100개의 배열값 이라면?
    static{
        for(int i=0; i<100; i++){
            OTHER_NUM[i] = i;
        }     
    }
}
  public class Data{
    public static final double RANDOM_VALUE = ?;  
    static{
        RANDOM_VALUE = Math.random();
        // Math클래스의 정적random메서드는 0.000... ~ 0.9999... 사이의 랜덤값을 반환한다.
    }
}
0 notes
coffee-mark · 11 years
Text
JAVA OOP-접근제어자와 캡슐화
1. 클래스 접근 제어자
  생략(default) : 같은 패키지의 클래스에서만 객체(인스턴스)생성이 가능하다. 
public : 다른 패키지에서 객체(인스턴스)의 생성이 가능하다. 
    2. 멤버에 접근 제어자
  private : 같은 클래스 내에서만 접근이 가능, 외부객체 접근 불가(this키워드 사용하는 것들), 상속되지도 않는다.
생략(default) : 접근제어자가 없는 형태로 같은 패키지 내에서만 접근이 가능.
protected : 같은 패키지 내에서 사용가능하며, 다른 패키지라도 상속을 받은 클래스는 접근 가능.
public : 모든 객체에서 접근 가능.
  ※ 입문자의 경우 default 사용은 피하고 protected는 객체지향적 설계에서 사용이 많이 되니 입문자는 개념만 이해하고, 특별한 경우가 아니면 public과 private만 사용하자.
    3. 멤버에 접근제어자를 이용한 캡슐화
  클래스의 멤버변수를 외부에서 접근을 막고 public 메서드를 통해서 읽기와 쓰기가 가능하게 함으로서 잘못된 데이터 값이 들어오거나 악의적인 접근을 막을 수있다.
  public class Member
{
private String id;
private int age;
  public String getId()
{
return this.id;
}
public int getAge()
{
return this.age;
}
  public void setId(String id)
{
this.id=id;
}
public void setPw(int age)
{
if(age<0) {
    return; //메서드 종료
}
this.age=age;
}
  private void one() {
     System.out.println("one");
}
private void two() {
     System.out.println("two");
}
public void oneTwo() {
     one();
     two();
}
}
  멤버변수나 메서드를 숨기기 위해서는 private이라는 접근 제어자를 사용했다. 예제에서 멤버변수들을 모두 private으로 선언하여 외부클래스에선 더 이상 그 변수들을 호출할 수 없게 된다. 변수(데이터)의 은폐화가 구현된 것이다.
하지만 이렇게 숨기기만 하면 또 다른 문제가 생긴다. 정작 숨긴 변수들에게 접근을 꼭 해야 할 상황에서조차 접근을 할수 없기 때문이다
변수들을 private선언 하더라도 접근할 수 있다면 public을 쓰는것과 같은것이지않느냐는 것이다. 물론 변수자체를 public을 사용하면 훨씬 편할 수 있다. 하지만 다른측면에서 생각해보자. 멤버변수중 외부에서 값은 열람은 하되 수정은 하지 못하게 하고 싶다면 어떻게 해야할까? 멤버변수를 public으로 그냥 노출시켜놓는다면 외부에서 수정하는 것을 원천적으로 막을 수 가 없다. 그렇기 때문에 get과 set 메서드를 선택적으로 두면 멤버변수는 읽기전용 혹은 쓰기 전용 식으로 데이터에 대한 접근 권한을 더 세분화 할 수 있다는 장점이 있고 또한 위의 코드를 보면 age같은 속성에는 음수값이 들어오면 안된다. 마이너스 나이라는것이 있을수가 없기 때문이다. 그렇기 때문에 set 메소드에 로직을 추가하여 음수값은 저장될 수 없게 원천적으로 막을 수가 있다.
onw(), two() 메서드 역시 private으로 외부호출을 막고 oneTwo() 메서드만을 public으로 외부호출이 되도록 하여 one(), two() 두 메서드가 연속적으로 같이 호출되도록만 하고 개별적 호출은 되지않도록 캡슐화 하였다.
  즉 캡슐화의 결정적인 이유는 데이터에 대한 읽기 쓰기 권한 구분과 입력된 데이터의 유효성을 검증할 수 있는 부분을 코드에 포함시킬 수 있다는 것 이다.
    4. 캡슐화 예제
  class Pay
{
  public int rate; //시간당 단가
  public Pay()
  {
    this.rate = 5000;
  }
  // 시간당 급여를 지불하는 메서드
  public int sendPay(int hour)
  {
    return hour*rate;
  } 
}
위의 클래스는 아르바이트생에게 시간당 5000원씩 지급하는 시스템 클래스중 일부이다.
ex1)무슨 문제가 발생할 수 있는가?
  누군가 코딩중 실수로 rate값을 바꾼다면 어떻게 될까? 그래서.... 
  class Pay
{
  private int rate; //시간당 단가
  public Pay()
  {
    this.rate = 5000;
  }
  // 시간당 급여를 지불하는 메서드
  public int sendPay(int hour)
  {
    return hour*rate;
  } 
}
ex2) 위와 같이 수정후에는 어떠한 문제가 발생할까?
  rate값을 수정하지 못하지만 값을 읽어올수는 있어야 한다면...
프로그램 실행중에 rate값이 수시로 변해야 한다면...아무나 바꿀수 없게지만 권한있는 접근자에게는 허락하고 싶다면...
그래서...setter 와 getter를 이용한 캡슐화...
  class Pay
{
  private int rate; //시간당 단가
  public Pay()
  {
    this.rate = 5000;
  }
  // 시간당 급여를 지불하는 메서드
  public int sendPay(int hour)
  {
    return hour*rate;
  } 
  //getter 추가
  public int getRate()
  {
    return this.rate;
  }
//setter 추가
  public void setRate(String id, String pw, int rate)
  {
    if(id.equals("admin") && pw.equals("1234")
    {
      this.rate = rate;  
    }
    else
    {
      System.out.println("아무나 rate값을 변경할 수 없습니다.");
    }
  }
}
0 notes