목차
04 클래스와 객체 I
4.1 객체 지향 프로그래밍이란?
- 객체를 사용하는 프로그래밍 방식을 객체 지향 프로그래밍(OOP: Object-Oriented Programming)이라고 한다.
- OOP는 우리가 사는 실세계와 비슷하게 소프트웨어도 작성해보자는 방법론
- 객체들은 객체 나름대로의 고유한기능을 수행하면서 다른 객체들과 상호 작용한다.
- 소프트웨어 개발에서 OOP는 다양한 기능을 하는 소프트웨어 객체들을 조합하여 자기가 원하는 기능을 구현하는 기법
객체
- 객체의 상태 : 객체의 속성
- 객체의 동작 : 객체가 취할 수 있는 동작
- 필드 : 객체 안의 변수
- 메소드 : 객체 안의 함수
- 객체는 필드와 메소드로 이루어져 있는 소프트웨어의 묶음
프로그래밍 기법의 발전
- 어셈블리 → 절차 지향 → 객체 지향 → 함수형
- 절차 지향 프로그래밍에서 어떤 문제점이 있어서 객체 지향 프로그래밍으로 발전되었는지는 더 경험해야 알 수 있음
절차 지향 프로그래밍
- 프로그래밍 패러다임에서 보면 명령형 프로그래밍에 속하는 방법
- 프로시저(procedure)에 기반을 두고 있다.
- 프로그램은 함수(프로시저)들의 집합으로 이루어진다.
- 하향식 설계 : 복잡한 문제를 점점 더 작은 문제로 분해하는 방법
- 문제점 : 가장 중요한 단점이 데이터가 함수와 분리된다는 점
(절차 지향 언어에서는 변수와 함수를 묶을 방법 자체가 아예 없다.)
객체 지향이 나오게 된 동기
- 기존에는 이미 작성된 수많은 함수와 코드들을 재활용하는 것이 어렵기 때문에, 항상 처음부터 프로그램을 다시 작성
- 객체 지향으로 소프트웨어를 작성 하면 컴퓨터 하드웨어를 조립 하듯,
부품 하나하나들 한 업체에서 만들지 않고 다른 업체의 부품을 조립하여 사용할 수 있다.
객체 지향 프로그래밍
- 연구가 진행될수록 관련 있는 함수와 데이터를 묶어서 생각해야 한다는 점이 명확해짐
- 캡슐화 : 데이터와 함수를 하나의 덩어리로 묶는 것
절차 지향 vs 객체 지향
- 예시 : 자율 주행 애플리케이션
- 절차 지향 : 자동차가 주행하거나 멈추는 등의 함수를 작성하는게 중요
- 객체 지향 : 자동차나 보행자, 신호등 등의 정보가 중심이 되어 객체가 생성되고 이들이 상호작용하면서 프로그램 수행됨
객체 지향 프로그래밍의 특징
캡슐화
- 객체가 하나의 캡슐
- 목적 : 서로 관련된 데이터와 알고리즘을 캡슐에 넣어서 보호한다
정보 은닉
- 객체의 외부에서는 객체의 내부 데이터를 볼 수 없게 한다는 의미
- 객체 안의 데이터와 알고리즘은 외부에서 변경하지 못하게 막고, 공개된 인터페이스를 통해서만 객체에 접근하도록 하는 개념
- 외부 객체는 객체의 내부 데이터 값에 직접 접근할 수 없으므로, 메소드를 통해 간접적으로 값을 전달받아야 한다.
- 예시) 도서관의 2가지 형태
- 개가식 도서관 : 방문자가 직접 책을 찾음 → 찾는게 힘들고, 반납시 엉뚱한 곳에 두면 내부 데이터가 망가짐
- 폐가식 도서관 : 도서관을 관리하는 사서가 있음 → 사서가 책을 찾아 주고 정리하기때문에 안전
- 메소드는 위의 예시에서의 사서 역할을 한다
상속
- 이미 작성된 클래스(부모 클래스)를 이어받아서 새로운 클래스(자식 클래스)를 생성하는 것.
- 부모 클래스를 이용하여 공통적인 속성과 동작을 정의.
- 자식 클래스는 부모 클래스의 모든 속성과 동작을 물려받는다.
- 클래스를 상속받아 자신이 필요한 부분을 변경하여 사용할 수 있다.
다형성
- 동일한 이름의 동작이라고 하여도 객체의 실제 타입에 따라서 동작의 내용이 달라질 수 있다는 것을 의미
추상화
- 불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 프로그램을 간단히 만드는 기법
4.2 클래스와 객체 만들기
클래스란?
- 클래스 : 객체에 대한 설계도. 특정한 종류의 객체들을 찍어내는 형틀(templet) 또는 청사진(blueprint)
- 인스턴스 : 클래스로부터 만들어지는 각각의 객체
클래스 작성
- 클래스는 변수와 함수를 동시에 가지고 있다.
- 클래스 안에 필드와 메소드들을 정의. 이들을 멤버라고 한다.
객체 생성
- 클래스는 객체가 아니고 설계도의 개념이니 설계도를 가지고 어떤 작업을 할 수는 없다.
- 작업을 하려면 객첼르 생성해야함
참조 변수
- 객체를 참조할 때 사용되는 변수. 객체의 참조값(일반적으로 객체의 주소)이 저장됨.
💡 주의할 것 💡
프로그래밍 시 많이 혼동 하는 부분이 선언만 하면 객체가 생성된다고 생각하는 것.
객체를 참조하는 변수를 선언만 하면 단순히 객체의 이름만 정해놓은 것이고,
new 연산자를 이용해야만 비로소 생성된다.
4.3 생성자와 메소드 오버로딩
메소드 오버로딩
- 메소드 오버로딩(중복정의) : 같은 이름의 메소드가 여러 개 존재함
- 다형성을 구현하는 한 가지 방법
- 메소드의 매개 변수로 구별. 따라서 반드시 매개 변수를 서로 다르게 하여야 한다.
- 장점 : 같은 역할을 하는 메소드의 이름을 중복해서 사용할 수 있음
생성자
- 객체가 생성될 때 객체를 초기화하는 특수한 메소드
- 생성자의 이름 = 클래스의 이름
- 반환값을 가지지 않는다. void도 x
- 주로 초기값을 부여할 때 많이 사용되지만 특별한 초기화 절차를 수행할 수도 있다.
기본 생성자
- 매개 변수가 없는 생성자
- 생성자를 하나도 정의하지 않으면 자바 컴파일러가 자동으로 만듬
기본 생성자가 추가되지 않는 경우
- 생성자를 하나라도 정의 했을 경우
this 참조 변수
- this는 현재 객체 자신을 가리키는 참조 변수.
- 생성자에서 매개 변수 이름과 필드 이름이 동일한 경우에 혼동을 막기 위해서 사용.
- 예시) this.radius는 현재 객체가 가지고 있는 필드 radius
this()
- 다른 생성자
- 주로 가장 복잡한생성자를 먼저 작성한 후에, 호출함
this() 사용 시 주의 사항
- 반드시 생성자 안에서만 호출
- 반드시 첫 번째 문장
- 다른 생성자를 호출할 때만 사용
4.4 접근 제어
접근 제어란?
- 클래스의 멤버에 접근하는 것을 제어하는 것.
- 객체를 잘못 사용하는 것을 방지
자바의 접근 제어 지정자
접근 지정자 | 해당 클래스 안 | 패키지 | 자식 클래스 | 전체 |
public | O | O | O | O |
protected | O | O | O | X |
default | O | O | X | X |
private | O | X | X | X |
💡 접근 제어를 선택하는 팁
• 일반적으로 특별한 이유가 없으면 가장 엄격한 접근 제어
• 상수를 제외하고는 필드에 public 사용 x / 외부 클래스가 필드를 자유롭게 변경하면 코드 변경이 힘듦
접근자와 설정자
- 정보 은닉 : 구현의 세부 사항을 클래스 안에 감추는 것
- 클래스 안에 변수를 선언할 때는 private을 붙이는 것이 좋다.
- 클래스 안에 저장된 필드 값이 꼭 필요한 경우 : getter(접근자) setter(설정자) 메소드 사용
접근자와 설정자를 사용하는 이유
- 접근자와 설정자를 사용해야만 나중에 클래스를 업그레이드할 때 편하다.
- 접근자에서 매개 변수를 통하여 잘못된 값이 넘어오는 경우, 이를 사전에 차단할 수 있다.
- 필요할 때마다 필드값을 동적으로 계산하여 반환할 수 있다.
- 접근자만을 제공하면 자동적으로 읽기만 가능한 필드를 만들 수 있다.
4.5 무엇을 클래스로 만들어야 할까?
요구 사항 문서
- 어떤 회사가 시스템 개발을 의뢰할 때 작업 명세서를 보냄
- 작업 명세서를 바탕으로 요구 사항 문서를 작성
- 요구 사항 문서는 최종 제품에 대한 사용자 요구를 나타낼 수 있을 만큼 구체적이어야 함.
설계 그룹이 이 문서를 사용하여 설계 단계를 진행할 수 있도록 구체적인 세부 정보를 제공해야 함.
클래스 식별
- 요구 사항이 문서화되면 클래스 식별 과정을 시작할 수 있다.
- 이때, 일단 모든 명사를 클래스 후보로 설정
- 이후, 반드시 필요한 클래스만을 선별
- 예를 들어, 한 단어가 다른 단어의 별칭인 경우 ("아이디" "id")
한 단어가 다른 단어의 속성인 경우(계좌 번호는 계좌의 속성)
한 단어가 다른 클래스의 인스턴스인 경우
클래스의 속성 결정
- 클래스가 저장해야하는 데이터를 결정
클래스의 동작(책임) 결정
- 클래스가 수행해야 하는 작업을 식별
- 요구 사항 문서에서 동사에 대한 하는 부분이 많음
- 데이터 구조나 알고리즘에 대한 것은 세부 설계 단계까지 남겨두는 것이 좋다.
클래스 간의 관계를 결정한다.
- 대부분의 클래스는 단독으로 존재하지 않고, 다른 클래스와 상호 작용해야 하는 경우가 많다.
- 가장 중요한 결정은 상속, 구성
UML
- 객체 지향 프로그래밍에서도 프로그래머들은 애플리케이션을 구성하는 클래스들 간의 관계를 그리기 위하여 클래스 다이어그램을 사용한다.
- UML : 가장 대표적인 클래스 다이어그램 표기법
Unified Modeling Language - UML이 클래스만을 그리는 도구는 아니고 객체 지향 설계 시에 사용되는 일반적인 모델링언어이다.
- UML을 사용하면 소프트웨어를 본격적으로 작성하기 전에 구현하고자 하는 시스템을 시각화하여 검토 할 수 있다.
UML은 Rational software의 Grady Booch, Ivar Jacobson, James Rumbaugh에 의하여 1994~1995년에 걸쳐서 첫 번째 버전이 완성되었다. 1997년에 Object Management Group(OMG)에 의하여 표준으로 채택되었다. 2005년에는 International Organization for Standardization(ISO)에 의하여 ISO 표준으로 채택되었다.
- UML의 구성 요소에는 클래스 다이어그램, 객체 다이어그램, 상태 다이어그램, 시퀀스 다이어그램 등과 같은 많은 다이어그램이 있다.
- 클래스 다이어 그램에서 각 클래스는 사각형으로 그려지고 그 사각형은 세부분으로 나누어져 있다
car |
-speed:int -gear:int -color:String |
+speedUp():void +speedDown():void |
- 필드나 메소드의 이름 앞에는 가시성 표시자가 올 수 있다.
+ | Public |
- | Private |
# | Protected |
/ | Derived |
~ | Package |
- 클래스 다이어그램에서는 화살표를 사용하여 클래스 간의 관계를 나타낼 수 있다.
관계 | 화살표 |
일반화, 상속 | ㅡㅡㅡㅡ▷ |
구현 | - - - - - - -▷ |
구성관계 | ㅡㅡㅡㅡ◆ |
집합관계 | ㅡㅡㅡㅡ◇ |
유향 연관 | ㅡㅡㅡㅡ> |
양방향 연관 | ㅡㅡㅡㅡㅡ |
의존 | - - - - - - -> |
의존 관계
- 점선의 열린 화살표
- 하나의 클래스가 다른 클래스를 사용하는 관계
Mini Project 주사위 게임
주사위 2개를 생성하여 1,1이 나올때까지 반복하여 굴리기
package basic.practice;
public class DiceTest {
public static void main(String[] args) {
Dice dice1 = new Dice("주사위1");
Dice dice2 = new Dice("주사위2");
int count = 0;
while (true) {
count++;
dice1.roll();
dice2.roll();
System.out.println();
if (2 == dice1.getValue() + dice2.getValue()) {
System.out.println("(1, 1)이 나오는데 걸린 횟수= " + count);
break;
}
}
}
}
결과
주사위1= 5 주사위2= 5
주사위1= 5 주사위2= 3
주사위1= 1 주사위2= 5
주사위1= 5 주사위2= 2
주사위1= 5 주사위2= 4
주사위1= 3 주사위2= 6
주사위1= 6 주사위2= 5
주사위1= 2 주사위2= 1
주사위1= 3 주사위2= 2
주사위1= 5 주사위2= 6
주사위1= 2 주사위2= 1
주사위1= 5 주사위2= 1
주사위1= 3 주사위2= 2
주사위1= 5 주사위2= 4
주사위1= 4 주사위2= 5
주사위1= 2 주사위2= 1
주사위1= 5 주사위2= 6
주사위1= 4 주사위2= 4
주사위1= 2 주사위2= 5
주사위1= 2 주사위2= 4
주사위1= 4 주사위2= 2
주사위1= 3 주사위2= 6
주사위1= 5 주사위2= 3
주사위1= 2 주사위2= 2
주사위1= 2 주사위2= 3
주사위1= 1 주사위2= 1
(1, 1)이 나오는데 걸린 횟수= 26
Summary
- 객체 지향 방법은 실세계가 객체로 구성되어 있는 것처럼 소프트웨어도 객체로 구성하는 방법론.
- 절차 지향은 함수를 사용하여 프로그램을 작성하는 방법. 함수를 재사용하기가 어렵다.
- 객체 지향을 이루고 있는 핵심적인 개념에는 "캡슐화", "상속", "다형성", "추상화" 등이 있다.
- 캡슐화는 객체의 속성과 동작을 하나로 묶는 것을 의미한다. 내부 구현을 알 수 없게 은닉하는 것도 캡슐화에 포함.
- 상속은 다른 클래스를 재사용하는 강력한 방법.
- 객체는 속성과 동작으로 정의된다. 프로그램에서는 속성은 필드로, 동작은 메소드로 구현된다.
- 클래스는 필드와 메소드로 구성된다.
- 자바에서는 new를 사용하여 객체를 생성한다.
- 객체를 생성하기 전에 반드시 객체를 참조하는 변수를 먼저 선언하여야 한다.
- 메소드 오버로딩이란 이름은 동일하지만 매개 변수가 다른 메소드를 여러 개 정의하는 것이다.
- 생성자는 객체가 생성될 때, 초기화 작업을 담당하는 특별한 메소드이다.
- this는 현재 객체를 가리키는 참조 변수이다.
- this()는 생성자에서 다른 생성자를 호출할 때 사용된다.
- 접근 제어란 외부에서 내부 구현을 알 수 없게끔 감추는 것.
'Java > 교재 정리' 카테고리의 다른 글
06 상속 (1) | 2024.04.23 |
---|---|
05 클래스와 객체 II (0) | 2024.04.18 |
03 조건문, 반복문, 배열 (0) | 2024.04.14 |
02 자바 프로그래밍 기초 (0) | 2024.04.12 |
01 자바 소개와 개발도구 설치 (0) | 2024.04.11 |