ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Chapter 1. Object Oriented Programming
    Java 2021. 7. 4. 17:55

    1. 객체지향이란

    '모듈'별로 개발하고, 이를 '조립'하는 프로그래밍 방법론이다. 여기서 말하는 모듈은 '객체' 혹은 '클래스'를 의미한다.

     

    클래스란 '설계도', 혹은 '붕어빵 틀'로 표현되며 '멤버 변수', '멤버 함수', '생성자'로 구성된다.

    객체란 '설계도를 바탕으로 생성된 실체', 혹은 '붕어빵'으로 표현되며 '클래스를 실제 실행한 것'이다.

     

     2. OOP 특징

    1. 캡슐화 : 클래스의 일부 데이터를 '숨길수도' 혹은 자식 클래스에게 '상속하지 않도록' '접근 제한자'를 둠으로 모듈별로 캡슐화가 가능하다.
      • 예를 들어 어떤 객체의 멤버 변수로 score 변수는 0부터 100까지의 값만 설정 될 수 있다. 개발자가 해당 데이터를 바로 접근하여 소수, 혹은 매우 큰 값등 이상 데이터를 넣을 수 있다. 따라서 보통 객체의 상태를 나타내는 멤버 변수는 접근 제한자를 강하게 두고 setScore 함수를 통해 변수를 설정할 수 있다. 이때 해당 함수에는 이상 값이 들어가지 않도록 '예외처리' 하여 데이터를 보호한다. 
      • 부모 클래스가 가지는 기능 중 접근 제한자를 public, protected 등으로 둔다면 자식 클래스는 해당 기능을 사용할 수 있다. 이때, 부모 클래스가 해당 기능을 변경하면 자식 클래스 모두 해당 기능이 모두 변경된다. 어떻게 보면 장점이자 단점일 수 있다. 유지보수 측면에서 편리할 수도 있지만 부모 클래스에서만 변경되고 자식 클래스는 해당 정보를 수정되길 원하지 않을 수 있다. 따라서 일부 기능을 접근 제한자를 강하게 두어 상속을 회피한다.
    2. 상속 : 부모 / 자식 구조로 클래스는 구성되며, 필요할 경우 자신의 정보를 자식 클래스에게 물려줄 수 있다. 이때 자식 클래스는 부모의 기능을 '그대로 사용하거나', 혹은 Overriding 할 수 있다.
      • Overriding : 부모 클래스가 가진 메소드와 동일한 명칭, 파리미터 형식, 리턴 타입을 가진 메소드를 재정의 함을 의미한다.
      • Overloading : 동일 함수명, 리턴 타입을 가지지만 파라미터 형식이 다르게 하여 함수 호출의 편의성을 위해 사용된다. 예를 들어, print 함수를 정의할 때도 하나의 타입으로 정의 하는것이 아니라 입력으로 들어오는 파라미터의 모든 형식 int, double, char etc 모두에 대해 Overloading처리한다.
      • 예를 들어, 모험가 클래스가 있고 자식 클래스로 '전사', '도적', '마법사', '궁수' 등이 있다. 모험가 클래스에서 기본 공격으로 attack 함수가 있고 자식 클래스는 자신의 직업 특성에 맞게 atack 메소드를 재정의 할 수 있다. 또한, move 함수가 있고 모든 자식 클래스들은 공통적으로 '모험가' 클래스가 가진 move 함수를 사용하고 있었다. 그런데 모험가[부모 클래스] 클래스만 이동속도를 늦추고 싶더라도 자식 클래스 모두 부모 클래스가 가진 메소드를 사용하여 부모 클래스를 수정할 수는 없는 경우가 존재한다. 따라서 부모/자식의 의존도를 고려하며 클래스를 설계해야한다.
    3. 다형성 : 부모 클래스가 가진 기능을 자식 클래서에서 'overriding'한다. 이후 수 많은 자식 클래스를 부모 클래스에 대입하여 다양한 결과 값을 추출하는 기능을 가진다.
      • 예를 들어, 자동차 클래스가 있고 자식 클래스로 '현대', '기아', '제네시스', '벤츠', '폭스바겐' 등 다양한 자동차 클래스들이 존재한다. 이후 자식 클래스들은 해당 기업에 맞게 부모 클래스가 가진 기능을 overriding한다. 이후 객체를 생성할 때 Car car1 = new Hyundai(); Car car2 = new Kia(); 등 부모 타입에 자식 타입을 대입하여 부모 타입이 가진 하나의 기능이 다양한 결과 값이 나올 수 있다.
    4. 추상화 : 클래스들 중 공통된 기능을 가진 것들을 '추상화'하여 부모 클래스를 둠으로 '코드의 재사용성', '코드 유지보수'의 장점을 이끌 수 있다.
      • 예를 들어, 자동차에는 '현대', '기아', '벤츠' 등 수많은 클래스들이 존재한다. 이들의 공통된 기능을 묶어 '자동차'라는 추상화된 클래스를 생성하고 해당 클래스에 'move', 'stop', 'parking' 등의 공통 기능을 생성하여 코드 재사용 및 유지보수의 장점을 이끈다.

     

    ※ 접근 제한자

    • private : 자신의 클래스에서만 접근할 수 있다.
    • protected : 자식 클래스, 같은 패키지에서만 접근 할 수 있다.
    • public : 외부, 자식 클래스, 모든 패키지에서 접근 할 수 있다.

    3. 프로그래밍 패러다임

    점차 프로그램의 규모가 확장되며, 보다 편리하게 프로그래밍하기 위해 다양한 프로그래밍 방법론이 도출됬다.

     

    예를 들어, 학급을 청소하는 상황을 프로그래밍해보자.

     

    # 비구조적 프로그래밍

    '철수' : 빗자루로 쓸고, 쓰레기가 꽉차면 버리고 다시 청소하자. 빗자루가 더러워지면 다른 걸로 교체하자.

    '영희' : 빗자루로 쓸고, 쓰레기가 꽉차면 버리고 다시 청소하자. 빗자루가 더러워지면 다른 걸로 교체하자.

    '민수' : 빗자루로 쓸고, 쓰레기가 꽉차면 버리고 다시 청소하자. 빗자루가 더러워지면 다른 걸로 교체하자.

     

    이렇게 같은 작업임에도 매번 똑같은 명령을 내리면 귀찮고 일부 내용이 수정된다면 유지보수에도 어려운 측면이 있었습니다. 따라서 동일 기능을 하는 작업을  함수[프로시저]로 묶어 코드의 재사용성 및 유지보수의 장점을 이끌었습니다.

     

    # 절차 지향 프로그래밍

    빗자루 쓸기 : 빗자루로 쓸고, 쓰레기가 꽉차면 버리고 다시 청소하자. 빗자루가 더러워지면 다른 걸로 교체하자.

    바닥 닦기 : 바닥을 대걸레로 닦고, 대걸레가 더러우면 화장실에서 빨고 다시 청소하자.

    창문 닦이 : 4면으로 구분하여 닦는데 걸레가 더러워지면 다르면으로 닦고, 모든 면이 더러우면 걸레를 빨고 다시 닦자.

     

    같은 기능을 하는 부분을 묶어 코드의 재상용성이나 유지보수의 장점을 이끌었습니다. 하지만 규모가 확장되면 이마저도 감당하기 힘들다. 모든학생들마다 빗자수 쓸기, 바닥 닦기 등을 시키며 계속 '감시'해야한다.

     

    # 객체 지향 프로그래밍

    빗자루 클래스 { 빗자루, 쓰레받기, 쓸기 함수}

    닦기 클래스 {대걸레, 물통, 닦기 함수}

    창문 닦기 클래스 {걸레, 닦기 함수}

     

    역할 별로 클래스로 묶고 각각에 '상태'와 '동작'을 나타내는 정보를 담는다. 이전 절차 지향 프로그래밍에서는 프로시저로 묶어 기능을 수행했지만 학생마다의 상태 정보를 담지는 않았다. 물론 ArrayList로 상태정보를 따로 관리할 수 있지만 개발의 편의성을 봤을 때 객체 지향이 훨씬 편리하다. 또한 객체지향이 가지는 '상속', '다형성', '추상화', '캡슐화' 등에 특징이 더해지면 더욱 강력하게 편리하다.

    '청소'라는 부모 클래스로 추상화하여 묶고 자식 클래스에 맞게 즉 바닥 쓸기, 걸레 닦기 등의 성징을 추가하여 Overriding한다. 이후 모든 학생들을 '청소' 클래스[부모]로 생성하고 = new 닦기(); or = new 빗자루(); 등으로 생성한다. 학생들 모두를 Arraylist<청소>로 묶어서 for문을 돌며 청소 함수를 실행시킨다.

     

    4. Abstract Class vs Interface

    추상 클래스, 인터페이스 모두 해당 클래스에서 'Instance를 생성하지 않고' 하위 클래스에게 구현을 강제하는 공통점을 가진다. '선언'만 있고 '구현 내용'은 없다.

     

    Abstract Class

    • 부모/자식 관계에서 Abstract Class를 상속 받아 자식 클래스에서 '구현을 강제'한다.
    • 멤버 변수, 멤버 함수, 추상 메서드등이 함께 구성되며 다중 상속이 불가능하다.
    • '협업'하여 개발 시 무언가 대충(추상적으로) 구현을 해야 할 때 사용된다. 즉, 설계시 대충이라도 무언가 만들어놔야 개발을 할 수 있다. 또한, 부모 클래스에서는 구현할 수 없지만 자식 클래스들이 '반드시' 구현해야 되는 내용이면 추상 메서드를 설정하여 자식 클래스에서 반드시 구현하도록 설정한다. 

    Interface

    • 부모, 자식 관계 즉 상속 관계에 얽메이지 않고, '공통 기능'을 장착한다.
    • 상수, Abstract Method로만 구성되며 변수는 사용되지 않는다. Abstract Class 보다 추상화가 높다.
    • implements로 상속 받아 필요 기능들을 Overriding하며 다중 상속이 가능하다.
    • '협업'하여 개발 시 공통적으로 사용되는 부분을 미리 정의하여 개발 한 후, 추후에 코드를 합칠때 효율적이다.
      • 예를 들어, 어떤 클래스를 개발할 때 A 개발자는 일부 기능을 B 개발자는 다른 일부 기능을 개발한다고 가정해보자. 이때 시간이 없어 두명의 개발자는  동시에 개발을 하는 상황이다. 먼저 두명의 개발자가 공통적으로 사용하는 Method가 있고 이러한 부분을 'Interface'로 묶은 후 더미데이터로 각자 채워 넣는다. 이후 각자 개발을 하여 완료하면, Dummy로 개발한 부분을 제외하고 한개의 코드로 합친다.

    'Java' 카테고리의 다른 글

    Chapter 3. Java Virtual Machine  (0) 2021.07.04
    Chapter 2. Java Memory & Variable Type  (0) 2021.07.04
    기본기  (0) 2020.08.26
Designed by Tistory.