01. 객체와 객체 지향 프로그래밍
객체 (Object)
의사나 행위가 미치는 대상 ( 사전적 의미 )
구체적, 추상적 데이터의 단위 ( 학생, 회원, 생산, 주문, 배송 )
명사와 같은 것들
객체 지향 프로그램과 절차 지향 프로그래밍
아침에 일어나 학교를 가는 과정을 예를 들어 봅시다.
절차 지향 프로그래밍이 일어난다 -> 씻는다 -> 밥을 먹는다 -> 버스를 탄다-> 요금을 지불한다 -> 학교에 도착
절차 지향 프로그래밍 언어: C언어 등..
-시간이나 사건의 흐름에 따른 프로그래밍
객체 지향 프로그래밍
C++, C#, Python, Javascript, Java 등...
객체들 간의 상호작용이 일어남. 즉, 객체마다의 관계가 정의됨
객체 지향 프로그램은 어떻게 구현하는가?
객체를 정의 하고
각 객체 제공하는 기능들을 구현하고
각 객체가 제공하는 기능들 간의 소통(메세지 전달)을 통하여 객체간의 협력을 구현
02. 생활 속에서 객체 찾아 클래스로 구현해 보기
객체를 찾아 봅시다
온라인 쇼핑몰에 회원 로그인을 하고 여러 판매자 가 판매하고 있는 제품 중 하나를 골라 주문 을 한다
아침에 회사 에 가는 길에 별다방 커피숍에 들려 아이스 카페라떼 를 주문했다
성적확인을 위해 학사 관리 시스템에 로그인 하여 수강 한 과목들의 성적을 확인했다.
학생, 과목, 학기, 교수님, 강의실, 통계자료 등...
각 객체를 구성하기 위해 겉으로는 보이지 않는 객체들도 존재합니다.
클래스는 객체의 청사진(blueprint) 입니다
객체의 속성은 클래스의 멤버 변수(member variable) 로 선언 함
학생 클래스 (학생마다 필요한 속성을 '멤버변수' 로 정의)
String은 기본 데이터 타입이 아닌 자바에서 제공하는 라이브러리의 데이터 타입이다.
또한 데이터 타입으로 객체가 사용될 수도 있다.
객체 지향 프로그램을 할 때는
객체를 정의 하고
각 객체의 속성을 멤버 변수로 역할을 메서드로 구현하고
각 객체간의 협력을 구현합니다.
클래스 코딩하기
클래스는 대문자로 시작하는것이 좋음
java 파일 하나에 클래스는 여러 개가 있을 수 있지만, public 클래스는 하나이고, public 클래스와 .java 파일의 이름은 동일함
camel notation 방식으로 명명
03. 함수와 메서드
함수란 (function)
하나의 기능을 수행하는 일련의 코드
구현된(정의된) 함수는 호출하여 사용하고 호출된 함수는 기능이 끝나면 제어가 반환됨
함수로 구현된 하나의 기능은 여러 곳에서 동일한 방식으로 호출되어 사용될 수 있음
함수 정의하기
함수는 이름, 매개 변수, 반환 값, 함수 몸체(body)로 구성됨
함수의 반환값이 없는 경우 'void'로 명시한다.
매개변수가 없는 경우에는 괄호를 빈 채로 두기도 한다.
함수 구현하기 예제
함수 호출과 스택 메모리
스택 : 함수가 호출될 때 지역 변수들이 사용하는 메모리
함수의 수행이 끝나면 자동으로 반환 되는 메모리
메서드 (method)
객체의 기능을 구현하기 위해 클래스 내부에 구현되는 함수
멤버 함수 (member function)이라고도 함
메서드를 구현함으로써 객체의 기능이 구현 됨
메서드의 이름은 그 객체를 사용하는 객체(클라이언트)에 맞게 짓는것이 좋음
즉 호출하는 측 입장에서 작명한다.
예) getStudentName()
04. 객체의 속성은 멤버 변수로, 객체의 기능은 메서드로 구현한다
학생 클래스를 정의 하고 이를 사용해 보자
학생 클래스의 속성을 멤버 변수로 선언하고 메서드를 구현한다
학생 클래스를 생성하여 생성된 객체(인스턴스)에 각각 다른 이름과 주소를 대입한다
이는 만든 클래스를 생성해 보기 위해서 만든 클래스이며 클래스를 생성할 때는 new 연산자와 함께 작성한다.
이처럼 만들어진 하나의 인스턴스는 여러개가 만들어질 수 있으며 각각이 이름은 같지만 물리적으로는 다른 멤버변수와 메서드를 갖게 된다.
05. 인스턴스 생성과 힙 메모리 (heap memory)
인스턴스 (instance)
클래스는 객체의 속성을 정의하고, 기능을 구현하여 만들어 놓은 코드 상태
실제 클래스 기반으로 생성된 객체(인스턴스)는 각각 다른 멤버 변수 값을 가지게 됨
가령, 학생의 클래스에서 생성된 각각의 인스턴스는 각각 다른 이름, 학번, 학년등의 값을 가지게 됨
new 키워드를 사용하여 인스턴스 생성
힙 메모리
생성된 인스턴스는 동적 메모리(heap memory) 에 할당됨
C나 C++ 언어에서는 사용한 동적 메모리(malloc)를 프로그래머가 해제 시켜야 함 ( free()나 delete 이용)
자바에서 Gabage Collector 가 주기 적으로 사용하지 않늠 메모리를 수거
하나의 클래스로 부터 여러개의 인스턴스가 생성되고 각각 다른 메모리 주소를 가지게 됨
studentLee 자체를 참조 변수, 그것이 가리키는 것은 참조 값이라고 한다.
참조 변수, 참조 값
용어 정리
06. 생성자에 대해 알아봅시다 (constructor)
int와 같은 것들은 따로 생성자를 만들지 않아도 되고, 선언 시에 자동적으로 메모리 4바이트가 할당 됨.
생성자
생성자 기본 문법 <class_name>([<argument_list]) { [<statements] }
객체를 생성할 때, new 키워드와 함께 사용 - new Student();
생성자는 일반 함수처럼 기능을 호출하는 것이 아니고 객체를 생성하기 위해 new 와 함께 호출 됨
객체가 생성될 때 변수나 상수를 초기화 하거나 다른 초기화 기능을 수행하는 메서드를 호출 함
생성자는 반환 값이 없고, 클래스의 이름과 동일
대부분의 생성자는 외부에서 접근 가능하지만, 필요에 의해 private 으로 선언되는 경우도 있음
기본 생성자 (default constructor)
클래스에는 반드시 적어도 하나 이상의 생성자가 존재
클래스에 생성자를 구현하지 않아도 new 키워드와 함께 생성자를 호출할 수 있음
클래스에 생성자가 하나도 없는 경우 컴파일러가 (기본) 생성자 코드를 넣어 줌
매개 변수가 없음, 구현부가 없음
생성자 만들기
컴파일러가 제공해 주는 기본 생성자외에 필요에 의해 생성자를 직접 구현 할 수 있음
Student.java
StudentTest.java
멤버 변수는 객체가 생성될 때 데이터 타입에 맞게 자동으로 초기화된다.
만약 Student 객체를 생성할 때 안에 인자가 없이 생성하면 오류가 발생함.
생성자를 별도로 만들어 컴파일러에 의해 default 생성자가 따로 생성되지 않기 때문에
07. 여러가지 생성자를 정의하는 생성자 오버로딩 (overloading)
생성자 정의 하기
생성자를 구현해서 사용할 수 있음
클래스에 생성자를 따로 구현하면 기본 생성자 (default constructor)는 제공되지 않음
생성자를 호출하는 코드(client 코드)에서 여러 생성자 중 필요에 따라 호출해서 사용할 수 있음
UserInfo.java
UserInfoTest.java
1. 멤버 변수를 직접 바꾸는 방식
2. 생성자 호출 시 멤버 변수값 세팅되도록 하는 방식
08. 복습해봅시다 (객체 구현하기)
다음 설명에 해당되는 객체를 구현하고 해당 정보를 출력해 보세요
키가 180 이고 몸무게가 78킬로인 남성이 있습니다. 이름은 Tomas 이고 나이는 37세입니다.
음식점에 배달 주문이 들어왔습니다.
09. 참조 자료형 변수
참조 자료형
클래스형으로 변수를 선언
기본 자료형(Primitive Datatype)은 사용하는 메모리의 크기가 정해져 있지만, 참조 자료형은 클래스에 따라 다름
참조 자료형을 사용 할때는 해당 변수에 대해 생성하여야 함 (String 클래스는 예외적으로 생성하지 않고 사용할 수 있음)
참조 자료형 정의하여 사용하기
학생이 수강한 과목들에 대한 성적을 산출하기 위한 경우 학생 클래스 속성에 과목이 모두 있으면 불합리
학생(Student)과 과목(Subject)에 대한 클래스를 분리하여 사용하고 Subject 클래스를 활용하여 수강한 과목들의 변수의 타입으로 선언
선언된 Subject 변수는 생성된 인스턴스가 아니므로, Student의 생성자에서 생성하여 사용
Student.java
Subject.java
StudentTest.java
10. 접근 제어 지시자(access modifier)와 정보은닉(infomation hiding)
접근 제어 지시자 (accesss modifier)
클래스 외부에서 클래스의 멤버 변수, 메서드, 생성자를 사용할 수 있는지 여부를 지정하는 키워드
private : 같은 클래스 내부 에서만 접근 가능 ( 외부 클래스, 상속 관계의 클래스에서도 접근 불가)
아무것도 없음 (default) : 같은 패키지 내부 에서만 접근 가능 ( 상속 관계라도 패키지가 다르면 접근 불가)
protected : 같은 패키지 나 상속관계의 클래스 에서 접근 가능하고 그 외 외부에서는 접근 할 수 없음
public : 클래스의 외부 어디서나 접근 할 수 있음
get()/ set() 메서드
private 으로 선언된 멤버 변수 (필드)에 대해 접근, 수정할 수 있는 메서드를 public으로 제공
get() 메서드만 제공 되는 경우 read-only 필드
이클립스에서 자동으로 생성됨
정보 은닉
private으로 제어한 멤버 변수도 public 메서드가 제공되면 접근 가능하지만 변수가 public으로 공개되었을 때보다
private 일때 각 변수에 대한 제한을 public 메서드에서 제어 할 수 있다.
객체 지향 프로그램에서 정보 은닉은 필요한 외부에서 접근 가능한 최소한의 정보를 오픈함으로써 객체의 오류를 방지하 클라이언트 객체가 더 효율적으로 객체를 활용할 수 있도록 해준다.
이렇게 멤버변수에 직접적으로 접근하지 않는 이유는 해당 멤버 변수를 클래스를 생성하는 쪽에서 그냥 바꿔버리게 되면 유효하지 않은 값이 들어가도 처리할 수 있는 방법이 없지만 getter()와 setter()를 통해 변경하면 그 validation을 해 줄 수 있기 때문이다.
11. 캡슐화 (encapsulation)
정보 은닉을 활용한 캡슐화
(객체를 감싸서) 꼭 필요한 정보와 기능만 외부에 오픈함
대부분의 멤버 변수와 메서드를 감추고 외부에 통합된 인터페이스만은 제공하여 일관된 기능을 구현 하게 함
각각의 메서드나 멤버 변수를 접근함으로써 발생하는 오류를 최소화 한다.
레포트 만들기 예제
객체 지향 설계를 할 때에는 어떤 필드, 메소드는 숨길지, 공개할 지를 고려하는 것이 중요하다.
12. 객체 자신을 가리키는 this
this가 하는 일
인스턴스 자신의 메모리를 가리킴
생성자에서 또 다른 생성자를 호출 할때 사용
자신의 주소(참조값)을 반환 함
생성된 인스턴스 메모리의 주소를 가짐
클래스 내에서 참조변수가 가지는 주소 값과 동일 한 주소 값을 가지는 키워드
생성자에서 다른 생성자를 호출 하는 this
클래스에 생성자가 여러 개 인경우, this를 이용하여 생성자에서 다른 생성자를 호출할 수 있음
생성자에서 다른 생성자를 호출하는 경우, 인스턴스의 생성이 완전하지 않은 상태이므로 this() statement 이전에 다른 statement를 쓸 수 없음
자신의 주소를 반환하는 this
13. 객체 간의 협력 (collabration)
객체 지향 프로그래밍에서의 협력
객체 지향 프로그램에서 객체 간에는 협력 이 이루어짐
협력을 위해서는 필요한 메세지를 전송하고 이를 처리하는 기능이 구현되어야 함
매개 변수로 객체가 전달되는 경우가 발생
객체 협력의 예
객체지향 프로그래밍은 어찌보면 실생활을 굉장히 잘 반영한 테크닉임을 알 수 있다.(by 각각의 협력)
14. 버스 타고 학교 가는 학생의 과정을 객체 지향 프로그래밍으로 구현해보기
버스와 지하철을 타는 예제 프로그래밍
Student.java
Bus.java
Subway.java
TakeTransTest.java
15. 복습해봅시다 (객체 협력)
다음과 같은 상황을 구현해 봅시다.
출력결과
16. 여러 인스턴스에서 공통으로 사용하는 변수를 선언하자 - static 변수
그 전까지 한 인스턴스를 생성하기 위해서 new 연산자를 통해서 생성했었다. 그러면 생성되는 인스턴스마다의 메모리가 heap 영역에 생성되었었는데 프로그램을 짜다 보면 같은 클래스의 인스턴스끼리 공통적으로 사용해야하는 변수가 필요할 때가 존재한다.
이것이 바로 static 변수이다.
공통으로 사용하는 변수가 필요한 경우
여러 인스턴스가 공유하는 기준 값이 필요한 경우
학생마다 새로운 학번 생성
카드회사에서 카드를 새로 발급할때마다 새로운 카드 번호를 부여
회사에 사원이 입사할때 마다 새로운 사번이 필요한
static 변수 선언과 사용하기
static int serialNum;
인스턴스가 생성될 때 만들어지는 변수가 아닌(At heap), 처음 프로그램이 메모리에 로딩될 때 메모리를 할당(At data)
클래스 변수, 정적변수라고도 함(vs. 인스턴스 변수)
인스턴스 생성과 상관 없이 사용 가능하므로 클래스 이름으로 직접 참조
Student.serialNum = 100;
static 변수 테스트하기
Employee.java
EmployeeTest.java
static 변수는 인스턴스에서 공통으로 사용하는 영역임을 알 수 있음
지역변수들은 스택 메모리에 할당되며, 그로 인해 참조되는 메모리는 힙 영역이다.
데이터 영역: 프로그램이 실행(load)될 때 할당 되어지고 프로그램이 종료될 때(unload) 소멸되는 메모리 공간
스택 메모리: 함수가 호출되어 변수가 선언될 때 생성되는 메모리 공간
힙 메모리: 인스턴스가 생성될 때 만들어지고 소멸될 때 다시 사라지는 메모리 공간
회사원이 입사할 때마다 새로운 사번 부여하기
Employee.java 생성자 구현
EmployeeTest.java
static 변수와 메서드는 인스턴스 변수, 메서드가 아니므로 클래스 이름으로 직접 참조
static 변수는 프로그램이 실행될 때 메모리에 로드되기 때문에 해당 클래스의 인스턴스를 생성해 주지 않아도 해당 변수에 접근이 가능하다. 이 때 클래스 이름으로 참조를 해야 한다.
17. static메서드의 구현과 활용, 변수의 유효 범위
static 메서드 만들기
serialNum 변수를 private으로 선언하고 getter/setter 구현
Employee.java
클래스 이름으로 호출 가능 ( 클래스 메서드, 정적 메서드 )
static 메서드(클래스 메서드)에서는 인스턴스 변수를 사용할 수 없다
static 메서드는 인스턴스 생성과 무관하게 클래스 이름으로 호출 될 수 있음
인스턴스 생성 전에 호출 될 수 있으므로 static 메서드 내부에서는 인스턴스 변수(멤버 변수)를 사용할 수 없음
반대로 인스턴스 메서드 내에서 static 변수에 접근하는 것은 가능하다.(static 변수는 이미 메모리에 로드되어 있기 때문에)
Employee.java
EmployeeTest2.java
변수의 유효 범위와 메모리
변수의 유효 범위(scope)와 생성과 소멸(life cycle)은 각 변수의 종류마다 다름
지역변수, 멤버 변수, 클래스 변수는 유효범위와 life cycle, 사용하는 메모리도 다름
static 변수는 프로그램이 메모리에 있는 동안 계속 그 영역을 차지하므로 너무 큰 메모리를 할당하는 것은 좋지 않음
클래스 내부의 여러 메서드에서 사용하는 변수는 멤버 변수로 선언하는 것이 좋음
멤버 변수가 너무 많으면 인스턴스 생성 시 쓸데없는 메모리가 할당됨
클래스의 속성이 될 수 있는 변수를 토대로 멤버변수로 선언
상황에 적절하게 변수를 사용해야 함
18. static 응용 - 싱글톤 패턴(singleton pattern)
싱글톤 패턴이란?
프로그램에서 인스턴스가 단 한 개만 생성되어야 하는 경우 사용하는 디자인 패턴
예시) 회사라는 인스턴스는 딱 하나만 있어야지, 여러 개가 생성되면 사원 수가 배가 된다.
static 변수, 메서드를 활용하여 구현 할 수 있음
싱글톤 패턴으로 회사 객체 구현하기
이를 통해 외부에서 new 연산자를 통해 인스턴스를 생성하는 것을 막는다.
클래스 내부에 유일한 private 인스턴스 생성
유일한 인스턴스(객체)가 클래스 내부에서 만들어진다.
외부에서 유일한 인스턴스를 참조할 수 있는 public 메서드 제공
외부에서 접근할 수 있도록 static 메서드 로 선언
CompanyTest.java
19. 복습해봅시다 (static과 싱클톤 패턴)
설명에 따른 객체를 구현하여 테스트 코드가 실행되도록 구현하기
CarFactoryTest.java
20. 자료를 순차적으로 한꺼번에 관리하는 방법 - 배열(array)
배열이란?
동일한 자료형(same datatype)의 순차적 자료 구조
인덱스 연산자[]를 이용하여 빠른 참조가 가능
물리적 위치와 논리적 위치가 동일
바로 옆칸에 존재하면 실제로 physically 옆칸에 존재하는 것
Linked List와는 다른 개념
배열의 순서는 0부터 시작
자바에서는 객체 배열을 구현한 ArrayList를 많이 활용함
몇개짜리 배열인지 선언시 명시해야 함.
배열 선언과 초기화
배열은 선언과 동시에 자료형에 따라 초기화 됨 ( 정수는 0, 실수는 0.0, 객체는 null)
필요에 따라 초기값을 지정할 수 있음
배열 사용하기
[] 인덱스 연산자 활용 - 배열 요소가 저장된 메모리의 위치를 연산하여 찾아 줌
배열을 이용하여 합을 구하기
new 라는 키워드로 배열을 생성하게 되면 초기에 특정 값으로 초기화 해 주지 않아도 0으로 초기화가 된다.
배열의 길이와 요소의 개수는 동일하지 않습니다.
배열을 선언하면 개수만큼 메모리가 할당되지만, 실제 요소(데이타)가 없는 경우도 있음
배열의 length 속성은 배열의 개수를 반환해주기 때문에 요소의 개수와는 다름
length를 활용하여 오류가 나는 경우
요소의 개수에 대한 변수(count)를 따로 유지
문자 배열을 만들어 A-Z 까지 배열에 저장하고 이를 다시 출력하기
향상된 for문 사용하기
배열의 n개 요소를 0 부터 n-1까지 전부 순차적으로 순회할 때 간단하게 사용할 수 있음
21. 객체 배열 사용하기
객체 배열 선언과 구현
기본 자료형 배열은 선언과 동시에 배열의 크기만큼의 메모리가 할당되지만, 객체 배열의 경우엔 요소가 되는 객체의 주소가 들어갈(4바이트, 8바이트) 메모리만 할당되고(null) 각 요소 객체는 생성하여 저장해야 함
Person 객체를 생성한다면 Person 객체의 주소를 저장할 메모리가 할당이된다.
Book.java
BookArrayTest.java
객체 배열 복사하기
System.arrayCopy(src, srcPos, dest, destPos, length) 자바에서 제공되는 배열 복사 메서드
얕은 복사(shallow copy) 즉, 두 배열이 같은 객체를 가리킴
객체 주소만 복사되어 한쪽 배열의 요소를 수정하면 같이 수정 됨
깊은 복사(deep copy)
일일히 각각의 객체를 생성하여 그 객체의 값 을 복사 하여 배열이 서로 다른 객체를 가리키도록 함
22. 2차원 배열 사용하기
다차원 배열
이차원 이상으로 구현 된 배열
평면 (이차원 배열) 이나 공간(삼차원 배열)을 활용한 프로그램 구현
이차원 배열 예제
실제로는 일렬로 배치되어 있지만 논리적으로 아래 그림과 같이 생각한다.
22. 2차원 배열 사용하기
다차원 배열
이차원 이상으로 구현 된 배열
평면 (이차원 배열) 이나 공간(삼차원 배열)을 활용한 프로그램 구현
이차원 배열 예제
23. 객체 배열을 구현한 클래스 ArrayList
java.util 패키지에서 제공되는 ArrayList
기존의 배열 선언과 사용 방식은 배열의 길이를 정하고 요소의 개수가 배열의 길이보다 커지면 배열을 재할당하고 복사해야 했음
배열의 요소를 추가하거나 삭제하면 다른 요소들의 이동에 대한 구현을 해야 함
ArrayList는 객체 배열을 좀더 효율적으로 관리하기 위해 자바에서 제공해 주는 클래스
이미 많은 메서드들이 최적의 알고리즘으로 구현되어 있어 각 메서드의 사용 방법만 익히면 유용하게 사용할 수 있음
ArrayList의 주요 메서드
ArrayList를 활용한 간단한 예제
24. ArrayList를 활용한 간단한 성적 산출 프로그램
예제 시나리오
Student 클래스
Subject 클래스
실행하기