객체 지향 프로그래밍 (OOP)
객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"
들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다.
객체(Object) : 모델링(설계) 관점에서 실세계에 존재하는 모든 유형 및 무형의 사물을 말한다.
클래스 (Class)
• 클래스는 실세계를 구성하고 있는 객체(object)를 구현하기 위해 정의하는 템플릿(template) 이다.
• 실세계의 객체를 클래스로 정의하고 클래스로 인스턴스를 생성하는 것이다.
클래스 선언
인스턴스 생성
자동차를 구현한 클래스와 인스턴스 생성을 해보자.
• Car라는 자동차를 만들 수 있는 클래스와 Car를 사용할 수 있는 CarTest라는 클래스를 만든다.
(이러한 관계를 디펜던스 관계라 한다.)
• 인스턴스가 생성되면 인스턴스 정보는 힙(Heap) 영역에서 관리한다.
메모리 구조
• Class Loader : Class라는 바이트 코드를 메모리로 읽어들이게 한다.
• Runtime Data Area : JVM이 OS(운영체제)로 부터 할당받은 메모리 영역이다.
• Method Area : Class 와 Interface 의 자바 바이트 코드 및 메타 데이터가 저장된다.
(메타데이터: 데이터에 대한 정보를 가지고 있는 데이터)
• Heap Area
1. new 명령어로 생성된 인스턴스가 저장되는 영역
2. Garbage Collection 의 대상이 되는 영역(C++같은 경우는 개발자가 메모리 관리를 해야하지만,
자바는 Garbage Collection이 알아서 관리한다.)
• Stack Area : 메소드 내에 사용되는 값들(매개변수, 로컬(지역)변수, 리턴값 등)이 저장되는 영역
Stack & Heap 영역에 대한 예제
• car1은 로컬(지역)변수니까 stack에 공간이 확보되고, Car클래스 안에 있는 변수는 인스턴스 변수니까 자동차이름,
색상, 방향, 속도 등의 정보를 가리키는 주소값을 가지고 관리한다.
• car1이 Car클래스 내에 있는 name 변수를 참조하기 위한 코드는 car1.name 이라는 코드로 참조할 수 있다.
(마찬가지로, car1.color, car1.direction, car1.speed 라는 코드로 데이터를 참조할 수 있다.)
1. car1의 인스턴스를 생성한다.
2. car1의 주소, 자동차 이름, 색상, 방향, 속도 등의 초기값을 확인한다.
1. 클래스타입 Car로 생성된 인스턴스 변수 car1.으로 인스턴스 변수 값을 초기화한다.
2. 초기화된 car1의 인스턴스 정보를 확인한다.
클래스 구성 멤버
클래스에는 객체가 가져야 할 구성 멤버가 선언됩니다. 구성 멤버에는 필드(Field), 생성자(Constructor),
메서드(Method)가 있습니다. 이 구성 멤버들은 생략되거나 복수 개가 작성될 수 있습니다.
필드 (field)
• 클래스에 선언된 인스턴스 변수(variable)를 필드라고 한다.
• 클래스 내에서 필드는 선언된 위치에 따라 다음과 같이 구분된다.
• 클래스 변수(static variable) ;
1. static 키워드를 갖는다.
2. 클래스 변수는 인스턴스를 생성하지 않고도 바로 사용할 수 있다.
3. 클래스 변수는 해당 클래스의 모든 인스턴스가 공유해야 하는 값을 유지하기 위해 사용된다.
• 인스턴스 변수(instance variable)
1. new 로 인스턴스를 생성한다.
2. 인스턴스마다 고유한 값을 유지하기 위해 사용된다.
• 지역 변수(local variable) : 메소드 안에 정의된 변수
생성자 메소드 (Constructor)
생성자 메소드가 필요한 이유?
• 생성자 메소드를 통해 필드에 초기화를 하고 다시 의미있는 값으로 초기화(위와같이 일일히
바꿔주지않아도 된다.)
• new 연산자를 통해 객체(인스턴스)가 생성될 때 인스턴스 변수를 초기화하기 위해 단 한번만 호출되는 메소드이다.
• 생성자 메소드 이름은 클래스 이름과 반드시 동일해야 한다.
• 생성자 메소드는 여러 개 작성 가능하다. (메소드 오버로딩이라고 한다.)
• 생성자는 리턴 타입을 지정할 수 없다.
• 개발자가 생성자를 작성하지 않았으면 컴파일러가 자동으로 기본 생성자 삽입한다.
** 메소드 오버로딩 : 한 클래스 내에 같은 이름의 메소드를 중첩하여 정의하는 것을 말한다.
(조건 : 매개변수의 개수가 다르거나, 매개변수의 타입이 달라야한다.)
• 위 그림은 매개변수가 있는 생성마 메소드이다.
• 생성자 메소드는 이클립스에서 단축키 Alt + Shift + s 를 사용하여 생성할 수 있다.
[생성자 예제] 인스턴스를 생성하면서 매개변수를 생성하여 생성자 메소드를 통해 인자값을 전달하고 전달된 인자값은 인스턴스 변수에 저장된다.
• 위 그림으로부터 알 수 있는 사실은 인스턴스를 생성할 때마다 힙(Heap) 영역에 새로운 공간이 할당된다는 것이다.
(각 인스턴스는 주소가 서로 다르다.)
• Car 클래스를 데이터 타입으로 하는 변수 car1과 car2의 인스턴스 정보를 출력해보았다.
메소드 (Method)
• 중복되는 코드의 반복적인 프로그래밍을 피할 수 있고, 모듈화로 인해 코드의 가독성도 좋아진다.
• 메소드를 작성할 때는 되도록 하나의 메소드가 하나의 기능만을 수행하도록 작성하는 것이 좋다. (응집도가 높다.)
• 하나의 메소드 안에는 하나의 기능만 만들어야한다.(재사용성)
메소드 선언
1. 접근 제어자 : 해당 메소드에 접근할 수 있는 범위를 명시한다.
2. 리턴타입 : 메소드가 모든 작업을 마치고 반환(return)하는 자료형을 명시한다.
(단, 리턴값이 없는 경우 void 를 지정한다.)
3. 메소드 이름 : 메소드를 호출하기 위한 이름을 명시한다. (첫글자는 소문자를 원칙으로한다.)
4. 매개변수 목록 (parameterlist) : 메소드 호출 시에 전달되는 인수의 값을 저장할 변수들을 명시한다.
메소드 호출
• 메소드명( ); // 매개변수가 없는 메소드 호출 메소드명( 값 1, 값 2, ...); // Arguments List(인자 목록)
메소드 구분
• 클래스 메소드(static method) : static 키워드를 갖는다.
• 인스턴스 메소드(instance method)
1. 클래스 메소드는 클래스 변수와 마찬가지로 인스턴스를 생성하지 않고도 바로 사용할 수 있다.
2. 클래스 메소드는 메소드 내부에서 인스턴스 변수를 사용할 수 없다.
[Method 생성 예제1] 두 정수 합계를 구하는 메소드 생성
1. main 메소드에 메소드 add를 통해 두 정수의 인자 값을 전달할 클래스 메소드 add를 생성한다.
2. 전달 받은 두 정수의 매개변수를 산술연산하여 return(반환)한다.
3. 반환되어 전달된 값을 int형 변수 result에 저장한다.
4. 변수 result의 값을 출력한다.
[Method 생성 예제2] 두 실수의 합계를 구하는 메소드 생성
1. main 메소드에 메소드 add를 통해 두 실수의 인자 값을 전달할 클래스 메소드 add를 생성한다.
2. 전달 받은 두 실수의 매개변수를 산술연산하여 return(반환)한다.
3. 반환되어 전달된 값을 double형 변수 result에 저장한다.
4. 변수 result의 값을 소수둘째짜리까지 출력한다.
[Method 생성 예제3] char형 문자를 매개인자로 전달하여 그에 맞는 문자열 반환하는 메소드 생성
1. 'M'이라는 문자를 받아올 수 있는 char형 타입의 하나의 매개변수를 가진 getGender 메소드를 생성한다.
2. "남자" 또는 "여자"라는 String 클래스 타입의 문자열을 리턴하기때문에 리턴타입은 String 클래스이다.
3. getGender 메소드에서 return(반환)되어 값이 호출부로 전달된다.
4. 전달된 문자열을 받을 String 클래스 타입 변수 result에 저장한다.
5. 변수 result의 값을 출력한다.
[Method 생성 예제4] 숫자(정수)가 홀수인지 짝수인지 반환하는 메소드 정의(isEven)
1. main 메소드에 넘겨줄 인자값이 1개이기때문에 isEven 메소드의 매개변수는 하나이다.
2. 10이라는 인자값이 넘어와서 조건식을 통해 boolean형으로 반환해야하기때문에 리턴타입은 boolean으로 한다.
3. 조건이 true인 경우 짝수입니다.를 반환하도록 조건이 참일 때 return true;로 반환하도록하고 반대로 거짓일 때,
return false;를 반환한다.
4. main 메소드에서 isEven 메소드 호출로 넘어온 인자값(true or false)에 의해 출력이 된다.
[Method 생성 예제5] 두 정수형 데이터가 같은 경우 true, 그렇지 않은 경우 false를 반환하는 메소드 정의
1. main 메소드에서 넘겨줄 인자값이 2개이기때문에 equalsInt 메소드의 매개변수는 두개이다.
2. 10과 10 두 정수 인자값이 넘어와서 조건식을 통해 boolean형으로 반환해야하기때문에 리턴타입은 boolean으로 한다.
3. 두 정수가 같으면 true, 그렇지 않으면 false가 나오도록 조건식을 만든다.
4. main 메소드에서 equalsInt 메소드 호출로 넘어온 인자값(true or false)에 의해 출력이 된다.
[Method 생성 예제6] main 메소드에서 메소드를 호출하고, 매개변수의 인자값을 전달하여 메소드에서 바로 출력한다.
1. main 메소드에서 넘겨줄 인자값이 1개이기때문에 hello 메소드의 매개변수는 1개이다.
2. "일길동"이라는 문자열 인자값이 넘어와서 데이터를 다시 넘겨주지 않아도 되기때문에 리턴타입은 void로 한다.
3. 매개변수로 전달된 문자열을 출력문에 추가되어 출력된다.
4. hello 메소드에서 출력된 문자열은 main 메소드로 넘어오고 프로그램이 종료된다.
** main 메소드도 어떠한 값을 반환하지 않아도 되기때문에 리턴타입을 void로 한다.
[Method 생성 예제7] 두 정수의 몫을 출력하는 메소드
1. main 메소드에서 넘겨줄 인자값이 2개이기때문에 divide 메소드의 매개변수는 2개이다.
2. 10과 5 두 정수 인자값이 넘어와서 데이터를 다시 넘겨주지 않아도 되기때문에 리턴타입은 void로 한다.
3. divide 메소드에서 출력된 문자열은 main 메소드로 넘어오고 프로그램이 종료된다.
[Method 생성 예제8] 두 정수의 몫을 구하는 메소드 예외처리
1. 첫번째 그림의 에러는 두 정수의 몫을 구하기 위해 매개변수의 인자값을 전달한다. 여기에서 num2의 값이 0일 때,
예외가 발생한다.
2. 예외처리를 하기위해 조건문을 만들어서 num2의 값이 0일 때 return;(프로그램 종료) 한다.