의식의 흐름대로 정리

Java는 네트워크 상에서 쓸 수 있도록 미국의 썬 마이크로 시스템즈가 개발한 객체 지향 프로그래밍 언어

 

Java의 특징

  1. 자바가상머신(JVM)만 설치하면 컴퓨터의 운영체제(OS)에 상관없이 작동하기 때문에 운영체제에 독립적이다.
    - JVM(Java Virtual Machine) : 컴파일된 자바 바이트 코드를 실행시켜주는 소프트웨어

  2. 객체 지향 프로그래밍 언어이다. > 캡슐화, 상속, 다형성의 특징을 갖는다. > 코드의 재사용 및 유지보수에 용이하다.
    - 객체 지향 프로그래밍(OOP; Object-Oriented Programming) : 데이터를 객체로 취급하여 프로그램에 반영한 것으로, 기존의 절차 지향 프로그래밍과 다르게 객체의 상호작용을 통해 프로그램이 동작한다.
    - 객체 지향 프로그래밍과 절차 지향 프로그래밍 차이 : 절차 지향 프로그래밍은 순차적인 처리가 중요하며, 대표적으로는 C언어가 있다. 컴퓨터의 처리 방식과 유사하기 때문에 객체 지향 언어보다 처리 속도가 더 빠르다. 하지만 실행 순서가 정해져 있어 코드의 순서가 바뀌면 동일한 결과를 보장하기 어려워 유지보수가 어렵다. 또 디버깅이 어렵다. 객체 지향 프로그래밍은 코드의 재활용성이 높고 절차지향보다 코딩이 간편하다. 디버깅이 쉽다. 반면에 처리속도는 절차 지향 언어보다 느리며, 설계에 많은 시간이 소요된다. 절차 지향 언어는 실행 순서, 절차가 더 중점이고 객체 지향 언어는 필요한 객체들의 종류와 속성 등에 더 중점을 두고 프로그래밍 된다. 즉, 절차 지향과 객체 지향은 서로 프로그래밍 되는 방식이 다를 뿐, 반대되는 성질이 아니다.
    - 캡슐화 : 관련된 데이터와 메서드를 하나의 단위로 묶어 정보를 은닉하는 것(외부 객체에서 구현 방식은 알 수 없다). 클래스 필드 값에 권한을 설정할 수 있다(public, private, protected, default). getter/setter를 통해 접근하도록 가능하다.
    - public : 접근 제한 없음
    - private : 같은 클래스에서만 사용 가능(접근 권한이 가장 적음)
    - public > protected > default > private
    - 상속 : 부모 클래스에 자식이 접근할 수 있도록 물려받는 방식
    - 다형성 : 부모 타입의 참조 변수로 자식 타입의 객체를 다루는 것. 오버로딩과 오버라이딩이 있다.
    - 오버로딩 : 상속이 아닌 하나의 클래스 내에서 이름이 같은 여러 개의 메서드를 정의하는 것. 매개변수의 수, 배치(순서), 타입이 달라야 한다.
    - 오버라이딩 : 부모에게서 상속받은 것들을 새롭게 재정의 하는 것을 뜻함. 재정의 한 것은 자신의 클래스 내부에서만 영향을 끼치며 부모에게는 영향을 끼치지 않는다.

  3. Garbage Collector를 통해 자동적으로 메모리를 관리한다.
    - 시스템에서 더 이상 사용하지 않는 동적 할당된 메모리 블럭을 찾아 자동으로 다시 사용 가능한 자원으로 회수하는 것을 Garbage Collection이라고 하고, Garbage Collection을 수행하는 부분을 Garbage Collector라고 부른다.
    - 자바 메모리는 Method Area, Heap, Stack, PC Register, Native Method Stack 영역으로 나눈다.
    - Method Area는 JVM이 실행되면서 생기는 공간으로 모든 스레드가 공유하는 영역이다.
    - 런타임 상수풀(runtime constant pool), 필드(field) 데이터, 메소드(Method) 데이터 등을 분류하고 저장한다.
    - Heap 영역은 객체와 배열이 생성되는 영역이며, 힙 영역에 생성된 객체와 배열은 Stack 영역의 변수나 다른 객체의 필드에서 참조
    - 참조하는 변수나 필드가 없는 의미없는 객체는 Garbage Collector가 자동으로 제거한다.
    - 그래서 개발자는 객체를 제거하기 위한 별도의 코드를 작성할 필요가 없다.
    - Stack 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당된다.
    - 메소드를 호출할 때마다 push 되고 메소드가 종료되면 제거(pop)된다. Last In First Out 방식이다.
    - PC Register는 스레드가 생성되면서 생기는 공간으로, 스레드가 처리하고 있는 명령어의 주소를 등록한다.
    - JVM이 실행하고 있는 현재 위치를 저장하는 역할
    - Native Method Stack은 Java가 아닌 다른 언어(C, C++)로 구성된 메소드 실행이 필요할 때 사용되는 공간이다.

  4. Multi thread를 지원
    - thread는 한 process 내에서 실행되는 동작(기능 function)의 단위
    - 각 thread는 속해 있는 process의 스택 메모리를 제외한 나머지 메모리 영역을 공유할 수 있다.
    - multi thread는 하나의 process가 동시에 여러 개의 일을 수행할 수 있도록 해주는 것.
    - 즉, 하나의 process에서 여러 작업을 병렬로 처리하기 위해 multi thread를 사용한다.
    - process는 프로그램이 메모리에 적재되어 CPU를 할당받아 실행되는 것
    - 예를 들어 유튜브를 실행하면 한 개의 프로세스가 실행되는 것.
    - 2개 이상의 process가 동시에 실행되면 multi process라고 한다.
    - cpu core가 1개라면 여러 프로세스를 짧은 시간 동안 번갈아 연산을 하는 동시성을 갖는다.
    - cpu core가 여러 개 라면 각각의 core가 각각의 process를 연산하는 병렬성을 갖는다.
    - multi process와 multi thread는 동시에 여러 작업을 수행한다는 측면에서 유사한 면이 있다.
    - 적용할 시스템에 따라 두 방법의 장단점을 고려하여 적합한 방식을 선택해야 한다.
    - multi thread는 multi process보다 적은 메모리공간을 차지하고 Context Switching이 빠르다.
    - 컴퓨터는 다양한 업무를 처리하기 위해 task를 번갈아 가며 실행하는데, 이 때 현재 진행하고 있는 task(process, thread)를 저장하고 다음 실행할 task의 상태를 읽어 적용하는 과정을 Context Switching이라고 한다.
    - multi process는 multi thread보다 많은 메모리 공간과 CPU 시간을 차지한다.
    - multi thread는 동기화 문제나 하나의 thread 장애로 전체 thread가 종료될 위험이 있다.
    - 동기화 문제란, 서로 다른 thread가 메모리 영역을 공유하기 때문에(자원을 공유하기 때문에) 여러 thread가 동일한 자원에 동시에 접근하여 엉뚱한 값을 읽거나 수정하는 문제이다.
    - multi process는 하나의 process가 죽더라도 다른 process에 영향을 주지 않아 안정성이 높다.
    - 메모리 구분이 필요할 때는 multi process가 유리하고, Context switching이 자주 일어나고 데이터 공유가 빈번한 경우, 자원을 효율적으로 사용해야 하는 경우에는 multi thread가 유리하다.


 

 

한 줄 정리

Java는 객체지향 프로그래밍 언어로써 캡슐화, 다형성, 상속의 특징을 갖습니다. 또 JVM(자바 가상 머신) 위에서 실행이 되기 때문에 운영체제에 독립적입니다.

 

객체지향 프로그래밍(OOP; Object-Oriented Programming)은 데이터를 객체로 취급하여 프로그램에 반영한 것으로, 기존의 절차지향 프로그래밍과 다르게 객체의 상호작용을 통해 프로그램이 동작합니다.

 

절차지향 프로그래밍은 순차적인 처리가 중요하며 대표적으로는 C언어가 있습니다. 컴퓨터의 처리 방식과 유사하기 때문에 객체지향보다 처리 속도가 빠릅니다. 하지만 실행 순서가 정해져 있어 코드의 순서가 바뀌면 동일한 결과를 보장하기 어렵고, 따라서 유지보수가 어렵습니다.
객체지향 프로그래밍은 코드의 재활용성이 높고, 절차지향보다 코딩이 간편합니다. 반면에 처리속도는 절차지향보다 느리며, 설계에 많은 시간이 소요됩니다.
절차지향은 실행 순서, 절차가 더 중점이고 객체 지향 언어는 필요한 객체들의 종류와 속성 등에 더 중점을 두고 프로그래밍을 합니다. 즉, 절차지향과 객체지향은 서로 프로그래밍 되는 방식이 다를 뿐, 반대되는 성질은 아닙니다.

 

캡슐화는 변수와 함수를 하나의 클래스로 묶어 정보를 은닉화하는 것으로, 외부객체에서 구현 방식을 알 수 없습니다. 접근 권한을 설정할 수 있으며, getter/setter를 통해 접근할 수 있습니다.

 

접근 권한에는 권한 순으로 public, protected, default, private이 있고, 접근 제한이 없는 public과 같은 클래스 내에서만 사용 가능하여 접근 권한이 가장 적은 private가 주로 쓰입니다.

 

다형성은 부모 타입의 참조 변수로 자식 타입의 객체를 다루는 것을 뜻합니다. 오버로딩과 오버라이딩 등이 있습니다.

 

오버로딩은 하나의 클래스 내에서 같은 이름의 메소드를 여러 개 정의하는 것으로, 매개 변수의 개수나 변수 타입이 달라야 합니다.

 

오버라이딩은 부모 클래스에서 상속 받은 것들을 재정의하는 것입니다. 재정의된 메서드는 같은 클래스 내에서만 영향을 끼치며, 부모에게는 영향을 주지 않습니다.

 

상속은 부모 클래스에 자식이 접근할 수 있도록 물려받는 것입니다. 기존 클래스의 기능을 유지하면서 추가적인 기능을 추가하여 클래스를 만들고 싶을 때 사용합니다. 상속은 코드를 간결화하며, 재사용성을 높일 수 있습니다.

 

JVM(Java Virtual Marchine)은 컴파일된 소스 코드를 실행시켜주는 소프트웨어입니다. JVM이 있어 운영체제에 상관없이 자바를 실행할 수 있습니다. JRE(Java Runtime Environment)는 자바 실행환경으로, 라이브러리 등 개발 되어있는 것을 실행합니다. JDK(Java Development Kit)는 개발을 위해 필요한 도구들을 포함하고 있어 개발 및 실행이 가능합니다.

 

자바의 메모리 영역은 Method Area, Heap, Stack, PC Register, Native Method Stack으로 나뉩니다.

 

Method Area는 JVM이 실행되면서 생기는 공간으로 모든 스레드가 공유하는 영역으로, 컴파일되어 들어온 코드를 분류하여 저장합니다.

 

Heap 영역에서는 Stack 영역의 변수나 다른 객체의 필드에서 참조하는 객체와 배열이 생성됩니다. 더 이상 참조하지 않게 되는 의미없는 객체는 Garbage Collector에 의해 제거됩니다. 

 

Stack 영역은 각 스레드마다 하나씩 존재하며 스레드가 시작될 때 할당됩니다. 메소드를 호출할 때마다 push되고 종료되면 마지막 메소드부터 제거(pop)됩니다(Last In First Out)

 

스레드(thread)는 한 프로세스(process) 내에서 실행되는 동작의 단위이고, 프로세스는 CPU를 할당받아 실행되는 프로그램을 뜻합니다. 예를 들어 유튜브를 키면, 한 개의 프로세스가 실행되는 것입니다.

 

PC Register는 스레드가 생성되면서 생기는 공간으로, JVM이 실행되고 있는 현재 위치를 저장하는 역할을 합니다.

 

Native Method Stack은 자바 외의 언어로 구성된 메소드 실행이 필요할 때 사용되는 공간입니다.

 

자바는 멀티 스레드를 지원합니다. 멀티 스레드란, 하나의 프로세스에서 여러 개의 작업을 병렬로 처리하는 것을 말합니다.

 

프로세스도 두 개 이상의 프로세스가 동시에 작동할 때 멀티 프로세스라고 합니다. CPU core를 한 개만 사용할 때는 여러 프로세스를 짧은 시간 동안 번갈아 연산하는 동시성을 갖습니다. CPU core가 여러 개라면, 각각의 코어가 각각의 프로세스를 연산하는 병렬성을 갖습니다.

 

멀티 스레드와 멀티 프로세스는 동시에 여러 작업을 한다는 측면에서 유사하지만, 장단점이 다릅니다.
멀티 스레드는 멀티 프로세스보다 적은 메모리 공간을 차지하고, Context Switching이 빠릅니다. 반면 멀티 프로세스는 멀티 스레드보다 많은 메모리 공간과 CPU 시간을 차지합니다.
멀티 스레드는 동기화 문제나 하나의 스레드 장애로 전체 스레드가 종료될 위험이 있지만, 멀티 프로세스는 하나의 프로세스가 죽더라도 다른 프로세스에 영향을 주지 않아 안정성이 높습니다.

 

메모리 구분이 필요할 때는 멀티 프로세스가 유리하고, Context switching이 자주 일어나고 데이터 공유가 빈번한 경우, 자원을 효율적으로 사용해야 하는 경우에는 멀티 스레드가 유리합니다.

 

Context switching은 컴퓨터가 task를 번갈아 가며 실행할 때, 현재 진행하고 있는 task를 저장하고 다음 실행할 task의 상태를 읽어 적용하는 과정입니다.

 

동기화 문제란, 서로 다른 스레드가 메모리 영역(자원)을 공유하기 때문에, 동일한 자원에 동시에 접근하여 엉뚱한 값을 읽거나 수정하는 문제 입니다.

 

728x90

'이론 > CS공부' 카테고리의 다른 글

컬렉션 프레임워크  (0) 2022.11.02
추상화  (0) 2022.11.02
MVC패턴  (0) 2022.11.02
Cookie vs Session  (0) 2022.10.31
Servlet vs JSP  (0) 2022.10.27
1. String Class

문자열에서 정보를 추출하기 위한 String 클래스의 기본 기능

 

▶ 다양한 기능들

 


 

▶ 활용방법들

방법 1
방법2 - 달거북씨 풀이
방법2 - 강사님 풀이
방법3
방법4
방법5

 

 

 

2. 정규표현식

2-1. 정규표현식이란?

  • 정규표현식(Regular expression)은 특정한 규칙을 가진 문자열의 집합을 표현하는데 사용하는 '형식언어'이다.
  • 정규표현식은 많은 텍스트 편집기와 프로그래밍 언어에서 '문자열의 검색과 치환'을 위해 지원하고 있다.
  • java.util.regex 패키지에 포함되어 있다.

 

2-2. 정규표현식의 사용

  • boolean java.util.regex.Pattern.matches(String arg0, charSequence arg1);
  • arg0 : 정규표현식 문자열이다.
  • arg1 : 형식을 검사받기 위한 내용이다.
  • 즉, 위의 기능은 arg1이 arg0의 형식에 맞는지를 검사하고 결과를 boolean으로 리턴한다.

 

2-3. 정규표현식 종류

  • 숫자 모양에 대한 형식 검사
    "^[0-9]*$"

  • 영문으로만 구성되었는지에 대한 형식 검사
    "^[a-zA-Z]*$"

  • 한글로만 구성되었는지에 대한 형식 검사
    "^[ㄱ-ㅎ가-힣]*$"

  • 영문과 숫자로만 구성되었는지에 대한 형식 검사
    "^[a-zA-Z0-9]*$"

  • 한글과 숫자로만 구성되었는지에 대한 형식 검사
    "^[ㄱ-ㅎ가-힣0-9]*$"

  • 이메일 형식인지에 대한 검사. "아이디@도메인"의 형식을 충족해야 한다.
    "^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$"

  • "-"없이 핸드폰번호인지에 대한 형식검사.
    "^01(?:0|1|[6-9])(?:\\d{3}|\\d{4})\\d{4}$"

  • "-"없이 전화번호인지에 대한 형식검사. 각 부분에 대한 자리수도 충족시켜야 한다.
    "^\\d{2,3}\\d{3,4}\\d{4}$"

  • "-"없이 주민번호에 대한 글자수 및 뒷자리 첫글자가 1~4의 범위에 있는지에 대한 검사
    "^\\d{6}[1-4]\\d{6}"
  • 강사님이 추천해주신 블로그
    https://hamait.tistory.com/342
 

정규표현식 (Regex) 정리

정규표현식은 아주 가끔 쓰기때문에 항상 다시 볼때마다 헷갈리곤 하는데.. 주요 사용예를 정리하여 보았다. 나중에 찾아보기 편하라고~ 정규 표현식의 용어들정규 표현식에서 사용되는 기호를

hamait.tistory.com

 

▶ Pattern.matches()를 사용해 정규표현식이 맞게 사용되었는지 비교(import 필요)

▶ Pattern.matches() 안의 정규표현식과 맞지 않으면 if문 안으로 들어간다.

if문마다 return;을 사용하는 이유는 해당 결과를 보고 다음 if문으로 넘어가지 않고 종료시키기 위해 사용한다.

 


 

▶ 싱글톤 객체 생성해서 사용하기

▶ isValue로 값이 공백 또는 null인지 체크

▶ 문제를 풀 때 문자열 안의 공백을 찾으라는 줄 알고,

    boolean isValue = Pattern.matches("^[\\S]*$", str);

    이렇게 풀었으나, 아니었다. 띠로리-!

▶ isValue로 체크 후 공백이나 null이 아니면 나머지 과정을 수행하도록 로직을 짠다.

 

 


 

 

 

728x90

정리 얼른 끝내고 프로젝트 다시 하고 싶댜...

오늘 포스팅 앞부분은 약간 개념잡는 느낌?

 


 

1. ClassPath

컴파일이 완료된 *.class 파일들이 위치하는 경로

 


2. 라이브러리
  • 한 개 이상의 패키지들을 배포하기 용이하도록 압축한 형태
  • 다른 프로그램에서 라이브러리 안에 포함된 기능을 활용할 수 있다.
  • *.jar

 

3. JAVA의 기본 API들

우리가 사용하는 JDK 안에는 이미 수많은 라이브러리가 포함되어 있고, 이 라이브러리 안에는 프로그램 개발에 필요한 패키지들이 기본적으로 포함되어 있다.

자바 프로그래밍은 이러한 라이브러리들의 기능을 활용하여 이루어진다.

이렇게 프로그램 개발을 위하여 기본적으로 제공되는 기능들을 API라고 한다.

 

▶ API는 일종의 설명서다. 다운 받아도 되고 아래 오라클 사이트에서 검색해도 된다. 

https://docs.oracle.com/javase/8/docs/api/index.html

 

Java Platform SE 8

 

docs.oracle.com

 

4. Wrapper Class
  • Java는 데이터를 관리하기 위하여 기본 데이터 타입을 지원하지만, 클래스를 통해서 만들어진 객체를 통한 데이터 관리도 가능하다.
  • 어떤 상황에서는 기본 데이터 타입의 변수를 객체 형태로 사용해야 하는 경우가 있는데, 이 때 기본형 타입을 객체로 포장할 필요가 있다.
  • 포장 클래스(Wrapper Class)는 특정 기본형 타입을 나타내는 용도로 사용된다.

 

4-1. Wrapper Class 의미

  • 초창기 java 언어는 기본 자료형의 연산보다도 Wrapper 클래스를 사용한 연산이 더 많이 이루어졌으나, Java 언어가 발전함에 따라서 기본 자료형과 Wrapper 클래스 간의 연산의 차이가 없어졌다.
  • 최근의 java 언어는 Wrapper 클래스와 기본 자료형을 구분하지 않고 사용하기 때문에 객체로서의 특별한 의미가 없어졌다고 볼 수 있다.

 

4-2. Wrapper Class의 객체 만들기각각의 Wrapper 클래스의 객체는 자신과 대응되는 기본 자료형의 데이터를 파라미터로 전달받는다.

int num = 1;
Integer wrapper = new Integer(num);

 

4-3. Wrapper Class의 형변환

기본 자료형과 Wrapper 클래스 간에는 서로 암묵적 형변환이 가능하다.

int num = 100;
Integer wrapper = num;
// --------------------------------
Integer wrapper2 = new Integer(200);
int num = wrapper2;

 

5-4. Wrapper Class의 static 데이터

모든 Wrapper 클래스는 static 데이터 형태로 Wrapper 클래스에 대응되는 자료형에 대한 최소값과 최대값을 가지고 있다.

int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;

 

5-5. 문자열 데이터의 형변환★

  • 1과 "1"의 차이
    → 기본 자료형과 문자열 데이터 간의 연산에서는 기본 자료형 데이터가 문자열로 변환된 후, 문자열 간의 연산으로 처리된다.
int a = 1;
String b = "1";
System.out.println(a+b);	// "11"이 출력됨
  • 사용자 입력값에 대한 연산
    → 모든 프로그램 플랫폼에서 사용자의 입력값은 String으로 처리된다.
    → 만약, 인터넷 뱅킹에서 2개의 계좌로 송금할 금액을 각각 입력하였을 때, 총 금액을 계산한다면 다음과 같이 처리될 것이다.
String money1 = "5000"
String money2 = "3000"

String total = money1 + money2;	// 50003000
				// 이렇게 하면 금액을 계산할 수 없으므로 Wrapper Class를 사용한다.
  • 문자열 데이터를 기본 데이터형으로 변환하기(★★★이렇게 많이 쓰임)
    → Wrapper 클래스에는 기본 자료형의 모양을 띄고 있는 문자열 데이터를 실제 기본 자료형으로 변환시키는 기능이 포함되어 있다.
    → Java에서 Wrapper 클래스의 가장 큰 의미는 바로 이 부분이라고 할 수 있다.
String money1 = "5000";
String money2 = "3000";

int m1 = Integer.parseInt(money1);
int m2 = Integer.parseInt(money2);

System.out.println(m1 + m2);	// 8000

 

 

 

 

6. Math Class

6-1. 수학적인 연산을 지원하는 클래스

  • Math 클래스는 흔히 계산을 하는데 도움이 되는 많은 수의 기본적인 수학 함수들을 제공한다.
  • Math 클래스는 java 표준 라이브러리의 java.lang 패키지에 정의되어 있다.
  • Math 클래스의 모든 메서드들은 static 메서드로, 클래스 객체를 생성하지 않고 그 메서드가 정의된 클래스 이름을 통해서 호출될 수 있다.

 

▶ Math Class의 다양한 메서드 사용 예시

 


 

▶ Math.random() 싱글톤으로 만들기

728x90
1. 디자인패턴(Design Pattern)

1-1. 디자인 패턴이란?

  • 디자인 패턴이란 기존 환경 내에서 반복적으로 일어나는 문제들을 어떻게 풀어나갈 것인가에 대한 일종의 솔루션 같은 것이다.
  • 디자인 패턴은 설계자들이 "올바른" 설계를 "빨리" 만들 수 있도록 도와준다.

 

1-2. SingleTone 패턴

  • 프로그램 내의 여러 곳에서 반복적으로 사용되어야 하는 객체에 대해 전역적인 범위를 갖도록 객체를 생성하고, 이 객체를 여러 곳에서 공유하기 위한 클래스 작성 패턴
  • 이러한 패턴을 통해 생성된 객체를 싱글톤 객체라고 한다.

 

1-3. SingleTone 객체의 이점

  • 프로그램의 전역에서 활용할 재료로 사용되는 공유 기능을 하나만 생성하여 여러 곳에서 재사용함으로 해서 메모리를 효율적으로 사용할 수 있다.
  • 단 한 번만 객체를 생성하면 다시 객체를 생성할 필요가 없기 때문에, 해당 기능을 사용할 때마다 객체를 일일이 생성해야 하는 번거로움을 피할 수 있다.

 

1-4. 공통 기능을 포함할 클래스 안에서 스스로의 객체를 static으로 선언

  • static이 적용된 자원은 메모리의 고정영역에 생성되기 때문에, 클래스 자체의 객체나, 그 안에 포함된 멤버변수, 메서드와는 메모리 상에서 구별된다고 볼 수 있다.
  • 그러므로 Calc 클래스 안에 static 형태로 Calc 클래스의 객체를 정의하더라도 코드상의 논리적인 연관관계를 위해 하나의 파일에서 정의하는 것일 뿐, 실제로는 Calc 클래스 자체에서 독립된 객체가 되는 것이다.
    public class Calc{
    	static Calc current;
    }
  • Calc 클래스 이외의 여러 곳에서 new 연산자를 사용하여 객체 할당이 가능하다면 SingleTon이라는 개념 자체가 성립되지 않으므로, 외부에서 이 객체에 직접적인 접근을 못하도록 은닉시킨다.
    public class Calc{
    	private static Calc current;
    }

 

1-5. 은닉된 객체를 할당하거나 메모리에서 삭제하는 기능 추가

  • current 객체를 private로 지정하였기 대문에 객체를 메모리에서 간접적으로 할당하고 삭제하기 위한 메서드가 필요하다.
  • 객체를 메모리에서 제어하기 위해서는 null을 사용한다.
public class Calc {
	// 내 자신에 대한 객체 선언
	private static Calc current;	// Private static Calc current = new Calc();로도 사용 가능

	public static Calc getInstance() {
		// 객체 할당 처리
		// 객체가 할당되지 않은 경우에만 할당하도록 하여 중복할당을 방지
		if(current == null) {
			current = new Calc();
		}
		return current;
	}
	
	public static void freeInstance() {
		current = null;	// 객체에 null을 대입하면 메모리에서 삭제된다.
	}
}

 

1-6. new 연산자를 사용한 객체 할당 금지하기

기본 생성자를 private 형대로 정의하면 객체 생성자가 은닉 처리되어 외부에서 new 연산자를 사용한 객체 할당이 금지된다.

public class Calc {
	// 내 자신에 대한 객체 선언
	private static Calc current;	// Private static Calc current = new Calc();로도 사용 가능

	public static Calc getInstance() {
		// 객체 할당 처리
		// 객체가 할당되지 않은 경우에만 할당하도록 하여 중복할당을 방지
		if(current == null) {
			current = new Calc();
		}
		return current;
	}
	
	public static void freeInstance() {
		current = null;	// 객체에 null을 대입하면 메모리에서 삭제된다.
	}
    
	private Calc(){
    		super();
    	}
}

 


 

계산 기능 싱글톤 생성
싱글톤 객체 사용

 


 

2. 패키지(Package)

2-1. Java Package

    • 패키지 : 클래스에 대한 묶음 단위
    • 클래스를 용도별이나, 기능별로 그룹화 한 것을 말한다. 소스 코드는 폴더로 분류된 형태로 존재하게 된다.
    • 패키지 이름의 일반적인 정의 형식
      회사 도메인 이름의 역순, 프로젝트 이름의 소문자

      → com.koreait.shop.user
      → com.koreait.shop.article
  • 서로 다른 패키지에 속해 있다면 다른 클래스와 이름이 동일하더라도 충돌이 발생하지 않는다.(서로 다른 폴더에는 이름이 같은 파일들이 존재할 수 있다)
  • 패키지에 소속된 클래스 파일은 첫번째 라인에서 자신이 소속된 클래스 패키지 이름을 선언해야 한다.
  • 이클립스가 왼쪽의 트리 영역에서 소스를 분류하는 작업을 통해 구문을 자동으로 추가해주지만, 간혹 처리되지 않을 때도 있으므로 패키지 구문에서 에러가 발생할 경우, 소스가 어떤 패키지에 있는지 확인하여 직접 이 구문을 수정해주어야 한다.
    저번 시간 Article 복사해와서 활용
    패키지에 속해 있는 클래스에 대한 객체 생성 방법
728x90
1. 추상화

1-1. 상속성과 다형성의 필요성

  • 상속성은 객체 간의 공통적인 기능을 관리하기 위한 비법으로, 코드의 재사용을 통하여 프로그램 유지보수를 편리하게 한다.
  • 다형성(Override, Overeload)은 서로 다른 기능이지만 메서드의 이름을 공통되게 처리함으로써 전체 프로그램에 일관성을 유지하게 한다.

 

1-2. Override 처리의 문제 발생 가능성

  • '@Override' 키워드를 사용하지 않고 메서드를 재정의하는 과정에서 메서드 이름에 실수가 있을 경우, 에러가 아닌 새로운 메서드의 정의로 인식되어 의도하지 않은 실행결과를 가져올 수 있다.
  • '@Override' 키워드를 사용하더라도 자식 클래스를 구현하는 개발자의 실수로 인하여 부모의 기능을 재정의하지 않았다면 다형성의 구현은 이루어지지 않게 된다.

 

1-3. 상속 처리시, Override를 강제하기

  • 추상화 기법은 특정 클래스를 상속받은 경우, 부모의 특정 메서드들을 무조건 재정의하도록 강제하는 기법이다.
  • 특정 메서드를 재정의하도록 강제함으로써, 자식 클래스들을 작성하기 위한 가이드의 역할을 할 수 있다.
  • 즉, 추상화 기법은 java 클래스를 작성하기 위한 설계도를 소스코드 형태로 제시하는 역할을 한다.

 

1-4. 추상 메서드 만들기

  • 추상 메서드를 정의하기 위해서는 'abstract' 키워드를 사용하여 메서드를 정의한다.
  • 추상 메서드는 자식 클래스가 구현해야 하는 메서드의 가이드라인만 제시하기 위한 목적으로 사용되기 때문에, 선언만 가능하고 구현부가 없다.
    // 선언만 가능하고 구현부를 위한 블록이 존재하지 않는다.
    public abstract void sayHello();

 

1-5. 추상 메서드를 포함한 클래스

  • 추상 메서드를 하나 이상 포함하고 있는 클래스는 반드시 '추상 클래스'로 정의되어야 한다.
  • 추상 클래스 'abstract' 키워드를 사용하여 정의할 수 있습니다.
    // 추상 클래스의 정의
    public abstract class Hello {
    	public abstract void sayHello();
    }
  • 추상 클래스는 객체를 생성할 수 없고, 반드시 상속을 통해서만 사용될 수 있다. 즉, 추상 클래스는 다른 자식 클래스를 위한 '가이드라인'의 역할을 한다.

 

1-6. 공통 기능과 설계 제시를 모두 처리하기

  • 추상 클래스는 생성자, 멤버변수, 일반 메서드 등을 포함할 수 있다.
  • 즉, 공통 기능과 가이드라인을 모두 정의하여 다른 클래스에게 상속된다.
public abstract class Hello {
	// 멤버변수
	private String msg;

	// 생성자
	public Hello(String msg) {
		this.msg = msg;    
	}

	// 일반 메서드
	public String getMsg() {
		return this.msg;
	}

	public vlid setMsg(String msg) {
		this.msg = msg;    
	}

	// 선언만 되고, 구현부를 위한 블록이 존재하지 않는 추상 메서드
	public abstract void sayHello();
}

/* 
 * 추상 클래스를 상속받는 과정은 일반 클래스의 상속과 동일하게 'extends' 키워드를 사용한다.
 */
public class Korean extends Hello {

	// 부모 생성자의 호출이 이루어진다.
	public Korean(String msg) {
		super(msg);
	}

	// 추상 메서드의 재정의를 요구한다.
	// 추상 메서드를 상속 받고 에러를 해결하는 과정에서 부모가 정의하고 있는 메서드들을 재정의하게 된다. 
	@Override
	public void sayHello() {
		
	}
	// 추상 클래스는 이와 같이 자식클래스가 정의해야 하는 규격을 강제하기 위하여 사용한다.
}

 


 

추상클래스 Unit
*차상 오타 > 추상 / 자식은 부모의 모든 추상 메서드를 재정의해야 한다.

 


 

 

 

2. 인터페이스

① 부모클래스 Unit과 자식클래스 주인공, 몬스터
② Unit의 기능을 용도별로 나누어 주인공과 몬스터가 각각의 기능 중 자신에게 필요한 것들만 상속받는다.

→ 추상 클래스 Unit의 기능을 용도별로 분할하여 나누어 놓고, 주인공과 몬스터가 각각의 기능 중에서 자신에게 필요한 것들만 상속받도록 하는 방법을 필요로 한다.

 

2-1. 추상 클래스의 한계

자바 클래스 간의 상속에서는 하나의 부모만 존재할 수 있기 때문에, 앞의 상황에서 요구하는 다중 상속의 구현은 불가능하다.

 

2-2. Interface란?

  • 완벽한 추상화를 구현하기 위한 java Calss의 한 종류이다.
  • 다중 상속이 가능하기 때문에 용도별로 세분화하여 필요한 요소만 상속할 수 있다.
  • 추상클래스
    - 멤버변수, 생성자, 메서드, 추상메서드를 포함할 수 있다.
    - 이 클래스를 상속받는 자식 클래스는 다른 클래스를 상속받을 수 없다.
    - 객체의 생성이 불가능하다.
  • 인터페이스
    - 추상 메서드만 포함할 수 있다.
    - 인터페이스는 다중상속이 가능하다.
    - 객체의 생성이 불가능하다.

Unit 인터페이스

 

2-3. 인터페이스 상속을 위한 implements 키워드

  • 인터페이스의 상속은 implements 키워드를 사용한다.
  • 인터페이스도 추상화를 구현하고 있기 때문에, 인터페이스를 상속받는 클래스는 인터페이스 내의 모든 메서드들을 반드시 재정의해야 한다.

Unit 인터페이스를 상속하는(implements) User 클래스

 

2-4. 인터페이스 다중 상속

  • 인터페이스는 콤마(,)로 연결하여 여러 개를 동시에 상속받을 수 있다.
    public class Monster implements Fight, Move {}	// Monster : Class
    						// Fight, Move : Interface
  • 필요한 경우 다른 클래스(▶부모클래스)와 동시에 상속받을 수 있다.
    public class Monster extends User implements Fight, Move {}	// Monster : Class
    								// Fight, Move : Interface
                            					// User : Super Class

 


 

위 구조와 같이 코딩하기
Action, Fight, Move 인터페이스를 상속받는 Character 클래스
Fight, Move 인터페이스를 상속받는 Monster 클래스

 


 

 

 

3. Static
// 하나의 게시물을 표현하기 위한 클래스
public class Article {
	private int num;		// 글 번호
	private String title;		// 제목
	private String regDate;		// 날짜
    
    // 고객사의 요청사항 : 카테고리와 카테고리 내 전체 글 수 추가
	private int count;		// 전체 글 수
	private String category;	// 카테고리
}

  • 멤버변수는 모든 객체가 독립적으로 갖는 고유 데이터이기 때문에 전체 글 수라는 공유데이터를 모든 게시물이 갖게 된다.
  • 즉, 각각의 객체가 중복된 데이터를 갖게 된다.

 

▶ 위에 코딩된 그대로 출력할 경우, 게시물이 추가될 때마다 공유데이터가 계속 업데이트되어 그림과 같이 출력된다.

▶ 메모리의 불필요한 낭비 > 따라서 해결책 필요(↓↓)

 

3-1. 객체 간의 공유 자원을 표현하는 static 키워드

  • 클래스를 설계할 때, 멤버변수 중 모든 객체에서 공통적으로 사용해야 하는 값에 static을 붙인다.
// 하나의 게시물을 표현하기 위한 클래스
public class Article {
	private int num;		// 글 번호
	private String title;		// 제목
	private String regDate;		// 날짜
    
    // 고객사의 요청사항 : 전체 글 수와 카테고리 추가
	private static int count;		// 전체 글 수
	private static String category;	// 카테고리
}

  • static이 붙은 멤버변수는 객체의 개수에 상관없이 단 하나만 생성되며(▶ 메모리 상에 하나만 생성된다는 뜻), 이를 모든 객체가 공유하기 때문에 메모리를 효율적으로 사용할 수 있다.

 

static 멤버변수를 갖는 Article
Article 클래스의 getter, setter
Main 클래스에서 실행

 

3-2. 컴퓨터의 메모리 구조

  • 코드 영역(고정 영역) : 프로그램의 코드가 저장되는 영역
    → 이 영역에 저장된 명령어들을 CPU가 하나씩 가져가 실행한다.
  • 데이터 영역(고정 영역) : 전역변수와 static으로 선언되는 변수가 할당된다.
    이 영역에 할당되는 변수들은 프로그램 시작과 동시에 메모리 공간이 할당되어 종료될 때까지 남아있게 된다.
  • 힙 영역(동적 영역) : 프로그래머가 원하는 시점에 변수를 할당하고 소멸시키는 영역
    → 메모리 동적 할당시 사용된다. 객체가 생성되는 영역이다.
  • 스택 영역(동적 영역) : 함수가 실행될 때 사용되는 파라미터와 지역변수에 대한 메모리 공간
    함수의 종료와 함께 소멸된다.

 

3-3. 하나의 프로그램이 사용하는 메모리 영역

  • 고정영역
    → 프로그램이 실행되면 실행파일이 메모리에 로드되면서, 실행파일의 용량만큼 RAM을 사용한다.
    → 실행 파일의 크기는 변할 수 없으므로 이 영역의 크기는 고정 크기를 갖는다.
  • 동적영역
    → 프로그래머가 new 키워드를 사용해서 객체나 배열을 생성하면 사용된다(힙 영역)
    → 또 다른 경우, 메서드가 호출되는 동안 사용될 파라미터와 지역변수가 생성된다.(스택 영역)
    → 메서드가 종료되거나 객체가 더 이상 사용되지 않으면 생성된 변수나 객체는 메모리에서 사라지므로, 이 영역은 유동적인 크기를 갖게 된다.

3-4. static 데이터의 생성 위치

static 데이터는 메모리의 고정영역 중 데이터 영역에 생성되고, 일반 멤버변수나 객체는 동적 영역 중 Heap 메모리 영역에 생성된다.

 

3-5. 프로그램이 메모리를 사용하는 순서

① 최초 실행 시 고정 영역에 실행 파일만큼의 메모리를 점유한다.② 프로그램이 각종 동작을 수행하는 동안 동적영역을 사용한다.

 

3-6. 멤버변수와 static 멤버변수의 차이

  • static 변수는 프로그램의 실행과 동시에 객체의 생성 여부와 상관없이 이미 존재하기 때문에 소스코드에서는 특정 클래스 안에 명시하지만, 그 클래스를 통해서 생성되는 객체나 그 안에 포함되는 멤버변수와는 다른 존재이다.
  • 객체가 생성되지 않았더라도 이미 존재하고 있기 때문에 static 변수는 객체의 이름을 통해 접근하는 것이 아니라, 클래스의 이름을 통해서 접근해야 한다.
  • 단, static 변수가 선언된 클래스 안에서는 변수 이름으로 직접 접근이 허용된다.
  • Article 클래스 및 다른 클래스에서 접근하는 경우
    Article.count = 9;
    Article.category = "공지사항";

 

  • Article 클래스에서 접근하는 경우
    count = 15;
    category = "Q&A게시판";

 

3-7. static 변수와 static 메서드

  • 클래스에서 정의하는 일반 메서드들은 객체의 생성과 동시에 동적 메모리 영역에서 활성화된다.
    → 동적 메모리 영역의 입장에서는 고정 메모리 영역의 자원들은 항상 존재한다.
    고정 메모리 영역의 자원들은 동적 메모리의 자원들이 항상 존재하는 것이라는 보장을 받지 못한다.
  • 그러므로 객체의 생성과 상관없이 static 변수에 접근하기 위한 메서드를 만들 필요가 있는데, 메서드의 정의 과정에서 static 키워드를 사용하면 static 자원에 접근하기 위한 메서드를 만들 수 있다.
public class Article {
	private static int count;
    
    public static void setCount(int count) {
		Article.count = count;
	}

	public static int getCount(){
		return Article.count;    
	}
}

 

3-8. static 메서드 사용 시 제약 사항

메모리 영역의 차이 때문에 static 메서드는 동적 메모리 영역의 멤버 변수를 사용하거나, static이 아닌 일반 멤버함수를 호출할 수 없다.

  • 고정 영역
    static 변수와 static 멤버함수가 생성된다.
    → 이 영역의 자원들은 프로그램이 실행되는 동안 항상 존재한다.
    동적 영역의 자원들은 항상 존재하는 것이 아니기 때문에 Static 멤버함수는 동적 영역의 멤버변수를 사용하거나
        static이 아닌 일반 멤버함수를 호출할 수 없다.
  • 동적 영역
    객체, 객체 안에 멤버변수, 메서드, 메서드가 호출되었을 때 사용되는 지역변수 등이 생성된다.
    → 이 영역의 자원들은 생성과 제거가 유동적으로 반복된다.
    static 자원은 항상 존재하는 것이므로 동적 영역에서는 static 변수를 활용하거나, static 멤버함수를 호출할 수 있다.
728x90

+ Recent posts