일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 짝수
- sigmoid
- LSTM
- inner join
- nlp논문
- HackerRank
- 카이제곱분포
- NLP
- Window Function
- airflow
- 자연어 논문
- 표준편차
- MySQL
- GRU
- update
- Statistics
- 자연어 논문 리뷰
- 그룹바이
- leetcode
- sql
- torch
- CASE
- 설명의무
- 서브쿼리
- 논문리뷰
- 코딩테스트
- 자연어처리
- SQL 날짜 데이터
- t분포
- SQL코테
- Today
- Total
HAZEL
[ CH02. 객체지향 입문 ] 객체 간의 협력, static 변수, 싱글톤 패턴(Singleton pattern) , 배열 , 다차원 배열 본문
[ CH02. 객체지향 입문 ] 객체 간의 협력, static 변수, 싱글톤 패턴(Singleton pattern) , 배열 , 다차원 배열
Rmsid01 2021. 3. 31. 13:33CH02. 객체지향 프로그래밍
: 패스트 캠퍼스 강의를 공부하고 정리한 내용입니다.
01. 객체 간의 협력 (collabration)
: 객체지향 프로그래밍에서 객체 간에는 협력이 이루어짐 - 유기적으로 연동되어있다.
: 협력을 위해서는 필요한 메세지를 전송하고 이를 처리하는 기능이 구현되어야 함
: 매개 변수로 객체가 전달되는 경우가 발생
02. static 변수 ( 정적 변수 )
: 동일한 클래스에서 생성된 여러 인스턴스에서 공통으로 사용하는 변수
1. 공통으로 사용하는 변수가 필요한 경우.
: 여러 인스턴스가 공유하는 기준 값이 필요한 경우
2. static 변수 사용 법
: static int LEEnum;
Student.LEEnum = 100;
- 인스턴스가 생성될때 만들어지는 변수가 아닌, 처음 프로그램이 메모리에 로딩될때, 메모리 할당 ( 자세한건 아래에 적혀있음 )
- 클래스 변수, 정적변수 라고 함. ( 인스턴스 변수와는 다르다 )
- 인스턴스 생성과 상관없이 사용 가능하므로, 클래스 이름으로 직접 참조
3. static 변수는 언제 만들어 지는 가 ?
: 프로그램을 구동시키면 -> 메모리에 올라가게 됨. ( 이러한 상태를 '프로세스'라고 함 ) -> 스레드 상태가 되서 돌아감
이렇게, 메모리에 올라가게 될때, 2가지 영역을 가지게 됨.
1. data( 상수, static ) 영역 - 처음에 메모리에 로딩될때, 처음부터 메모리를 잡는 영역 ex, 상수, 리터럴, static 변수
2. 코드 영역 - 프로그래밍을 하면, instruction - 명령을 하게되면 라인 바이 라인으로 수행됨.
즉, **힙메모리가 아닌, data 영역에 사용됨. 메모리가 로딩되는 순간 잡히고, 프로그래밍이 끝나서 메모리가 업로드 되는 순간 없어짐.
** 힙 메모리 - 인스턴스가 사용될때마다 쓰이는 메모리 ( 동적 메모리 ) => 이것이 사라지는 순간 garbage collector 에 의해서 메모리가 수거가 됨.
4. static 메서드의 구현과 활용
: 클래스 이름으로 호출 가능 ( 클래스 메서드, 정적 메서드 )
: 인스턴스 호출과 무관하게 바로 메서드를 사용할 수 있다. ( 이미 메모리상에 저장되어있기 때문! )
System.out.println(Employee.getSerialNum());
- static 메서드 ( 클래스 메서드 ) 에서는 인스턴스 변수를 사용할 수 없다.
: 인스턴스 생성과 무관함. - 따라서,
: 인스턴스 생성 전에 호출 될 수 있으므로 static 메서드 내부에서는 인스턴스 변수를 사용할 수 없음.
public static void setSerialNum(int serialNum) {
int i = 0; // i 는 이함수가 시작해서 없어질 지역 변수 - 지역변수는 상관 없다.
// employeeName = "Lee"; - 이 함수가 불러올때 이 변수(인스턴스변수)가 없을 수도 있음 -> 오류 발생
Employee.serialNum = serialNum;
}
// static가 아닌 일반 메서드 안에서는 아무 문제가 없다
// 메모리 문제 ! - 일반 메서드에서 static 변수를 사용하는것은 아무 문제가 없다. ( 이미 static은 있기 때문에)
public int getEmployeeId() {
serialNum = 1000;
return employeeId;
}
5. 변수의 유효범위(scope) 와 메모리
: 변수의 유효범위와 생성, 소멸은 각 변수의 종류마다 다르다.
: static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지함 -> 매우 큰 메모리를 할당하는것은 안좋음
: 클래스 내부의 여러 메서드에서 여러번 사용하는 변수는 멤버 변수로 선언하는것이 나음
: 그러나, 멤버 변수가 너무 많으면 인스턴스 생성시 메모리가 쓸데없이 할당되므로 적절하게 사용하는 것이 좋음
03. 싱글톤 패턴 ( Singleton pattern )
1. 싱글톤 패턴이란
: 디자인패턴(23개패턴)의 한 분야로, 객체지향프로그램에 의해서 좀더 효율적인 코드를 만들고자 하는 패턴
: 보통, 인스턴스가 여러개인 경우가 많지만, 그럴경우 문제가 발생하는 경우가 존재한다. ( ex, date ) 즉, 프로그램에서 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴으로 static 변수, 메서드를 활용하여 구현 가능
public class Company {
// 회사이름은 단하나 이기 때문에, static으로 만듦
private static Company instance = new Company();
// 외부에서 회사를 마음대로 new 할수없도록 private를 만듦
private Company(){}
// static 을 넣어줘야 외부에서 아래 이름을 써어줄수 있음 .
// 외부에서 유일한 인스턴스를 참조할 수 있는 public 메서드 제공
public static Company getInstance() {
if (instance == null){
instance = new Company(); // 혹시 몰라서 넣은 방어적인 코드
}
return instance;
}
}
import java.util.Calendar;
public class CompanyTest {
public static void main(String[] args) {
// 인스턴스를 만들지 않고, 바로 가져다 쓸것 이기 때문에 statics
Company company1 = Company.getInstance();
Company company2 = Company.getInstance();
System.out.println(company1); // ch18.Company@1540e19d
System.out.println(company2); // ch18.Company@1540e19d - 같음
// 날짜가 필요할때, 자바에서 util에서 제공해줌. - static 이므로, new 안됨. - 유일한 객체를 제공함
Calendar calendar = Calendar.getInstance();
System.out.println(calendar);
}
}
즉 , class 이름 : singleton 으로 - instance 라는 이름의 private 멤버 변수 - singleton 생성자가 private 이고, getinstance public으로 제공된다.
04. 배열
1. 배열이란?
: 동일한 자료형의 순차적 자료구조, 인덱스 연산자 [] 을 이용해서 빠르게 참조할 수 있음
: 물리적 위치와 논리적 위치가 동일하며 '0' 부터 시작함. - 데이터를 찾는데 빠르다. ( linked list 와 다름 )
- 자바에서는 ArrayList 를 많이 활용함 ( 파이썬에서 array와 비슷한 것 같다 )
- 배열의 한 요소를 element라고 하며, 몇개인지 먼저 선언해준다. 즉, size를 설정해준다.
- element 끼리 연속적이어야 한다. -> 그로인해, 중간에 삽입이나 삭제할 경우, 속도 지연이 좀 걸린다.
- 기본자료형 배열 ( int , double ) , 객체 배열 ( Student ,Employee )
2. 배열 선언 < 2가지 방법이 있음 >
int[] arr1 = new int[10];
int arr2[] = new int[10];
3. 배열 초기화 < 3가지 방법 >
: 배열은 선언과 동시에 자료형에서 초기화됨.
int[] numbers = new int[] {10, 20, 30}; //개수 생략해야 함 new int[3] - x
int[] numbers = {10, 20, 30}; // new int[] 생략 가능
int[] ids;
ids = new int[] {10, 20, 30}; // 선언후 배열을 생성하는 경우는 new int[] 생략할 수 없음
- arr.length : 길이를 나타내줌 ( 파이썬의 len(arr) 와 동일 )
4. 배열의 길이와 요소의 개수는 동일하지 않음
: 배열을 선언하면 개수만큼 메모리가 할당되지만, 실제 데이타가 없을 수 도 있음.
: arr.length - 배열의 개수를 반환 ; 요소의 개수와 다를 수 있음 . 즉, length를 활용하여 오류가 나는 경우가 있음
5. 객체 배열 선언과 구현
: 배열을 선언한 다는 것은 단지, 주소만 잡힌다. ( 메모리가 할당 ) 는 개념이지, 각 배열의 요소들의 객체는 생성된 것은 아니다.
따라서, 각각 객체는 생성하여 저장해야한다.
package ch21;
public class BookArrayTest {
public static void main(String[] args) {
Book[] library = new Book[5];
// 객체를 생성해서 각 배열의 요소 넣기 - 안넣으면 null 이 뜸
library[0] = new Book("태백산맥1","조정래");
library[1] = new Book("태백산맥2","조정래");
library[2] = new Book("태백산맥3","조정래");
library[3] = new Book("태백산맥4","조정래");
library[4] = new Book("태백산맥5","조정래");
for(int i = 0 ; i <library.length ; i++){
System.out.println(library[i]);
library[i].showBookInfo();
}
}
}
6. 객체 배열 복사
a. 얕은 복사
: 객체주소만 복사되어 한쪽 배열의 요소를 수정하면 같이 수정됨. 즉, 같은 객체( 같은 주소를 ) 가리킴
: 같이 복사된 이유는, 원본과 카피라이브러리가 있을 때, new를 하면 또 새로운 공간에 객체가 만들어진다.
- 여기서 복사한 것은 저 새로운 공간인 '주소'를 복사한 것이기 때문에, 두개 배열 모두 영향을 주게 된 것이다.
// 기준점 ~에서, 목적지 ~ 까지 , 얼만큼
System.arraycopy(library, 0, copylibrary , 0, 5);
b. 깊은 복사
: 각각의 객체를 생성하여 그 객체의 값을 복사하여 배열이 서로 다른 객체를 가리키도록 함.
: 다르게 복사가 되는 이유는 각각 다른 인스턴스의 주소를 가지고 있기 때문이다.
Book[] library = new Book[5];
Book[] copylibrary = new Book[5];
// 객체를 생성해서 각 배열의 요소 넣기 - 안넣으면 null 이 뜸
library[0] = new Book("태백산맥1", "조정래");
library[1] = new Book("태백산맥2", "조정래");
library[2] = new Book("태백산맥3", "조정래");
library[3] = new Book("태백산맥4", "조정래");
library[4] = new Book("태백산맥5", "조정래");
// 깊은 복사
copylibrary[0] = new Book();
copylibrary[1] = new Book();
copylibrary[2] = new Book();
copylibrary[3] = new Book();
copylibrary[4] = new Book();
// 다른 주소에 값만 복사!
for (int i = 0; i < library.length; i++) {
copylibrary[i].setTitle(library[i].getTitle());
copylibrary[i].setAuthor(library[i].getAuthor());
}
7. 다차원 배열
: 2차원 이상으로 구현된 배열 - 평면이나 공간을 표현할 수 있음.
int[ ][ ] = new int[2][3]
int[ ][ ] = {{1,2,3},{4,5,6}} // 초기화
8. ArrayList - java.util 패키지 제공
: 기존의 배열 선언과 사용은 - 배열의 길이를 정하고, 요소의 개수가 배열의 길이보다 커지면 배열을 재할당하고 복사해야한다는 단점을 가지고 있었다. 이것을 좀더 효율적으로 관리하기 위해서 자바에서 제공해주는 코드!
ArrayList<Book> library = new ArrayList<Book>(); // 생성자.
library.add(new Book("태백산맥","조정래"));