04 클래스와 객체 I

목차

    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 목차로 돌아가기

    '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