객체지향언어
객체지향이론의 역사
객체지향이론의 기본개념
- 실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용
- 실제 사물의 속성과 기능을 분석한 후 가상 세계를 구현해 모의실험을 함으로써 많은 시간과 비용 절약 가능.
발전과정
- 기존에는 FORTRAN이나 COBOL과 같은 절차적 언어들이 주류 언어
- 1980년대 중반에 C++를 비롯한 여러 객체지향언어 발표됐으나 주류 언어로는 자리잡지 못함
- 프로그램의 규모가 커지고 사용자의 요구가 빠르게 변화하면서 절차적 언어로는 대응에 한계가 있어 객체지향언어를 이용한 개발방법론이 대안으로 부상
- 1995년 자바 발표, 1990년대 말에 크게 유행하게 되면서 객체지향언어가 주류 언어로 자리잡음
객체지향언어
객체지향언어란?
- 기존의 프로그래밍 언어에 몇 가지 새로운 규칙을 추가
- 규칙을 통해 코드 간에 서로 관계를 맺어줌으로서 보다 유기적으로 프로그램을 구성하는 것이 가능해짐
객체지향언어의 특징
- 코드의 재사용성이 높다.
- 코드의 관리가 용이하다.
코드간 관계를 이용해서 적은 노력으로도 쉽게 코드의 변경이 가능
- 신뢰성이 높은 프로그래밍을 가능하게 한다.
제어자와 메서드를 이용해 데이터를 보호하고 올바른 값을 유지하도록 하여 코드의 중복을 제거해 코드의 불일치로 인한 오동작 방지 가능
클래스와 객체
클래스와 객체의 정의와 용도
클래스
- 정의 : 객체를 정의해놓은 것, 객체의 설계도 또는 틀
- 용도 : 객체르 생성하는 데 사용됨
객체
- 정의 : 실제로 존재하는 것
- 용도 : 객체가 가지고 있는 기능과 속성에 따라 다름
클래스와 객체의 관계
- 클래스 : 객체 = 제품 설계도 : 제품
- 클래스는 단지 객체를 생성하는데 사용되지 객체 그 자체는 아님
- JDK에서는 프로그래밍을 위해 수많은 유용한 클래스를 기본적으로 제공
객체와 인스턴스
인스턴스란?
- 클래스의 인스턴스화(instantiate) : 클래스로부터 객체를 만드는 과정
- 인스턴스 : 어떤 클래스로부터 만들어진 객체
- 인스턴스는 객체와 동일한 의미지만 객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖으며 인스턴스는 어떤 클래스로부터 만들어진 것임을 강조하는 구체적인 의미를 가짐
객체의 구성요소 - 속성과 기능
객체의 구성요소
- 속성, 기능 두 종류
- 객체는 다수의 속성과 다수의 기능을 갖음
- 객체가 갖는 속성과 기능을 그 객체의 멤버라 함
- 속성(property) : 멤버 변수, 특성, 필드, 상태
- 기능(function) : 메서드, 함수, 행위
인스턴스의 생성과 사용
인스턴스 생성
클래스명 변수명;
변수명 = new 클래스명();
Tv t;
t = new TV();
1. TV t;
- TV클래스 타입의 참조변수 t를 선언
- 메모리에 참조변수 t를 위한 공간이 마련됨
- 아직 인스턴스가 생성되지 않았으므로 어떤 것도 할 수 없음
2. t = new Tv();
- 연산자 new에 의해 Tv 클래스의 인스턴스가 메모리의 빈 공간에 생성됨
- 멤버 변수는 각 자료형에 해당하는 기본값으로 초기화됨
- 대입연산자(=)에 의해 생선된 객체의 주소값이 참조변수 t에 저장됨
3. Tv t1 = new Tv(); Tv t2 = new Tv();
4. t2 = t1;
- t1에 저장되어 있던 주소가 t2에 저장됨
- t2가 참조하고 있던 인스턴스는 더 이상 사용될 수 없어서 gc에 의해 자동적으로 메모리에서 제거됨
5. t1.channel = 7;
- t1.channel 과 t2.channel의 값은 같음
- 둘 이상의 참조변수가 한 인스턴스를 참조하는 것은 가능하지만 하나의 참조변수로 여러개의 인스턴스를 가리키는 것은 불가능
객체 배열
객체배열이란?
- 객체를 배열로 다루는 것
- 객체가 저장되지 않고 객체의 주소가 저장된다.
Tv[] tvArr = new TV[3];
- 객체 배열을 생성하는 것은 그저 참조 변수들이 만들어진 것일 뿐 아직 객체가 저장된 것은 아님
- 따라서 초기화를 해줘야 함
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();
클래스의 또 다른 정의
클래스란
- 데이터와 함수의 결합
- 서로 관련된 변수를 정의하고 이들에 대한 작업을 수행하는 함수를 함께 정의한 것
사용자 정의 타입
- 프로그래밍언어에서 제공하는 자료형외에 프로그래머가 서로 관련된 변수들을 묶어서 하나의 타입으로 새로 추가하는 것
변수와 메서드
선언위치에 따른 변수의 종류
변수의 종류
- 멤버 변수 : 클래스 영역에 선언된 변수
- 클래스 변수 : static이 붙은 것
- 인스턴스 변수 : static이 안붙은 것
- 지역 변수 : 클래스 영역 외에 선언된 변수
1. 인스턴스 변수
- 클래스 영역에 선언됨
- 클래스의 인스턴스를 생성할 때 만들어짐
- 인스턴스를 먼저 생성한 후에 인스턴스 변수의 값을 읽어 오거나 저장할 수 있음
- 인스턴스마다 독립적인 저장공간을 가짐
2. 클래스 변수
- 인스턴스 변수 앞에 static을 붙인 것
- 모든 인스턴스가 공통된 저장공간을 공유하게 됨
- 인스턴스를 생성하지 않아도 바로 사용 가능
3. 지역변수
- 메서드 내에 선언되어 메서드 내에서만 사용 가능, 메서드가 종료되면 사용 불가
메서드
메서드란?
- 특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것
- 필요한 값을 넣고 원하는 결과를 얻기만 하면 되기에 내부 동작 과정을 몰라도 됨. 그래서 메서드를 내부가 보이지 않는 '블랙 박스'라고도 함
메서드의 사용 이유
- 높은 재사용성
- 중복된 코드의 제거
- 프로그램의 구조화
메서드의 선언과 구현
선언부
- 메서드 이름, 매개변수 선언, 반환타입으로 구성
- 작업을 위해 어떤 값들을 필요로 하고 작업의 결과로 어떤 값을 반환하는지에 대한 정보 제공
매개변수 선언
- 매개변수는 메서드가 작업을 수행할 때 필요한 값들을 제공받기 위함
- 변수 간의 구분은
,
를 사용
- 변수 타입 생략 불가능
메서드의 이름
- 변수의 명명규칙 대로 작성
- 이름만으로 메서드의 기능을 쉽게 알 수 있도록 함축적이고 의미있게 지어야 함
반환타입
구현부
- 선언부 다음에 오는
{}
- 메서드를 호출하면 수행되는 문장들
return 문
- 반환 타입이
void
가 아니면 구현부 안에 return 반환값
이 반드시 들어가야 함
- 단 하나의 값만 반환 가능
메서드의 호출
인자(argument)와 매개변수(parameter)
- 인자 : 메서드 호출 시 괄호 안에 지정해준 값
- 인자의 개수와 순서는 호출된 메서드에 선언된 매개변수와 일치해야 함
메서드 실행흐름
- 같은 클래스 내의 메서드끼리는 참조변수를 사용하지 않아도 호출 가능
- static메서드는 같은 클래스 내의 인스턴스 메서드 호출 불가능
매개변수의 유효성 검사
- 메서드 구현부 작성시 제일 먼저 매개변수의 값이 적절한 것인지 확인해야 함
JVM의 메모리 구조
응용 프로그램이 실행되면, JVM은 시스템으로부터 프로그램을 수행하는데 필요한 메모리를 할당받고 JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리함
1. 메서드 영역(method area)
- 프로그램 실행 중 어떤 클래스가 사용되면 JVM은 해당 클래스파일(*.class)을 읽어서 분석한 후 클래스에 대한 정보를 이곳에 저장
- 클래스의 클래스변수(class variable)도 이 영역에 함께 생성됨
2. 힙(heap)
- 인스턴스가 생성되는 공간
- 인스턴스 변수(instance variable)들이 생성됨
3. 호출 스택(call stack)
- 메서드의 작업에 필요한 메모리 공간 제공
- 메서드가 호출되면 호출 스택에 호출된 메서드를 위한 메모리가 스택에 할당됨
- 할당된 메모리는 메서드가 작업을 수행하는 동안 지역변수들과 연산의 중간결과등을 저장하고 메서드가 작업을 마치면 할당된 메모리 공간은 반환되어 비워짐
- 호출스택의 제일 위에 있는 메서드가 현재 실행 중인 메서드
- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드
기본형 매개변수와 참조형 매개변수
- 기본형 매개변수 : 변수의 값을 읽기만 가능 (read only)
- 참조형 매개변수 : 변수의 값을 읽고 변경 가능 (read & write)
예시
[실행 결과]
main() : x = 10
change() : x = 1000
After change(d.x)
main() : x = 10
[실행 결과]
main() : x = 10
change() : x = 1000
After change(d)
main() : x = 1000
재귀호출
재귀호출이란?
- 메서드 내부에서 메서드 자신을 호출하는 것
- 반복문보다 재귀호출의 수행시간이 더 오래 걸림
- 재귀호출에 드는 비용보다 재귀호출의 간결함이 주는 이득이 충분할 때만 사용해야 함
클래스 메서드와 인스턴스 메서드
인스턴스 메서드
- 인스턴스 메서드 : 인스턴스 변수와 관련된 작업을 하는 메서드
클래스 메서드
- 정의 : static이 붙은 메서드, 인스턴스와 관계없는 메서드
- 클래스 메서드는 인스턴스 변수를 사용할 수 없음. 클래스 메서드는 인스턴스 생성 없이 호출 가능하기에 클래스 메서드가 호출되었을 때 인스턴스가 존재하지 않을 수 있기 때문
- 반대로 인스턴스 변수나 인스턴스 메서드는 static 멤버를 사용하는 것이 가능
- 클래스 메서드는 호출시간이 짧아지므로 성능이 향상됨
오버로딩
정의
- 한 클래스 내에 같은 이름의 메서드가 매개변수의 개수와 타입이 다르게 정의된 것
조건
- 매서드 이름이 같아야 함
- 매개변수의 개수 또는 타입이 달라야 함
장점
- 이름만 보고 같은 기능을 하리라는 것을 짐작할 수 있음
가변인자와 오버로딩
- 메서드의 매개변수 개수를 동적으로 지정할 수 있는 것
타입... 변수명
과 같이 선언
- 가변인자 외에도 매개변수가 더 있으면 가변인자를 매개변수 중 제일 마지막에 선언해야 함
- 가변인자는 내부적으로 배열을 이용하기에 가변인자가 선언된 메서드를 호출할 때마다 배열이 새로 생성됨(비효율성 주의)
예시
생성자
생성자란?
- 생성자 : 인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드'
조건
- 생성자의 이름은 클래스의 이름과 같아야 한다.
- 생성자는 리턴 값이 없다.
인스턴스 생성 과정
Card c = new Card();
- 연산자 new에 의해 메모리(heap)에 Card클래스의 인스턴스가 생성된다
- 생성자 Card()가 호출되어 수행된다
- 연산자 new의 결과로, 생성된 Card 인스턴스의 주소가 반환되 참조변수 c에 저장됨
기본 생성자
- 클래스에 생성자가 정의되지 않으면 다음과 같은 컴파일러가 제공하는 '기본 생성자'로 인스턴스가 생성된다
클래스 이름 () {}
- 클래스에 이미 생성자가 존재하는 경우 기본 생성자는 자동적으로 제공되지 않는다
생성자에서 다른 생성자 호출하기
호출 조건
- 생성자의 이름으로 클래스 이름 대신 this를 사용
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능
예시
this
- this는 참조변수로 인스턴스 자신을 가리킴
- this를 통해 인스턴스 변수에 접근 가능
- this를 사용할 수 있는 것은 인스턴스 멤버뿐이다.(static 사용 불가)
생성자를 이용한 인스턴스 복사
Car(Car c) {
color = c.color;
gearType = c.gearType;
door = c.door;
}
- Java API의 많은 클래스들이 인스턴스의 복사를 위한 생성자를 정의하고 있다.
변수의 초기화
변수의 초기화
- 멤버변수는 초기화하지 않아도 되지만, 지역변수는 반드시 초기화해야 한다.
- 초기화 방법은 명시적 초기화, 생성자, 초기화 블럭이 있다.
명시적 초기화
- 정의 : 변수를 선언과 동시에 초기화 하는 것
초기화 블럭
- 클래스 초기화 블럭 : 인스턴스 초기화 블럭 앞에 static 붙이면 됨
- 인스턴스 초기화 블럭 : 인스턴스 변수의 복잡한 초기화에 사용됨