객체지향 프로그래밍

» JAVA

객체지향 프로그래밍이란? (Object-Oriented Programming, OOP)

프로그래밍에서 필요한 데이터를 추상화 시켜 상태와 행위를 가진 객체로 만들고, 객체들간의 상호작용을 통해 로직을 구성하는 프로그래밍 방법

예전에는 군사 목적으로 사용되는것이 컴퓨터였다. 학자들은 미사일 또는 탱커 같은 실험체들의 모의실험을 위해 실제 세계와 같은 가상 세계를 구현하는데 노력하였고 이는 객체지향론을 탄생시킨다.

객체지향이란 ‘실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용이다.’라는 것이다.
실제 사물의 속성기능을 분석하여 데이터(변수)함수로 정의함으로써 가상 세계를 구현한것이다.

객체지향의 개념

객체지향 프로그래밍은 여러 프로그래밍 패러다임 중 하나이며 객체지향을 사용하는 장점은 아래와 같다.

  1. 재사용성: 코드의 재사용성이 높다.
    • 기존에 만들어진 객체를 이용하여 쉽게 작성할 수 있다.
  2. 유지보수: 코드관리가 용이하다.
    • 코드간의 관계를 이용하여 적은 노력으로 쉽게 코드를 변경할 수 있다.
  3. 중복된 코드의 제거: 신뢰성이 높은 프로그래밍을 가능하게 한다.
    • 제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며, 코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지할 수 있다.

객체지향의 큰 장점은 ‘코드의 재사용성이 높고 유지보수가 용이하다’는 것 프로그램의 개발과 유지보수에 드는 시간과 비용을 획기적으로 개선할 수 있다.

클래스와 객체

클래스(Class)

객체를 정의해놓은 것 ‘객체의 설계도 또는 틀’ 클래스는 객체를 생성하는데 사용되며, 객체는 클래스의 정의된 대로 생성

객체(Object)

컴퓨터에서 객체는 사물과 같은 유형적인 것들을 포함한 개념이나 논리와 같은 무형적인 것들을 포함.

클래스에 정의된 내용대로 메모리에 생성된 것

비유를 하자면 클래스는 TV 설계도, 객체는 TV가 되는것이다. TV가 생성이 되면 TV에 있는 기능(메소드)을 사용하여 소리를 높이거나 채널을 변경할 수 있다. 또한 TV에는 크기, 볼륨, 채널 등을 속성이라한다.

   
속성 높이, 넓이, 색상, 볼륨, 채널 등
기능 켜기, 끄기, 볼륨 높이지, 채널 변경하기 등

객체와 인스턴스

클래스로부터 만들어진 객체를 인스턴스(instance)라고 한다.

객체와 인스턴스는 같은 의미이다. 두 용어를 엄격히 구분할 필요는 없지만 문맥에 따라 다르게 사용이 되므로 이후 공부를 하다보면 객체와 인스턴스에 대해 혼동이 오고는 한다.
객체는 모든 인스턴스를 대표하는 포괄적인 의미를 가지며, 인스턴스는 어떤 클래스로부터 생성된 것을 강조한다.

자동차는 객체이다. 자동차는 자동차 클래스의 인스턴스다.

객체지향 주요특징

객체지향은 크게 추상화, 상속, 캡슐화, 다형성의 네가지 특징을 가진다.

추상화

사전적의미 : 사물을 정확하게 이해하기 위해서는 사물이 지니고 있는 여러 가지 측면 가운데서 특정한 측면만을 가려내어 포착하는 것

서로 다른 객체들의 공통된 부분들을 추출하여 멤버변수와 메서드를 설계하고 이를 이용하여 각 구현되는 클래스에 상속 시키기 위한 목적도 있으며, 실세계에서의 사물을 가상에서 객체로 표현을 위해 어떠한 사물이나 생물을 포함하여 특징이나 생김새 행동들을 분석하는 것을 말한다.

  • 미완성의 설계도와 같다.
  • 추상클래스는 인스턴스를 생성할 수 없다. 상속을 통해 하위 클래스에 의해서만 완성될 수 있다.
  • 추상클래스도 생성자가 있으며, 멤버변수와 메서드를 가질 수 있다.
  • 추상메서드는 선언부만 작성하고 구현부는 작성하지 않는다.
  • 제어자는 abstract 키워드를 가진다.

Abstract와 Interface

추상을 만드는데는 Abstract와 Interface가 있다.\

Abstract는 선언부만 가질 수 도 있지만 구현된 메소드를 하위 클래스에서 상속 받고, 상황에 따라 오버라이딩하여 재구현을 할 수 있다.
그러나 자바에서는 다중 상속은 허용되지 않으며 Abstract는 extends를 통해 단일 상속만 가능하다.

Interface는 상속 받는 클래스에서 공통된 기능들을 선언부만 작성함으로 일관되고 정형화된 개발을 진행할 수 있으며 서로 관계가 없는 클래스들에게 관계를 맺어 줄 수 있다.(다형성)
단, Interface는 모든 추상메서드를 반드시 오버라이딩하여 구현해야 한다. 또한, implement를 이용하여 다중 상속을 할 수 있으며, 하위 클래스에서 구현 하기에 같은 객체에서 다른 동작을 할 수 있는 다형성을 보여준다.

상속

  • 기존의 클래스를 재사용하여 새로운 클래스를 만드는 것.
  • 코드의 재사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여
  • extends 키워드를 사용하여 클래스를 상속받는다.
  • 상위 클래스가 변경되면 하위 클래스도 영향을 받게 되지만, 하위 클래스가 변경되는것은 상위 클래스에 영향을 주지 못한다.
  • 생성자와 초기화 블럭은 상속되지 않는다. 멤버만 상속된다.
  • 하위 클래스의 멤버 개수는 상위 클래스보다 항상 같거나 많다.
  • 상위 클래스의 메서드를 하위 클래스에 재정의 하는 것을 오버라이딩이라 한다.
  • 모든 클래스는 기본적으로 Object.class를 상속하고 있다.

오버라이딩

상위 클래스로 부터 상속받은 메서드를 재정의 하는것. 상속받은 메서드를 그대로 사용하기도 하지만 하위 클래스에 맞게 변경해야 하는 경우가 있다.

오버라이딩 조건

  • 이름이 같아야 한다.
  • 매개변수가 같아야 한다.
  • 반환타입이 같아야 한다.
  • 접근 제어자는 상위 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
  • 상위 클래스의 메서드보다 많은 예외를 선언할 수 없다.
  • 인스턴스 메서드를 static 메서드로 또는 그 반대로 변경할 수 없다.

다형성

한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록 한다. 상위 클래스 타입의 참조변수로 하위 클래스의 인스턴스를 참조할 수 있다.

상속 관계에 있는 클래스 사이에서는 참조변수의 형변환이 가능하다. (주의!! 하위 인스턴스를 가지고 있는 상위 참조변수를 하위 참조변수로 형변환이 가능하다. 상위 인스턴스를 하위 참조변수로 형변환은 에러가 발생한다.)

⚠ 참조변수의 형변환은 타입이 변경되는 것이지 인스턴스가 변경되는 것이 아니다. 하위 참조변수를 상위 참조변수로 형변환 되어도 하위 인스턴스의 멤버까지 사용할 수 없다.

캡슐화

데이터가 유효한 값을 유지하고 외부에서 함부로 변경하지 못하도록 접근을 제한하여 보호한다. 객체의 정보를 은닉화하여 객체간의 결합도를 낮춰 유지보수성과 재활용성을 향상시킨다.

비유하자면 마치 우리가 먹는 알약과도 같다. 캡슐 약 안에는 어떠한 성분이 있고 어떤 기능을 하는지 알 수 없지만 어디가 아플때 먹는 약 정도만 알고 있는 것처럼 캡슐화를 통해 하나의 모듈처럼 만들어 놓으면 상황에 필요한 메소드를 이용하여 처리할 수 있는것이다.

이때 외부에서는 캡슐안의 정보들을 몰라도 되고 알 수 없고 정보를 변경할 수 없기에 은닉화가 가능하며, 감기에 대한 처방을 위해 감기를 위한 여러 성분들이 모인 것처럼 하나의 문제를 처리하기 위한 기능들이 하나의 클래스나 메소드로 캡슐화 하여 높은 응집도를 표현할 수 있다.

이렇게 만들어진 모듈은 재사용성이 용이하며 유지보수를 향상시킨다.

  • 높은 응집도
  • 접근제어자를 이용한 정보은닉
  • 재활용성 향상

좋은 객체지향 설계를 위한 사고와 연습방법?

이 질문에 대해서는 정답이 없을것이다. 사람마다 스타일이 다르고 지향하는 방법이 다르기 때문에 개인차에 따라 객체를 구현하는 방법이 다를것이다. 다만 다른 사람들의 코드들을 최대한 많이 보고서