
절차 중심이 아닌 객체 중심으로 프로그래밍 하는 것
객체지향 언어는 절차지향과 다르게 순서와 과정을 중요하게 생각하지 않는다.
사람이 사고하는 방식을 그대로 프로그래밍에 적용한 것이며, 사람의 관점에서 프로그래밍 하기 때문에 이해하기 쉽고 각 기능들을 모듈화 하기 쉽다.
모듈화란 각 기능을 부품화 한다는 의미이며, 필요할 때마다 조립해서 사용할 수 있다.
객체의 속성과 동작을 추출한다. 객체가 가지고 있는 특성과 그 객체가 동작하는 방법을 나열한다.
이 객체의 속성은 개발자가 아닌, 일반인(주체)의 입장에서 각 객체의 속성과 동작을 추출한다.
예를 들어 랜터카 회사에 대한 객체가 있다고 가정하자.
| 속성 | 동작 |
|---|---|
| 이름, 나이, 직급 | 빌려준다, 예약을 확인한다, 차량을 관리한다 |
| 속성 | 동작 |
|---|---|
| 이름, 주소, 나이, 전화번호 | 예약한다, 사용한다, 지불한다 |
프로그래밍에 필요하지 않는 속성이나 동작은 배제하고, 실제 객체 추출에서는 파악되지 않았지만 프로그래밍시에는 필요한 속성이나 동작이 있다면 추출한다.
객체 추출 단계에서 만든 속성과 동작이 모두 실제 프로그래밍에 사용되는 것은 아니기 떄문에 객체 모델링 단계에서는 실제 프로그래밍에 필요한 속성과 동작을 정제한다.
위의 예시를 그대로 가져온다면 아래와 같다
| 속성 | 동작 |
|---|---|
| 이름, 직급 | 빌려준다, 예약을 확인한다 |
| 속성 | 동작 |
|---|---|
| 이름, 주소, 전화번호, 아이디, 비밀번호 | 예약한다, 사용한다, 지불한다 |
객체 모델링을 통해 추출된 객체를 자바 클래스로 변환하는 것
클래스 UML 표기법을 이용한다. 이는 분석, 설계시에 작업한 결과물을 문서화 할 때 사용하는 일종의 표기법이다.
+ : public# : protected- : private| UML | |
|---|---|
| Student (클래스 명) | |
| - name : String | - address : String (변수명 : type) |
| + Study() : String | + getTest() : String (method1() : return type) |
이때 객체명은 클래스명으로 변환, 속성은 맴버 변수로 변환, 동작은 매서드로 변환된다.
멤버 변수는 객체 모델링에서 추출한 속성을 클래스에서 표현하는 변수이며, 맴버 필드, 인스턴스 변수, 속성 이라고도 한다.
일반적으로 접근지정자와 일반지정자를 조합하여 사용한다.
[접근 지정자] [일반 지정자] 데이터 형 변수
위에 있는 UML을 기준으로 클래스를 하나 만들어보겠다.
package com.chapter5;
public class ExStudent {
private String name;
private String address;
public void study(){
System.out.println("공부를 합니다.");
}
public String getText(String score){
return score;
}
}
아래는 getter, setter메서드를 적용한 Student 클래스이다.
package com.chapter5;
public class ExStudent {
private String name;
private String address;
public String getName(){
return name;
}
public String getAddress(){
return address;
}
public void setName(String _name){
name = _name;
}
public void setAddress(String _address){
address = _address;
}
}
멤버 변수의 접근지정자가 private이므로 직접 접근이 불가능 하나, getter, setter메서드는 public이므로 호출할 수 있다.
정의한 클래스를 이용하여 컴퓨터의 메모리에 클래스의 속성과 기능을 가지는 객체
클래스는 일종의 설계도 또는 명세서와 같은 의미이다. 우리는 클래스 자체를 사용할 수 없다. 우리가 클래스를 실제로 사용하기 위해서는 클래스 내에 있는 변수와 메서드를 실제로 메모리에 생성해야 한다. 실제 클래스가 메모리에 생성된 상태를 클래스 인스턴스 또는 클래스 객체 라고 한다.
앞서 만든 Student클래스 인스턴스를 생성하는 방법을 보인다.
Student s;
s = new Student();
// 생성된 인스턴스는 같은 클래스 타입 참조 변수에 할당해야 한다.
객체 지향 프로그래밍에서 분석, 설계 과정을 거쳐 클래스를 만들었으면 최종적으로 각 클래스의 기능을 조립하여 하나의 완성된 기능을 하는 프로그램을 구현하는 컨베이어 벨트와 같은 기능을하는 실행클래스라는 개념이 필요하다.
실행 클래스는 각 기능을 하는 클래스들의 인스턴스를 생성한 뒤, 각 클래스 인스턴스를 초기화하고, 각 클래스 인스턴스로 원하는 작업을 하여 최종 결과를 만들어낸다. 따라서 실행 클래스에는 반드시 프로그램의 시작점 역할을 하는 main메서드가 존재해야 한다.
import com.chapter5.ExStudent;
public class Main {
public static void main(String[] args) {
ExStudent s;
s = new ExStudent();
s.setName("이순신");
String name = s.getName();
System.out.println("학생 이름은 "+name);
}
}
[[3. 자바 명령문과 배열#배열 (array)|배열]]의 요소의 총 합과 평균을 구하는 기능과 배열의 요소의 값을 오름차순으로 출력해주는 기능을 하는 클래스 구현
UML 구현
| UML | |
|---|---|
| ArrayTest | |
| - arr : int [] | |
| + arrSum() : int | +arrAvg() : int |
//Main.java
import com.chapter4.practice;
import com.chapter5.ExArrayUtil;
public class Main {
public static void main(String[] args) {
ExArrayUtil util;
util = new ExArrayUtil();
int[] arr = {1,2,3,4,5};
util.setArray(arr);
System.out.println(util.arrSum());
System.out.println(util.arrAvg());
}
}
//ExArrayUtil.java
package com.chapter5;
public class ExArrayUtil {
private int[] ar;
public void setArray(int[] changedArray){
ar = changedArray;
}
public int[] getArray(){
return ar;
}
public int arrSum(){
int s = 0;
for(int i = 0; i < ar.length; i++){
s += ar[i];
}
return s;
}
public float arrAvg() {
int avg = this.arrSum() / ar.length;
return avg;
}
}
이때 getter를 사용해 배열을 출력할때는 아래와 같이 사용한다.
System.out.println(util.getarray().toString())
클래스가 객체 생성될 때 맨 처음 호출되는 것
반드시 클래스 명과 동일 해야 함.
생성자는 메모리에 크랠스 인스턴스를 생성시킬 때나 인스턴스 생성 시 인스턴스 변수를 초기화 하는 용도로 사용된다.
생성자에는 클래스 명을 반드시 써주어야 하고, 앞에 [[4. 클래스 기본#지정자|접근 지정자]]를 지정해주어야 하며, 매개 변수도 지정해주어야 한다.
[접근 지정자] 클래스 명 ([매개 변수]){
// 인스턴스 변수 초기화
// 명령문
}
생성자의 형식은 메서드와 비슷하나 리턴 타입이 없다. 또한 사용자가 생성자를 만들어주지 않으면 자동으로 컴파일 시 디폴트 생성자를 추가한다.
앞선 Student클래스에 생성자를 추가해본다.
package com.chapter5;
public class ExStudent {
private String name;
private String address;
public ExStudent(String _name){
name = _name;
}
public ExStudent(){
}
public String getName(){
return name;
}
public String getAddress(){
return address;
}
public void setName(String _name){
name = _name;
}
public void setAddress(String _address){
address = _address;
}
}
나중에 나올 개념인 것 같은데 생성자 오버로딩을 통해 만약 이름이 주어져 인스턴스가 생성된다면 첫번째 생성자를 그렇지 않다면 두번째 디폴트 생성자를 호출하여 초기화 한다.
//main.java
ExStudent std1, std2;
std1 = new ExStudent("홍길동");
std2 = new ExStudent;
사용자 지정 생성자를 만든 경우 디폴트 생성자를 따로 만들어주지 않으므로, 습관적으로 디폴트 생성자를 만들어주는 습관이 필요함.
생성자를 여러개 만드는 방법을 생성자 오버로딩이라고 하며 사용 이유는 다음과 같다.
생성자 오버로딩을 할 때는 각 매개변수의 개수, 타입, 순서를 다르게 하여 사용해야 한다.
생성자 오버로딩과 마찬가지로 같은 클래스 내에 동일한 이름의 메서드가 여러개 존재하는 것을 의미한다.
반드시 메서드 매개변수 형식이 달라야하며, 리턴타입은 달라도 상관없다.
public class ClassUtil{
public void get(){...}
public void get(int n){...}
public int get(String n, int a){...}
}
같은 기능을 하는 클래스들을 모아놓은 그룹
package pack;
package test1, test2;
각 회사에서 사용하는 도메인 이름을 역순으로 배열하여 사용하고 있다.(역도메인 명명법)
예를 들어 jweb.com이라는 회사에서 어떤 프로그램을 패키지로 개발한다고 하면 아래와 같을 것이다.
패키지명.프로젝트명.기능명.클래스명
# com.jweb.prjname.member.MemWindow
패키지가 다른 클래스에 접근할 때 사용한다.
import package_name.class_name;
import package_name *;