Window -> Preferences -> General -> Editors -> Text Editors 
Show whitespace characters 체크




적용을 하면 탭, 스페이스 , 엔터가 표시가 된다.



예시



HTML


<div class="box">

  <img src="https://t1.daumcdn.net/cfile/tistory/99FB9E335A0696E312">

</div>


CSS


.box{

   height:200px;

   width: 200px;

   overflow: hidden;   

    }

.box img{

   height:100%;

   width: 100%;

   object-fit:cover;     


/* 마우스가 이미지를 벗어 났을 때도 자연스럽게 크기가 줄어들기 위함 */

   transform:scale(1.0);        

   transition: transform .5s; 

}

.box img:hover{            /* 마우스 호버시 */

   transform:scale(1.5);            /* 이미지 확대 */

   transition: transform .5s; /*  시간 설정  */

}


/*

*/






CSS에 추가

.ui-autocomplete {

  z-index:2147483647;

}


출처:https://stackoverflow.com/questions/16133654/autocomplete-issue-into-bootstrap-modal

<input type='file' accept='image/*' onchange='openFile(event)'><br>

<img id='output'>

<script>

  var openFile = function(event) {

    var input = event.target;


    var reader = new FileReader();

    reader.onload = function(){

      var dataURL = reader.result;

      var output = document.getElementById('output');

      output.src = dataURL;

    };

    reader.readAsDataURL(input.files[0]);

  };

</script>



실행 예시





출처:http://www.javascripture.com/FileReader

html,body,.container {

    height:100%;

}

.container {

    display:table;

    width: 100%;

    margin-top: -50px;

    padding: 50px 0 0 0; /*set left/right padding according to needs*/

    box-sizing: border-box;

}


.row {

    height: 100%;

    display: table-row;

}


.row .no-float {

  display: table-cell;

  float: none;

}





<원인>

eclipse.ini 에서 vm을 jdk 경로로 설정하였으나, 인식하지 못함.

vm을 설정할 때 jdk의 운영체제 bit 와 eclipse의 운영체제 bit가 일치해야함.

32bit eclipse를 사용할 경우 vm 경로를 32bit jre 경로로 설정해야 함.

64bit eclipse를 사용할 경우 vm 경로를 64bit jre 경로로 설정해야 함.


<해결방안>


eclipse.ini 에서 vm 경로를 jre 경로로 설정.


<eclipse.ini>


-startup

plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar

–launcher.library

plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.1.200.v20120522-1813

-product

org.eclipse.epp.package.jee.product

–launcher.defaultAction

openFile

–launcher.XXMaxPermSize

256M

-showsplash

org.eclipse.platform

–launcher.XXMaxPermSize

256m

–launcher.defaultAction

openFile

-vm

C:/Program Files (x86)/Java/jre7/bin/javaw.exe

-vmargs

-Dosgi.requiredJavaVersion=1.5

-Dhelp.lucene.tokenizer=standard

-Xms512m

-Xmx512m

-Dfile.encoding=UTF-8


출처:http://blog.daum.net/chemusic/51


 Web 서버

- HTTP 프로토콜을 기반으로 하여, Web 클라이언트(브라우저) 부터의 요청을 서비스 하는 기능을 담당하는

프로그램(일반적으로 Apache 많이 사용함)

- Web 서버의 역할은 html, 이미지(jpg, gif.. ), xml 등에 대한 처리를 담당(CGI 프로그램 요청도 처리)

 Web Appication 서버

여러 Web 클라이언트(브라우저) 요구를 Web 서버 혼자 감당하기에는 힘들기 때문에구조적으로 Web

서버의 기능을 분리하기 위해 만들어진 것으로 Web Applicatioin Server(WAS)라고 한다.(일반적으로

Tomcat, Weblogic, WebShpare, Jeus, JBoss 등이 이용된다.)

 Web 서버와 Web Applicatiion 서버의 차이점

- Web 서버와 Web Application 서버는 위의 설명처럼 사용의 목적이 다르다. Web 서버는 html, 이미지들의 요청을 처리하는데 빠르고 , Web Application 서버는 Servlet이나, JSP 비지니스 로직을 수행하는데 적합하다.(웹컨테이너란 이러한 ServletJSP 수행하는 역할을 하는 서버를 말한다.) 그렇다고 Web Application Server html, 이미지들의 요청을 처리하지 못한다는 얘기는 아니다다만 처리 속도가 Web 서버에 비해 느리다는  뿐이다이렇게 서로 다른 강점을 합해서 사용하기 위해 Web 서버와 Web Application 서버를 연동하여 서비스를 하는 것이 대부분이다.

 [참조] JSP 기초 http://cafe.naver.com/tonkjsp/6

 Tomcat

- Tomcat JSP 환경을 포함하고 있는 Servlet 컨테이너

- Servlet 컨테이너는 사용자 입장에서 Servlet 유지하고 호출하여 실행하는 

- Tomcat 크게 3가지로 컨테이너로 구분한다.

 Stand-alone servlet containers(Tomcat 기본 모드)

내장된 웹서버의 기능을 사용하는 

기능면에서 JavaWebServer 부분인 Serlvet 컨테이너와 Java 근간  서버를 사용

 In-process servlet containers

- Servlet 컨테이너는 웹서버 플러그인과 Java 컨테이너 구현

웹서버 플러그인은 웹서버의 주소 공간 내에 JVM 열고  안에서 JAVA 컨테이너가 실행되도록 한다.

다중 스레드의 단일 프로세스 서버에 적당하고 퍼포먼스도 좋지만 확장성에 한계가 있음

 Out-of-process servlet containers

웹서버 플러그인과 웹서버의 외부 JVM에서 실행하는 JAVA 컨테이너 구현

웹서버 플러그인과 JAVA 컨테이너 JVM 몇몇 IPC(보통은 TCP/IP 소켓) 사용해서 통신

- Out-of-process 엔진의 반응 시간은 in-process 만큼 좋지 않지만 out-of-process 엔진은 확장성과 안전성 면은 In-process보다 좋다.

 톰캣 디렉토리 구조

- tomcat 6.0 에서는  그림 처럼 되어 있지 않고 common, server 빠진 상태로 되어 있다.

- common, server 빠진 상태로 정리하면

디렉토리명

기능 설명

bin

여기에는 톰캣 서버의 동작을 제어할  있는 스크립트  실행 파일들이 포함되어 있습니다.

conf

톰캣의 기본적인 설정 파일들이 포함되어 있습니다.

lib

아파치와 같은 다른  서버와 톰캣을 연결해주는 바이너리 모듈들이 포함되어 있습니다.

webapps

톰캣이 제공하는  애플리케이션의 기본 위치입니다.

logs

서버의 로그 파일이 저장되는 디렉토리입니다.

Work

JSP 컨테이너와 다른 파일들이 생성하는 임시 디렉토리입니다.

temp

임시 저장 폴더

위의 그림과 같이 항상 같은 구조를 표준 처럼 유지 되어야 한다. 




요구되는
 형태로  어플리케이션 보관소 생성을 용이하게 하기 위해서 어플리케이션의 "실행파일들( 어플리케이션을 실행할  톰캣이 사용하는 파일들) WAR 형식에서 요구하는 것과 같은 구성으로 정리하는게 편합니다이렇게 하려면 어플리케이션의 "문서 루트 document root" 디렉토리에 다음 내용으로 구성합니다

  • *.html, *.jsp, 등. - 웹 어플리케이션에서 클라이언트 브라우저로 전송이 되는 HTML 과 JSP 페이지와 다른 파일들 (예를 들면 자바스크립트, 스타일시트, 이미지 같은). 대규모 어플리케이션에서 이 파일들을 서브디렉토리 체계로 나누어 놓을 수 있습니다. 그러나 규모가 작은 어플리케이션이라면 보통은 하나의 디렉토리에서 전체를 관리하는 것이 보다 단순하고 쉽습니다.
  • /WEB-INF/web.xml - 웹 어플리케이션의 웹 어플리케이션 배치 설명자 Web Application Deployment Descriptor. 서블릿과 웹어플리케이션을 구성하는 다른 컴포넌트들을 설명하고, 각종 초기화 파라메터들과 서버 기능을 활용하기 위한 컨테이너가 관리하는 보안 제한 구역을 지정하는 XML 파일입니다. 다음 섹션에서 좀 더 자세히 알아보도록 하겠습니다.
  • /WEB-INF/classes/ - 이 디렉토리에는 웹 어플리케이션에서 사용하는 모든 자바 파일(그리고, 관련 자원)이 들어있습니다. 서블릿과 비서블릿 클래스 파일들이며 jar 형태로 묶여있지 않은 것입니다. 패키지가 선언된 클래스라면 /WEB-INF/classes/ 를 기준으로 패키지의 디렉토리를 만들어 구성하면 됩니다. 예를 들어, 클래스명이 com.mycompany.mypackage.MyServlet 라면 파일의 저장경로는 /WEB-INF/classes/com/mycompany/mypackage/MyServlet.class 이 됩니다.
  • /WEB-INF/lib/ - 이 디렉토리에는 웹어플리케이션에서 사용하는 자바 클래스파일을 포함하는 JAR 파일들이 위치합니다. 외부 클래스 라이브러리나 JDBC 드라이버 같은 것들입니다.

톰캣(또는 다른 2.2/2.3 호환 서버)에 어플리케이션을 설치할 때, WEB-INF/classes/ 에 있는 클래스들과 WEB-INF/lib/ 디렉토리에 있는 JAR파일에 있는 모든 클래스들은 같은 웹 어플리케이션에서 사용하는 모든 클래스가 접근가능하게 되어있습니다. 따라서, 만일 이 디렉토리 안에 사용하는 모든 라이브러리 클래스들을 몰아 넣으면 (외부 라이브러리를 사용하는 경우 재배포 권한에 관한 라이센스를 확인하길 바랍니다.), 웹 어플리케이션의 설치가 간단히 끝날 수 있습니다 -- 시스템 클래스패스에 대한 조정(또는 서버에 있는 전체 라이브러리의 설치)도 필요 없습니다.

 톰캣 환경설정(server.xml)

- tomcat에서 주요한 환경설정 파일  하나 입니다.

컴포넌트에 대한 초기 설정 제공

- tomcat 대한 구조를 지정

- server.xml 구조  계층적 엘리먼트

상위의 속성은 자동적으로 하위의 요소에 계승된다예를 들어 <Host> 구성요소 <Logger>  속성은 아무것도 지정하지 않은 경우 <Engine> 구성 요소 <Logger> 설정이 사용된다변경이 필요한 경우에는 <Host> 구성요소 <Logger> 별도의 설정을 함으로서 상위의 설정을 덮어 쓸수 있다.



 server 엘리먼트

tomcat 서버 구성요소의 정의 부분이다기본값은 <server port="8005" shutdown="shutdown"> 되어 있으며포트 8005 감시하고 shutdown 명령어를 접수하도록 설정되어 있다서버에서는 복수의 서비스를 관련 지울  있다.

 service 엘리먼트

tomcat service 구성요소를 정의하고 있다. <service> 뒤에 기술  <Engine> 그것에 관련된 모든 <Connector> 그룹화  것이다기본값은 <Service name="Catalina"> 되어 있다. (name 으로 "Tomcat-Standalone" 설정하는 경우도 있음)

-> 속성

■ name : Catalina라고 하는이름으로 서비스가 정의 되어 있고에러 로그  관리툴은  이름으로 식별한다.

하나의 서버에 복수의 서비스를 정의하는 경우다른 name 속성을 기입할 필요가 있다 .

<Serice> <Engine> 하나 이상의 <Connector> 관련짓는 것이 가능하다. <Service> <Engine> 관계는 1:1

 Engine 엘리먼트

<Engine> servlet 컨테이너의 인스턴스를 표시하며, <Connector>로부터 보내진 요구를 처리한다. <Engine name="Catalina" defaultHost="localhost"> 되어 있다.

-> 속성

■ name : <Engine> 이름을 표시하며에러 로그  관리툴은  이름으로 <Engine> 식별한다.

■ defaulthost : server.xml 정의 되어 있지 않은 <Host> 요구가 있을 경우 발송되는 가상호스트를 지정한다.

<Engine>에는 하나 이상의 <Host> 관련지어져 있다.

 Connector 엘리먼트

요구를 <Engine> 건네 주는 역할을 하는 것이 <Connector>. <Serviced> 하나 이상의 <Connector> 갖을 필요 있음

사용자는 HTTP 또는 HTTP/SSL  여러가지 방법으로 <Engine> 요구를 보낸다이것들의 접속 요건의 처리는 <Connector>

구성요소에 맡겨진다 프로토콜에 대해 복수의 <Connector> 갖는 것으로서 어떤 접속에서 요구가 보내져와도 <Engine>

 동일하게 처리하고 , 응답을 <Connector> 맡길  있다.

tomcat에는 몇개의 표준<connector> 탑재되어 있으며기본값은 HTTP1.1 <Connector> AJP<Connector> 준비되어 .

 DefaultContext 엘리먼트

모든 <Conext> 고통의 정의부기본적으로 설정되어 있지 않다.

 Realm 엘리먼트

보안을 위해 role명과 사용자명비밀번호의 맵핑을 외부의 데이터베이스로 부터 가져오는 장치다. tomcat UserDataBase, Memory, JDBC, JNDI 몇개의 <Realm> 가지고 있다.

 <Realm> 차이는 어디로 부터 정보를 가져왔는가의 차이밖에 없다기본값으로는 UserDataBase이외의 <Realm> 주석 처리되어 무효로 되어 있다.

 Logger 엘리먼트

로그파일의 작성 방법을 설정한다. <Logger> server.xml 구조에서 보듯이 <Engine>레벨에서 설정할  있다.

<Logger className="org.apache.catalina.logger.FileLogger">

prefix="server-log." suffix=".txt"

timestamp="true"/>

위의 <>에서는 tomcat FileLogger 클래스를 사용, prefix, suffix, timestamp 속성에서 로그파일명을 정의하고 있다 경우로그파일은 [server-log.2008_08.txt] 같은 형식으로 $CATALINA_HOMe/log 디렉토리에 출력된다.

 Host 엘리먼트

<Engine> 관련된 가상호스트를 정의한다.. 기본값으로 다음과 같이 되어 있다.

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">

가상 호스트명을 "localhost" 설정하고 appBase 속성에서 어플리케이션이 탑재되어 있는 디렉토리를 "webapps" 설정하고 있다별도로 unpackWARs에서는 WAR파일을 전개하고나서 실행할 것인지의 여부를 , autoDeploy 속성에서는 tomcat 기동중에 웹어플리케이션을 배치한 경우에 자동으로 읽어 들일 것인지의 여붜를 설정할  있다.

 Value 엘리먼트

tomcat 특유의 기능이다. <Value> 상위 구성요소로의 필터 처리를 담당한다. <Engine>, <Host>, <Context> 관련짓는 것이 가능하다, Tomat에는 표준으로 다음과 같은 몇개의 <Value> 준비되어 있다.

AccessLogValue

<Valve className="org.apache.catalina.valves.AccessLogValve"

directory="logs" prefix="server-log-" fileDateFormat="yyyy-MM-dd" suffix=".txt"/>

RemoteAccessValve

<Valve className="org.apache.catalina.valves.RemoteAddrValve"

allow="127.0.0.1,192.168.0.1" />

SingleSignOnValue

<Valve className="org.apache.catalina.authenticator.SingleSignOn"/>

RequestDumpValue

<Valve className="org.apache.catalina.valves.RequestDumperValve"/>

- AccessLogValue

$CATALINA_HOME/logs 디렉토리에 server-log-2008-08-04.txt  형식으로 로그파일을 작성한다.

- RemoteAccessValue

접근을 IP주소 단위로 제한한다지정주소에서의 접근을 허가거부를 설정할  있다. <>에서는 로컬 IP주소 192.168.0.1 부터의 접근을 허가하고 있다 RemoteHostValue 사용하면 호스트 단위로 접근제한을 설정할  있다.

- SingleSignOnValue

요구와 응답의 헤더와 쿠키를 <Logger> 설정한 로그파일이 작성된다.

 Context 요소

<Host>에는 웹어플리케이션의 복수개의 <Context> 관련지어져 있다. <Context> 요소에는 웹어플리케이션의 일련의 설정 프로퍼티가 들어간다웹어프리케이션 배치에서 소개 한대로  설정은 웹어플리케이션마다에 설정파일을 가질  있다.

- <Logger> 엘리먼트 사용하는 경우

<Logger className="org.apache.catalina.logger.FileLogger"

directory="logs" prefix="localhost_log." suffix=".txt"

timestamp="true"/>

Logger 잠시보면 로거로 FileLogger라는 클래스를 사용할 것이며디렉토리는 톰캣의

logs 디렉토리를 , 파일명은 localhost_log.yyyy-mm-dd.txt 하겠다는 

속성

설명

backgroundProcessorDelay

 값은 컨텍스트와  자식 컨테이너에서 background process method invoke되는delay 시간을 나타낸다.

 값을 양수로 설정하면 어떤 쓰레드가 분기되어 일정 시간 후에  쓰레드가 해당 host 자식 컨테이너에서 background process method 실행시킵니다

만약 설정하지 않으면 디폴트값인 -1 가지며 음수의 값은 부모 host background processing 정책을 사용한다는 것입니다.

참고로 컨텍스트는 세션을 종료하거나 클래스 리로딩을 위한 모니터링등을 위해background processing 사용합니다.

className

사용할 Java 구현체 클래스의 이름 클래스는 반드시 org.apache.catalina.Context인터페이스를 구현해야 합니다지정하지 않으면 표준값 (아래에 정의됩니다) 사용됩니다

cookies

true(디폴트) 지정하면 클라이언트가 쿠키를 지원하는 경우 세션확인의 통신수단(session identifier communication)으로 쿠키를 사용합니다. false 지정하면 세션확인의 통신수단으로 쿠키 사용을 하지 않고어플리케이션에 의한 URL 다시쓰기(URL rewriting)에만 의존한다는 의미입니다.

crossContext

true 지정하면  어플리케이션에서 ServletContext.getContext() 호출을 통해 가상호스트에서 실행중인 다른 웹어플리케이션에 대한 요청디스패쳐(request dispatcher) 성공적으로 얻을  있습니다보안상의 이유로 false(디폴트) 지정하면getContext() 언제나 null 반환하게 됩니다.

docBase

 웹어플리케이션에 대한 Document Base (Context Root로도 알려져 있습니다디렉토리또는 웹어플리케이션 아카이브 파일의 경로명(웹어플리케이션을 WAR 파일로 직접 실행하는 경우) 나타냅니다 디렉토리나 WAR 파일에에 대한 절대경로명을 지정할 수도 있고 Context 정의된 Host appBase 디렉토리에 대한 상대경로명을 지정할 수도 있습니다

override

true 설정하면 DefaultContext element 관련된 host에서 명백하게 상속받아 사용합니다

기본값으로 Defaultcontext element 사용됩니다

privileged

true 설정하면  컨텍스트는 관리자서블릿(manager servlet) 같은 컨테이너 서블릿을사용할  있습니다.

path

 웹어플리케이션의 컨텍스트 경로(context path) 나타내며 요청 URI 시작부분이 컨텍스트 경로와 같을  해당 웹어플리케이션이  요청을 처리하게 됩니다하나의특정 Host 내의 컨텍스트 경로들은 모두 각각 유일해야 합니다만약 컨텍스트 경로를 스트링("")으로 지정하면 Context  Host 대한 디폴트 웹어플리케이션으로정의된 것입니다디폴트 웹어플리케이션은 다른 Context 들에 해당되지 않는 모든 요청을 처리할 것입니다.

reloadable

true 지정하면, Catalina /WEB-INF/classes/ /WEB-INF/lib  클래스 들의 변경여부를 감시하다가변경이 발견되면 웹어플리케이션을 자동으로 재적재(reload)합니다. 기능은 개발중에는 매우 유용하지만 얼마간의 실행부하(runtime overhead) 발생하므로실제 운영할 용도로 어플리케이션을 배치(deploy) 때는 사용하지 않도록 합니다그러나 이미 배치가 끝난 어플리케이션이라도 Manager 웹어플리케이션을 이용하면필요할  재적재 하도록   있습니다

wrapperClass

 Context 관리할 서블릿 들에 대해 사용할 org.apache.catalina.Wrapper 구현체 클래스의 Java 클래스명입니다지정하지 않으면 표준값이 사용됩니다

from http://jakarta.apache.org

=============================================

저자 : GoodBug (unicorn@jakartaproject.com)

최초 : http://www.jakartaproject.com

=============================================

 서블릿 환경설정 (web.xml)

 CATALINA(톰캣 설치 폴더)/conf/web.xml

 invoker 이용하여 모든 서블릿을 호출할  있는 서블릿을 지정합니다.

<servlet>

<servlet-name>invoker</servlet-name>

<servlet-class>

org.apache.catalina.servlets.InvokerServlet

</servlet-class>

<init-param>

<param-name>debug</param-name>

<param-value>0</param-value>

</init-param>

<load-on-startup>2</load-on-startup>

</servlet>

 서블렛을 사용   있도록 환경을 설정하고 Servlet URL상에서의 접근할  있도록 경로명을 지정합니다.

<servlet-mapping>

<servlet-name>invoker</servlet-name>

<url-pattern>/servlet/*</url-pattern>

</servlet-mapping>

 수정된 Servlet,JSP 페이지가 서버를 재시작안해도 인식이 설정

<servlet>

<servlet-name>jsp</servlet-name>

<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>

<init-param>

<param-name>modificationTestInterval</param-name>

<param-value>0</param-value>

</init-param>

<init-param>

<param-name>development</param-name>

<param-value>true</param-value>

</init-param>

<init-param>

<param-name>fork</param-name>

<param-value>false</param-value>

</init-param>

<init-param>

<param-name>reloading</param-name>

<param-value>true</param-value>

</init-param>

<init-param>

<param-name>xpoweredBy</param-name>

<param-value>false</param-value>

</init-param>

<load-on-startup>3</load-on-startup>

</servlet>



출처: http://jang8584.tistory.com/72 [개발자의 길]

static

static 이란

클래스 필드 또는 메소드 앞에 static 키워드를 사용하므로서 필드, 메소드를 인스턴스의 생성없이 사용 할 수있게한다.

 

목적

모든 인스턴스가 동일 정보를 공유 해야 할때 또는 

메소드가 인스턴스의 데이터와는 상관없이 공통적인 로직이 정의될때

인스턴스마다 할당 된다면 메모리 낭비 뿐만 아니라 데이터를 참조 하거나 호출 할때마다 인스턴스를 생성해야하는등의 번거로움과 인스턴스 메모리해제에 의해 정보손실을 발생시킬 수 있다.

static 을 통하여 이러한 점들을 해결 할 수있다.

인스턴스 생성과정이 없어도 되기때문에 속도 또한 빠르다.

 

 원리

인스턴스가 생성되면 heap 영역에 할당 되어 사용되어진다. 하지만 static 키워드를 붙인 변수와 메소드는 클래스 정보가 할당되는 Method Area에 클래스가 할당 될때 같이 올라가게된다.  heap영역은 가비지 컬렉터의 영향을 받지만 Method Area의 경우 가비지컬렉터의 영향을 받지않고 메모리에 상주 할 수있게 된다.

 

 주의 사항

메모리 누수

static을 통해 메모리가 할당될 경우 클래스가 메모리상에 올라갈때 같이 올라가고 가비지 컬렉터의 영향밖에 있게때문에 프로그램이 종료 될 때까지 메모리를 회수 할 수없다.

신뢰성 하락

static은 언제 어디서든 접근 할 수있다. 그렇기에 언제 어디서 어떻게 변할지 모르는데 멀티스레드 환경에서는 더더욱 static의 상태를 예상하기 어려워진다.

 

어떨때 사용하는 것이 적절할까

상태를 저장하거나 변경하지 않는 경우에 사용하는 것이 적절하다.

예를 들면 Math.PI 에경우 final static 처리되어 상수로 사용되어지고

 Integer.parseInt() 경우 메소드 처리과정에서 어떻한 상태도 변경하지않고 단순히 입력받은 문자열을 정수로 반환 할 뿐이다.


static을 사용하면 편리하기도 하지만 전반적으로 사용을 지양하려는 의견이 많다.

관련 링크




프로그램 구조

Java

package hello;


public class HelloWorld {
   public static void main(String[] args) {
      String name = "Java";

      // 매개변수를 확인
      if (args.length == 1)
         name = args[0];

      System.out.println("Hello, " + name + "!");
    }
}

C#

using System; 

namespace Hello {
   public class HelloWorld {
      public static void Main(string[] args) {
         string name = "C#";

         // 매개변수를 확인
         if (args.Length == 1)
            name = args[0];

         Console.WriteLine("Hello, " + name + "!");
      }
   }
}

Java 소스 파일의 확장자는 *.java이고, C#은 *.cs이다.

Java는 클래스마다 별도의 파일을 작성해야 하고 클래스명과 파일명이 일치해야 하지만, C#에서는 하나 이상의 최상위 클래스를 작성할 수 있고 파일명에 대한 제한도 없다.

Java

package harding.compsci.graphics;










// 단일 클래스를 임포트
import harding.compsci.graphics.Rectangle;
// 여러 클래스를 임포트
import harding.compsci.graphics.*; 

C#

namespace Harding.Compsci.Graphics {
  ...
}
또는
namespace Harding {
  namespace Compsci {
    namespace Graphics {
      ...
    }
  }
}
// 단일 클래스를 임포트
using Rectangle = Harding.CompSci.Graphics.Rectangle;
// 여러 클래스를 임포트
using Harding.Compsci.Graphics;

Java는 소스 코드의 첫 줄에 package를 선언하지만, C#에서는 namespace 키워드를 사용해서 블록으로 묶는다. C#에서는 하나의 소스 코드 파일에 여러 개의 네임스페이스를 포함시는 것도 가능하다.

Java의 import 키워드 대신, C#에서는 using 키워드를 사용한다. using 키워드를 namespace 블록 내부에 사용할 수도 있다. using 키워드를 사용해서 별칭을 지정할 수도 있다.

주석

Java

// 한 줄 주석
/* 여러 줄
    주석  */
/** 자바독 문서화 주석 */

C#

// 한 줄 주석
/* 여러 줄
    주석  */
/// 한 줄 XML 주석
/** 여러 줄 XML 주석 */

자료형

Java

원시 자료형
boolean
byte
char
short, int, long
float, double


참조 자료형
Object   (다른 모든 클래스들의 부모 클래스)
String
arrays, classes, interfaces

형 변환
// 정수를 문자열로 
int x = 123; 
String y = Integer.toString(x);  // y is "123"
// 문자열을 정수로
y = "456"; 
x = Integer.parseInt(y);   // x is 456
// 부동소수를 정수로
double z = 3.5; 
x = (int) z;   // x는 3  (소수부는 잘림)

C#

값 타입
bool
byte, sbyte
char
short, ushort, int, uint, long, ulong
float, double, decimal
structures, enumerations

참조 자료형
object    ( 다른 모든 클래스들의 부모 클래스)
string
arrays, classes, interfaces, delegates

형 변환
// 정수를 문자열로 
int x = 123; 
String y = x.ToString();  // y is "123"
// 문자열을 정수로
y = "456"; 
x = int.Parse(y);   // 또는 x = Convert.ToInt32(y);
// 부동소수를 정수로
double z = 3.5; 
x = (int) z;   // x는 3  (소수부는 잘림)

Java에서 지원되는 원시 자료형과 더불어, C#에서는 부호 없는(unsigned) 자료형과 128비트 부동 소수 형식(decimal)을 추가로 지원한다.

Java에서는 원시 자료형이 존재하고 각각의 래퍼 클래스가 존재하지만, C#에서 모든 원시 자료형은 System 네임스페이스의 객체이며 각각 별칭이 존재한다.

Java의 boolean은 C#에서 bool이다.

상수

Java

// 생성자에서 초기화 될 수 있음
final double PI = 3.14;

C#

const double PI = 3.14;

// const 또는 변수에 지정할 수 있음. 생성자에서 초기화 될 수 있음.
readonly int MAX_HEIGHT = 9;

Java에서는 final 키워드를, C#에서는 const와 readonly 키워드를 사용한다.

const 키워드를 사용하면 런타임시에 값을 변경할 수 없지만, readonly 키워드를 지정하면 런타임시에 단 한번 값을 지정할 수 있다.

열거형

Java

enum Action {Start, Stop, Rewind, Forward};
// 특수한 형태의 클래스이다. 
enum Status {
  Flunk(50), Pass(70), Excel(90);
  private final int value;
  Status(int value) { this.value = value; }
  public int value() { return value; } 
};
Action a = Action.Stop;
if (a != Action.Start)
  System.out.println(a);      // Prints "Stop"
Status s = Status.Pass;
System.out.println(s.value());      // Prints "70"

C#

enum Action {Start, Stop, Rewind, Forward};
enum Status {Flunk = 50, Pass = 70, Excel = 90};






Action a = Action.Stop;
if (a != Action.Start)
  Console.WriteLine(a);             // Prints "Stop"
Status s = Status.Pass;
Console.WriteLine((int) s);       // Prints "70"

Java 1.5 이상에서 enum을 지원한다.

C# 3.0 이상에서는 확장메서드를 통해서 enum 타입에 메서드를 정의할 수 있다.

연산자

Java

비교
==  <  >  <=  >=  !=

산술
+  -  *  /
%  (mod)
/   (integer division if both operands are ints)
Math.Pow(x, y)

할당
=  +=  -=  *=  /=   %=   &=  |=  ^=  <<=  >>=  >>>=  ++  --

비트
&  |  ^   ~  <<  >>  >>>

논리
&&  ||  &  |   ^   !

문자열 결합
+

C#

비교
==  <  >  <=  >=  !=

산술
+  -  *  /
%  (mod)
/   (integer division if both operands are ints)
Math.Pow(x, y)

할당
=  +=  -=  *=  /=   %=  &=  |=  ^=  <<=  >>=  ++  --


비트
&  |  ^   ~  <<  >>

논리
&&  ||  &  |   ^   !

문자열 결합
+

연산자 오버로딩
public static ComplexNumber operator+(ComplexNumber a, ComplexNumber b) { ...

Java의 >>> 연산자는 C#에서 사용할 수 없다. 이는 부호없는 자료형이 지원되기 때문이다.

C#의 checked, unchecked 키워드를 사용해서 오버플로우를 검사할 수 있다.

C#에서는 연산자 오버로딩을 위해 operator 키워드를 지원한다.

연산자 오버로딩은 static 메서드로 선언하고 메서드 이름 대신에 operator 키워드와 연산자 심볼을 붙인다.

조건문

Java

greeting = age < 20 ? "What's up?" : "Hello";

if (x < y) 
  System.out.println("greater");

if (x != 100) {    
  x *= 5; 
  y *= 2; 
} 
else 
  z *= 6;

int selection = 2;
switch (selection) { // byte, short, int, char, enum
  case 1: x++;   // break가 없으면 다음으로 넘어간다
  case 2: y++;   break; 
  case 3: z++;   break; 
  default: other++;
}

C#

greeting = age < 20 ? "What's up?" : "Hello";

if (x < y)  
  Console.WriteLine("greater");

if (x != 100) {    
  x *= 5; 
  y *= 2; 
} 
else 
  z *= 6;

string color = "red";
switch (color) {    //자료형 제한이 없다.
  case "red":    r++;    break;  // break 꼭 필요
  case "blue":   b++;   break; 
  case "green": g++;   break; 
  default: other++;     break; 
}

Java 7이후부터 switch문에 문자열을 사용할 수 있다.

Java와 달리 C#에서는 case문 다음에 반드시 break문이 존재해야 한다.

반복문

Java

while (i < 10) 
  i++;

for (i = 2; i <= 10; i += 2) 
  System.out.println(i);

do 
  i++; 
while (i < 10);

for (int i : numArray)  // foreach construct  
  sum += i;

import java.util.ArrayList;
ArrayList<Object> list = new ArrayList<Object>();
list.add(10); 
list.add("Bisons");
list.add(2.3);    
for (Object o : list)
  System.out.println(o);

C#

while (i < 10) 
  i++;

for (i = 2; i <= 10; i += 2) 
  Console.WriteLine(i);

do 
  i++; 
while (i < 10);

foreach (int i in numArray)  
  sum += i;
 
using System.Collections;
ArrayList list = new ArrayList();
list.Add(10);
list.Add("Bisons");
list.Add(2.3);
foreach (Object o in list)
  Console.WriteLine(o);

배열

Java

int nums[] = {1, 2, 3};   
     또는   int[] nums = {1, 2, 3};

for (int i = 0; i < nums.length; i++)
  System.out.println(nums[i]);

String names[] = new String[5];
names[0] = "David";

float twoD[][] = new float[rows][cols];
twoD[2][0] = 4.5;

int[][] jagged = new int[5][]; 
jagged[0] = new int[5]; 
jagged[1] = new int[2]; 
jagged[2] = new int[3]; 
jagged[0][4] = 5;

C#

int[] nums = {1, 2, 3};


for (int i = 0; i < nums.Length; i++)
  Console.WriteLine(nums[i]);

string[] names = new string[5];
names[0] = "David";

float[,] twoD = new float[rows, cols];
twoD[2,0] = 4.5f;

int[][] jagged = new int[3][] {
    new int[5], new int[2], new int[3] }; 
jagged[0][4] = 5;

Java와 달리 C#에서는 배열을 나타내는 대괄호 []는 반드시 자료형 다음에 와야 한다.

배열의 초기화 시에도, Java와 달리 C#에서는 배열의 크기와 초기값의 수가 일치해야 한다.

C#에서는 Jagged 배열 외에 다차원 배열을 추가로 지원한다.

메서드

Java

// 값을 반환
int Add(int x, int y) { 
   return x + y; 
}

int sum = Add(2, 3);
// 결과값을 반환하지 않음
void PrintSum(int x, int y) { 
   System.out.println(x + y); 
}
PrintSum(2, 3); 

// 값에 의한 전달
void TestFunc(int x, Point p) {
   x++; 
   p.x++;       // 객체 값 변경
   p = null;    // 객체 참조를 제거 
}
class Point { 
   public int x, y; 
}
Point p = new Point(); 
p.x = 2; 
int a = 1; 
TestFunc(a, p);
System.out.println(a + " " + p.x + " " + (p == null) );  // 1 3 false 




// 임의의 갯수의 매개변수
int Sum(int ... nums) {
  int sum = 0;
  for (int i : nums)
    sum += i;
  return sum;
}
int total = Sum(4, 3, 2, 1);   // returns 10

C#

// 값을 반환
int Add(int x, int y) { 
   return x + y; 
}

int sum = Add(2, 3);
// 결과값을 반환하지 않음
void PrintSum(int x, int y) { 
   Console.WriteLine(x + y); 
}
PrintSum(2, 3); 

// 값에 의한 전달, ref, out
void TestFunc(int x, ref int y, out int z, Point p1, ref Point p2) { 
   x++;  y++;  z = 5; 
   p1.x++;       // 객체 값 변경     
   p1 = null;    // 객체 참조를 제거 
   p2 = null;   // 객체 참조를 제거 
}
class Point { 
   public int x, y; 
}
Point p1 = new Point(); 
Point p2 = new Point(); 
p1.x = 2; 
int a = 1, b = 1, c;   // out은 초기화 필요 없음
TestFunc(a, ref b, out c, p1, ref p2); 
Console.WriteLine("{0} {1} {2} {3} {4}", 
   a, b, c, p1.x, p2 == null);   // 1 2 5 3 True

// 임의의 갯수의 매개변수
int Sum(params int[] nums) {
  int sum = 0;
  foreach (int i in nums)
    sum += i;
  return sum;
}
int total = Sum(4, 3, 2, 1);   // returns 10

C#에서는 값 형식의 데이터를 참조 형식으로 매개변수를 전달하기 위해서 ref, out 키워드를 지원한다.

ref의 경우 사용하기 전에 반드시 초기화 되어 있어야 하고, out의 경우 메서드 내에서 사용하기 전에 값을 할당해야 한다.

임의의 갯수의 매개변수를 전달 받으려는 경우, Java는 ...을, C#은 params 키워드를 사용한다.

문자열

Java

// 결합
String school = "Harding "; 
school = school + "University";   // school is "Harding University"

// 비교
String mascot = "Bisons"; 
if (mascot == "Bisons")    // 틀려!
if (mascot.equals("Bisons"))   // true
if (mascot.equalsIgnoreCase("BISONS"))   // true
if (mascot.compareTo("Bisons") == 0)   // true
System.out.println(mascot.substring(2, 5));   // Prints "son"

// 날짜
java.util.Calendar c 
  = new java.util.GregorianCalendar(1973, 10, 12);
String s 
  = String.format("My birthday: %1$tb %1$te, %1$tY", c);

// 조작가능한 문자열 
StringBuffer buffer = new StringBuffer("two "); 
buffer.append("three "); 
buffer.insert(0, "one "); 
buffer.replace(4, 7, "TWO"); 
System.out.println(buffer);     // Prints "one TWO three"

String path = "\\\\FileShare\\Directory\\file.txt";

C#

// 결합
string school = "Harding "; 
school = school + "University";   // school is "Harding University"

// 비교
string mascot = "Bisons"; 
if (mascot == "Bisons")    // true
if (mascot.Equals("Bisons"))   // true
if (mascot.ToUpper().Equals("BISONS"))   // true
if (mascot.CompareTo("Bisons") == 0)    // true
Console.WriteLine(mascot.Substring(2, 3));    // Prints "son"

// 날짜
DateTime dt 
  = new DateTime(1973, 10, 12);
string s 
  = "My birthday: " + dt.ToString("MMM dd, yyyy");


// 조작가능한 문자열 
System.Text.StringBuilder buffer = new System.Text.StringBuilder("two "); 
buffer.Append("three "); 
buffer.Insert(0, "one "); 
buffer.Replace("two", "TWO"); 
Console.WriteLine(buffer);     // Prints "one TWO three"
string path = @"\\FileShare\Directory\file.txt";

문자열 비교시에, Java는 equals() 메서드를 사용하지만, C#에서는 == 또는 != 연산자를 사용할 수 있다.

C#에서는 변수에 할당되는 문자열 앞에 @을 붙여서 이스케잎 문자를 효율적으로 처리할 수 있다.

예외처리

Java

// 메서드에서 예외를 던질 수 있도록 선언되어야 함
Exception ex 
  = new Exception("Something is really wrong."); 
throw ex;  

try {
  y = 0; 
  x = 10 / y;
} catch (Exception ex) {
  System.out.println(ex.getMessage()); 
} finally {
  // Code that always gets executed
}

C#

Exception up 
  = new Exception("Something is really wrong."); 
throw up;  // ha ha

try {
  y = 0; 
  x = 10 / y;
} catch (Exception ex) { // 매개변수가 없어도 됨
  Console.WriteLine(ex.Message); 
} finally {
  // Code that always gets executed
}

C#의 catch 블록에서 매개변수를 생략할 수도 있다.

C#에서는 throws 키워드가 없다.

클래스 / 인터페이스

Java

접근 키워드
public
private
protected
static



// 상속
class FootballGame extends Competition {
  ...
}

// 인터페이스
interface IAlarmClock {
  ...
}

// 인터페이스의 상속
interface IAlarmClock extends IClock {
  ...
}

// 인터페이스 구현
class WristWatch implements IAlarmClock, ITimer {
   ...
}

C#

접근 키워드
public
private
internal
protected
protected internal
static

// 상속
class FootballGame : Competition {
  ...
}

// 인터페이스
interface IAlarmClock {
  ...
}

// 인터페이스의 상속
interface IAlarmClock : IClock {
  ...
}

// 인터페이스 구현
class WristWatch : IAlarmClock, ITimer {
   ...
}

Java의 기본 접근 제한자는 동일 패키지 내에서 접근 가능인 반면, C#에서는 private이다.

C#의 internal 키워드는 현재 어셈블리 내에서만 접근 가능하도록 지정하는 것이며, 어셈블리는 Java의 Jar파일과 유사한 개념이다.

Java에서 클래스가 더이상 상속 될 수 없도록 지정하는 final 키워드 대신, C#에서는 sealed 키워드를 사용한다.

Java에서 상속과 구현을 나타내는 키워드인 extends와 implements 대신, C#에서는 :을 사용한다.

Java의 super 키워드 대신, C#에서는 base 키워드를 사용한다.

Java와 달리, C#에서는 오버라이드 될 메서드에는 virtual 키워드를 오버라이드 하는 메서드에는 override 키워드를 사용한다.

C#에서는 인덱서를 지원하므로 이를 이용하면 클래스나 구조체를 배열처럼 다룰 수 있다.

객체

Java

SuperHero hero = new SuperHero();
hero.setName("SpamMan"); 
hero.setPowerLevel(3); 

hero.Defend("Laura Jones");
SuperHero.Rest();  // 정적 메서드 호출
SuperHero hero2 = hero;   // 동일한 객체를 참조

hero2.setName("WormWoman"); 
System.out.println(hero.getName()); 

hero = null;   // Free the object
if (hero == null)
  hero = new SuperHero();
Object obj = new SuperHero(); 
System.out.println("object's type: " + obj.getClass().toString()); 
if (obj instanceof SuperHero) 
  System.out.println("Is a SuperHero object.");

C#

SuperHero hero = new SuperHero(); 
hero.Name = "SpamMan"; 
hero.PowerLevel = 3;

hero.Defend("Laura Jones");
SuperHero.Rest();   // 정적 메서드 호출
SuperHero hero2 = hero;   // 동일한 객체를 참조
 
hero2.Name = "WormWoman"; 
Console.WriteLine(hero.Name);  

hero = null ;   // Free the object
if (hero == null)
  hero = new SuperHero();
Object obj = new SuperHero(); 
Console.WriteLine("object's type: " + obj.GetType().ToString()); 
if (obj is SuperHero) 
  Console.WriteLine("Is a SuperHero object.");

생성자 / 파괴자

Java

class SuperHero {
  private int mPowerLevel;

  public SuperHero() {
    mPowerLevel = 0;
  }

  public SuperHero(int powerLevel) {
    this.mPowerLevel= powerLevel;
  }

  // 파괴자는 없음
  protected void finalize() throws Throwable { 
    super.finalize();   // 항상 부모 요소를 호출
  }
}

C#

class SuperHero {
  private int mPowerLevel;

  public SuperHero() {
     mPowerLevel = 0;
  }

  public SuperHero(int powerLevel) {
    this.mPowerLevel= powerLevel; 
  }

  ~SuperHero() {
    // Destructor code to free unmanaged resources.
    // Implicitly creates a Finalize method.
  }
}

Java에서는 finalize() 메서드를 사용해서 가비지 컬렉터에 의해 인스턴스가 정리되기 직전에 실행될 메서드를 지정하는 반면, C#에서는 매개변수 없는 생성자와 유사한 형식으로 지정하며 이름 앞에 물결 표시(~)를 붙인다.

속성

Java

private int mSize;

public int getSize() { return mSize; } 
public void setSize(int value) {
  if (value < 0) 
    mSize = 0; 
  else 
    mSize = value; 
}


int s = shoe.getSize();
shoe.setSize(s+1);

C#

private int mSize;

public int Size { 
  get { return mSize; } 
  set { 
    if (value < 0) 
      mSize = 0; 
    else 
      mSize = value; 
  } 
}

shoe.Size++;

C#에서는 private 멤버 변수의 getter와 setter 메서드를 처리하는 get, set 키워드를 지원한다.

구조체

Java

x

C#

x

x

프로그램 구조

Java

 

C#

struct StudentRecord {
  public string name;
  public float gpa;

  public StudentRecord(string name, float gpa) {
    this.name = name;
    this.gpa = gpa;
  }
}

StudentRecord stu = new StudentRecord("Bob", 3.5f);
StudentRecord stu2 = stu;  

stu2.name = "Sue";
Console.WriteLine(stu.name);    // Prints "Bob"
Console.WriteLine(stu2.name);   // Prints "Sue"

C#에서는 클래스와 유사한 구조체라는 자료형을 지원한다. 단, 구조체는 상속이 불가능하고, 참조형 데이터가 아니다.

이벤트

Java

 

C#

window.ClickedEvent += MyEventHandler;

Java의 경우 이벤트를 수신할 클래스에서 Listener를 구현한 후 이벤트를 발생시키는 객체에 등록(register)하지만, C#에서 이벤트는 이벤트를 발생시키는 객체의 멤버이므로 이벤트 핸들러 메서드를 추가하기만 하면 된다.

C#에서는 이벤트 핸들러 메서드를 위해 delegate 키워드를 제공한다. 딜리게이트는 함수 포인터와 유사한 개념이다.

콘솔 입출력

Java

java.io.DataInput in 
= new java.io.DataInputStream(System.in);
System.out.print("What is your name? ");
String name = in.readLine();

System.out.print("How old are you? ");
int age = Integer.parseInt(in.readLine());
System.out.println(name + " is " + age + " years old.");
int c = System.in.read();   // Read single char
System.out.println(c);      // Prints 65 if user enters "A"

// The studio costs $499.00 for 3 months.
System.out.printf("The %s costs $%.2f for %d months.%n",

 

"studio", 499.0, 3); // Today is 06/25/04 System.out.printf("Today is %tD\n", new java.util.Date());

C#

Console.Write("What's your name? ");
string name = Console.ReadLine();



Console.Write("How old are you? ");
int age = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("{0} is {1} years old.", name, age);
// 또는
Console.WriteLine(name + " is " + age + " years old.");

 

int c = Console.Read(); // Read single char Console.WriteLine(c); // Prints 65 if user enters "A" // The studio costs $499.00 for 3 months. Console.WriteLine("The {0} costs {1:C} for {2} months.\n", 

"studio", 499.0, 3); // Today is 06/25/2004 Console.WriteLine("Today is"+ DateTime.Now.ToShortDateString());

파일 입출력

Java

import java.io.*;

// Character stream writing
FileWriter writer 
  = new FileWriter("c:\\myfile.txt");
writer.write("Out to file.\n");
writer.close();

// Character stream reading
FileReader reader 
  = new FileReader("c:\\myfile.txt");
BufferedReader br = new BufferedReader(reader);
String line = br.readLine(); 
while (line != null) {
  System.out.println(line); 
  line = br.readLine(); 
} 
reader.close();

// Binary stream writing
FileOutputStream out 
  = new FileOutputStream("c:\\myfile.dat");
out.write("Text data".getBytes());
out.write(123);
out.close();

// Binary stream reading
FileInputStream in 
  = new FileInputStream("c:\\myfile.dat");
byte buff[] = new byte[9];
in.read(buff, 0, 9);   // Read first 9 bytes into buff
String s = new String(buff);
int num = in.read();   // Next is 123
in.close();

C#

using System.IO;

// Character stream writing
StreamWriter writer 
  = File.CreateText("c:\\myfile.txt"); 
writer.WriteLine("Out to file."); 
writer.Close();

// Character stream reading
StreamReader reader 
  = File.OpenText("c:\\myfile.txt"); 
string line = reader.ReadLine(); 
while (line != null) {
  Console.WriteLine(line); 
  line = reader.ReadLine(); 
} 
reader.Close();



// Binary stream writing
BinaryWriter out 
  = new BinaryWriter(File.OpenWrite("c:\\myfile.dat")); 
out.Write("Text data"); 
out.Write(123); 
out.Close();

// Binary stream reading
BinaryReader in 
  = new BinaryReader(File.OpenRead("c:\\myfile.dat")); 
string s = in.ReadString(); 
int num = in.ReadInt32(); 
in.Close();

C#에는 이 외에 인덱서, unsafe, fixed 등이 더 있음.


출처: http://www.elex.pe.kr/entry/Java-cf-C-Sharp [Elex]

OOPreport.txt

 

OOP (Object-oriented programming,객체지향프로그래밍)

  

프로그래밍 방법론으로 클래스,자료 추상화,상속,다형성,캡슐화등을 이용하여 프현실세계를 시스템을 독립적 객체들의 집합으로 모델링 하는것이다. 다른 방법론들 또한 현실세계를 모델링 하므로 OOP의 고유특성은 아니나 사물과 그 행위을 하나로 묶고 객체간의 메시지를 기본 모형으로 하기때문에 각 객체가 종속 될 필요가 없고 객체지향프로그래밍의 장점으로 나타난다. 이 장점 때문인지 현재 프로그래밍 방법론 중 가장 많이 쓰이고 있다.

객체지향프로그래밍의 장점으로는 시스템의 복잡성을 낮추며 코드의 재사용성 증가, 유지보수 감소등을 들수있다.

 

 

Objcet, 객체

현실세계의 존재하는 모든 것을 말하며 예를 들어 사람,동물,교실 처럼 실체하는 것부터 거래,계좌,수학 같은 개념적인 것을 모두 포함한다. 객체는 식별성, 상태(state), 행위(behavior)의 특성을 같는다. 현실의 객체는 무한에 가까운 특성을 가지고 있기때문에 이를 모델링 하기 위해서는 시스템에 필요한 요소만을 분류/집합 해야만 한다. 

객체지향프로그래밍이라는 이름에서 알 수 있듯이 OOP에서 중요한 개념이다.

 

Class, 클래스

 

모든 객체는 클래스를 통해 정의 될 수있다. 클래스는 여러객체들의 공통적인 상태와 행동을 가지고 있는데 이 과정을 추상화라고 한다. 클래스가 정의 된 후 객체가 정의되는데 이렇게 한 클래스에 속한 각가의 객체를 그 클래스의 인스턴스(instance)라고 한며, 그 객체들의 유형이 되는 클래스를 객체의 타입(Object Type)이라고 한다.

 

 

Abstraction, 추상화

현실세계의 객체의 일반적인 특징을 표현하기에는 너무많은 특징을 가지고 있다. 때문에 모델링하고자 하는 시스템에 필요한 정보를 집중, 분류하며 상세내역을 없애가는 과정을 추상화라고 한다. 시스템에 따라 필요정보가 다르기때문에 시스템에 의존적이게 된다.

 

Generalization, 일반화 / Inheritance, 상속

'남자와 여자는 사람이고 사람과 강아지는 동물이다' 처럼 클래스의 공통 된 특징을 추출하여 상위 클래스로 추상화 되는데 일반화란 이처럼 추상적으로 상위 클래스로 향함을 말한다. 

상속이란 일종의 일반화이다.

상속은 일반화한 상위클래스를 이용하여 공통 된 특징이외 고유의 특징을 추가하여 하위 클래스를 만들게되면 이 둘의 관계를 상속관계라고 한다.

상속을 통하여 기존의 클래스로부터 추가적 특성을 추가하는 것 만으로 하위클래스를 정의 할 수있기때문에 반복을 막아주고 재사용성이 늘어나게된다.

Java에서 extends 키워드를 통한 상속을 지원하고 상위 클래스를 공유하는 의미를 지닌다.

 

Specialization, 구체화

일반화와는 반대로 상속을 통해 클래스의 추상 수준을 낮추어 나가는 과정을 구체화라 한다. 

일반화와 구체화는 클래스간의 is-a 관계를 나타낸다.

 

Realization

추상화 과정을 거쳐 만들어진 클래스를 하나의 객체로 만드는 것을 말하다.

이때 만들어진 객체를 클래스의 인스턴스라고 한다.

예를 들면 사람이라는 클래스로부터 홍길동이라는 인스턴스가 나타난것이다.

Java에서 완전한 추상클래스를 지원하기 위해 interface를 제공한다. 

implements로 사용 할 수있으며 상속과 마찬가지고 is-a관계를 갖고 있지만 상속은 공유의 의미를 가지고 인터페이스는 구현의 의미를 가진다.


Association (소유)

객체간의 참조관계를 나타낸다. 

예를 들면 자동차의 구성으로 사람이라는 객체의 구성으로 팔,다리,머리들이 있고 머리는 눈,코,입을 가지고있듯이 객체간의 has-a 관계를 나타낸다.

 

Dependency, 종속성 (사용)

A라는 클래스가 B라는 클래스 또는 인터페이스를 사용할때 마다 A는 B에 의존하게 된다. 이때 A가 B에 종속되어있다고 할 수있으며 이는 종속에는 방향성이 있기에 A가 B에 종속된다해소 B가A에 종속되었다고 볼수는 없다.

A는 B 없이는 사용 될 수없고 이때문에 재사용을 어렵게 할 수있기때문에 개발에 부정적인 영향을 끼칠 수 있다.

이에 관련 Dependency Inversion Principle(DIP, 의존성 역전 원칙)

"상위 레벨의 모듈은 하위 레벨들에 의존해선 안되며, 모든 것들은 추상에 의존해야 한다"는 중요개념이 있다.


Polymorphism, 다형성

객체지향 개념에서의 다형성이란 '여러 가지 형태를 가질 수 있는 능력'을 의미하며 구현과정에서는 같은 상위클래스를 상속받아 동일한 메소드를 가지고있는 클래스들을 공통으로 상속받고있는 클래스 타입으로 참조하여 실제 구현내용은 다르지만 같은 타입으로 참조하기때문에 코드의 유지보수와 확장성에 유리하게 작용한다.



Encapuslation / 절차은닉 / 정보은닉

객체지향에서 캡슐화는 상태와 행위을 하나로 묶고 정보의 처리와 접근을 모두 클래스 내부에서 하도록 하는것이다. 

외부와의 상호작용은 메소드 호출로만 이루어지기때문에 외부로터 필드로 무분별한 접근을 막을 수있고 내부 내용의 변경이 외부에 영향을 끼치지않는다. 이로인하여 유지보수와 재상용성이 늘어나고 필드의 값이 손상 될 가능성또한 낮출수있다.

Access Modifier(접근 제한자)

정보를 은닉하기위해 프로그래밍언어에서는 Access Modifier(접근제한자)를 지원한다.

Java

public : 어디서나 접근가능

protected : 같은 패키지, 상속받은 클래스에서 접근가능

default : 같은 패키지에서만 접근가능

private : 외부접근 불가능



+ Recent posts