[Java 기본]Section 3 - 객체 지향 프로그래밍

우영·2024년 1월 30일

JAVA 기본편

목록 보기
3/13

단축키
ctrl + D = 한 줄 복사
ctrl + shift + enter = ;붙여주고 완성 단축키
ctrl + n -> 파일 찾기
ctrl + E + enter -> 이전 파일로 돌아가기
ctrl + space = 코드 완성 (Scanner치고 한칸 띄우고 단축키 누르면 scanner가 자동 완성됨)
shift + F6 = 변수명 한번에 바꾸기
ctrl + shift + / = 구간 주석 지정
iter : for- each문 생성
sout : system.out.println
ctrl + alt + v : 반환값 자동으로 처리

절차 지향 프로그래밍, 객체 지향 프로그래밍

절차 지향 프로그래밍 vs 객체 지향 프로그래밍

  • 절차 지향 프로그래밍
    : 프로그램의 흐름을 순차적으로 따르며 처리하는 방식. 즉 "어떻게"를 중심으로 프로그래밍 한다.

  • 객체 지향 프로그래밍
    : 실제 세계의 사물이나 사건을 객체로 보고, 이러한 객체들 간의 상호작용을 중심으로 프로그래밍하는 방식이다. 즉 "무엇을" 중심으로 프로그래밍 한다.

차이점
절차 지향은 데이터와 해당 데이터에 대한 처리방식이 분리되어 있다. 반면 객체 지향에서는 데이터와 그 데이터에 대한 행동(메서드)이 하나의 "객체" 안에 함께 포함되어 있다.

음악 플레이어 만들기

package oop1;

public class MusicPlayerMain1 {

    public static void main(String[] args) {

        int volumn = 0;
        boolean isOn = false;

        //음악 플레이어 켜기
        isOn = true;
        System.out.println("음악 플레이어를 시작합니다.");

        //볼륨 증가
        volumn ++;
        System.out.println("음악 플레이어 볼륨:" + volumn);
        //볼륨 증가
        volumn ++;
        System.out.println("음악 플레이어 볼륨:" + volumn);
        //볼륨 감소
        volumn --;
        System.out.println("음악 플레이어 볼륨:" + volumn);
        //음악 플레이어 상태
        isOn = true;
        System.out.println("음악 플레이어 상태 확인");
        if (isOn){
            System.out.println("음악 플레이어 ON, 볼륨:" + volumn);
        } else {
            System.out.println("음악 플레이어 OFF");
        }
        //음악 플레이어 끄기
        isOn = false;
        System.out.println("음악 플레이어를 종료합니다.");
    }

}

이 코드는 순서대로 작성한 절차 지향 프로그래밍이다.

절차 지향 프로그래밍 - 데이터 묶음

앞서 작성한 코드에 클래스를 도입하자. MusicPlayerData 라는 클래스를 만들고, 음악 플레이어에 사용되는 데이터들을 여기에 묶어서 멤버 변수로 사용하자.

package oop1;

public class MusicPlayerData {
    int volumn = 0;
    boolean isOn = false;
}
 MusicPlayerData data = new MusicPlayerData();


        //음악 플레이어 켜기
        data.isOn = true;
        System.out.println("음악 플레이어를 시작합니다.");

        //볼륨 증가
        data.volumn ++;
        System.out.println("음악 플레이어 볼륨:" + data.volumn);
        //볼륨 증가
        data.volumn ++;
        System.out.println("음악 플레이어 볼륨:" + data.volumn);
        //볼륨 감소
        data.volumn --;
        System.out.println("음악 플레이어 볼륨:" + data.volumn);
        //음악 플레이어 상태
        data.isOn = true;
        System.out.println("음악 플레이어 상태 확인");
        if (data.isOn){
            System.out.println("음악 플레이어 ON, 볼륨:" + data.volumn);
        } else {
            System.out.println("음악 플레이어 OFF");
        }
        //음악 플레이어 끄기
        data.isOn = false;
        System.out.println("음악 플레이어를 종료합니다.");
    }
  • MusicPlayerData data = new MusicPlayerData(); 추가
  • data.isOn = true; 처럼 바뀜.

음악 플레이어와 관련된 데이터는 MusicPlayerData 클래스에 존재한다. 이제 이 클래스를 사용하도록 기존 로직을 변경했다. 이후에 프로그램 로직이 더 복잡해져서 다양한 변수들이 추가되더라도 음악 플레이어와 관련된 변수들은 MusicPlayerData data 객체에 속해있으므로 쉽게 구분할 수 있다.

절차지향 프로그래밍3 - 메서드 추출

public class MusicPlayerMain2 {

    public static void main(String[] args) {


        MusicPlayerData data = new MusicPlayerData();


        //음악 플레이어 켜기
        on(data);

        //볼륨 증가
        volumnUp(data);
        //볼륨 증가
        volumnUp(data);
        //볼륨 감소
        volumnDown(data);
        //음악 플레이어 상태
        showStatus(data);
        //음악 플레이어 끄기
        off(data);
    }

    static void on(MusicPlayerData data){
        data.isOn = true;
        System.out.println("음악 프로그램을 시작합니다.");
    }
    static void off(MusicPlayerData data){
        data.isOn = false;
        System.out.println("음악 프로그램을 종료합니다.");
    }

    static void volumnUp(MusicPlayerData data) {
        data.volumn++;
        System.out.println("음악 플레이어 볼륨:" + data.volumn);
    }
    static void volumnDown(MusicPlayerData data) {
        data.volumn--;
        System.out.println("음악 플레이어 볼륨:" + data.volumn);
    }

    static void showStatus(MusicPlayerData data) {
        System.out.println("음악 플레이어 상태 확인");
        if (data.isOn){
            System.out.println("음악 플레이어 ON, 볼륨:" + data.volumn);
        } else {
            System.out.println("음악 플레이어 OFF");
        }
    }
}

각각의 기능을 메서드로 만든 덕분에 각각의 기능이 모듈화 되었다.

  • 중복 제거: 로직 중복 제거(같은 로직이 필요하면 해당 메서드를 여러번 호출하면 된다.)
  • 변경 영향 범위: 기능을 수정할 때 해당 메서드 내부만 변경
  • 메서드 이름 추가: 메서드 이름을 통해 코드를 더 쉽게 이해할 수 있다.

모듈화 : 쉽게 생각해서 레고 블럭을 생각하면 된다. 필요한 블럭을 가져다 꼽아서 사용할 수 있다. 여기서는 음악 플레이어의 기능이 필요하면 해당 기능을 메서드 호출 만으로 손쉽게 사용할 수 있다. 이제 음악 플레이어와 관련된 메서드를 조립해서 프로그램을 작성 할 수 있다.

  • 결론
    클래스를 사용해서 관련된 데이터를 하나로 묶고, 또 메서드를 사용해서 각각의 기능을 모듈화했다. 덕분에 좋은 코드를 작성할 수 있었다. 하지만 여기서 더 개선을 할 필요가 있다.

절차 지향 프로그래밍의 한계
: 데이터와 기능이 분리되어 있다.
위의 예제를 보면 음악 플레이어의 데이터는 MusicPlayerData에 있는데, 그 데이터를 사용하는 기능은 MusicPlayerMain3에 있는 각각의 메서드에 분리되어 있다.

객체 지향 프로그래밍

지금까지 개발한 음악 플레이어는 데이터와 기능이 분리되어 있다. 이제 데이터와 기능을 하나로 묶어서 음악 플레이어라는 개념을 온전히 하나의 클래스에 담는다.

프로그램을 작성하는 절차도 중요하지만 개념을 객체로 온전히 만드는 것이 더 중요하다.

package oop;
public class MusicPlayer {
 int volume = 0;
 boolean isOn = false;
 void on() {
 isOn = true;
 System.out.println("음악 플레이어를 시작합니다");
 }
 void off() {
 isOn = false;
 System.out.println("음악 플레이어를 종료합니다");
 }
 void volumeUp() {
 volume++;
 System.out.println("음악 플레이어 볼륨:" + volume);
 }
 void volumeDown() {
 volume--;
 System.out.println("음악 플레이어 볼륨:" + volume);
 }
 void showStatus() {
 System.out.println("음악 플레이어 상태 확인");
 if (isOn) {
 System.out.println("음악 플레이어 ON, 볼륨:" + volume);
 } else {
 System.out.println("음악 플레이어 OFF");
 }
 }
}
  • MusicPlayer 클래스에 음악 플레이어에 필요한 속성과 기능을 모두 정의
  • 외부에서 불러올 필요가 없어서 static을 뺀다.

    MusicPlayer 객체를 생성하고 필요한 기능을 호출하기만 하면 된다. 필요한 모든 것은 MusicPlayer에 들어있다.

캡슐화

속성과 기능을 하나로 묶어서 필요한 기능을 메서드를 통해 외부에 제공하는 것

문제풀이 1

package oop.ex;
public class RectangleProceduralMain {
 public static void main(String[] args) {
 int width = 5;
 int height = 8;
 int area = calculateArea(width, height);
 System.out.println("넓이: " + area);
 int perimeter = calculatePerimeter(width, height);
 System.out.println("둘레 길이: " + perimeter);
 boolean square = isSquare(width, height);
 System.out.println("정사각형 여부: " + square);
 }
 static int calculateArea(int width, int height) {
 return width * height;
 }
 static int calculatePerimeter(int width, int height) {
 return 2 * (width + height);
 }
 static boolean isSquare(int width, int height) {
 return width == height;
 }
}

정답

	package oop.ex;
public class Rectangle {
 int width;
 int height;
 int calculateArea() {
 return width * height;
 }
 int calculatePerimeter() {
 return 2 * (width + height);
 }
 boolean isSquare() {
 return this.width == this.height;
 }
}
public class RectangleOopMain {

    public static void main(String[] args) {
        Rectangle rectangle = new Rectangle();
        rectangle.width = 5;
        rectangle.height = 8;

        int area = rectangle.calculateArea();
        System.out.println("넓이: " + area);

        int perimeter = rectangle.calculatePerimeter();
        System.out.println("둘레 길이: "+ perimeter);

        boolean square = rectangle.isSquare();
        System.out.println("정사각형 여부: " + square);
    }
}

문제 2

  • 클래스
package oop1.ex;

public class Account {

    int balance;//잔액

    void deposit(int amount) {
        balance += amount;
    }
    void withdraw(int amount){
            if (balance >= amount) {
                balance -= amount;
            } else {
                System.out.println("잔액 부족");
        }
    }
}
  • 메인
package oop1.ex;

public class AccountMain {

    public static void main(String[] args) {

        Account account = new Account();
        account.deposit(10000);
        account.withdraw(9000);
        account.withdraw(2000);//오류
        System.out.println("잔고는: " + account.balance);
    }
}

정리

객체지향의 특징 : 캡슐화, 상속, 다형성, 추상화, 메세지 전달

0개의 댓글