일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 자바 다형성
- 안드로이드 유닛 테스트 예시
- 2022 플러터 안드로이드 스튜디오
- 스택 자바 코드
- jvm 작동 원리
- 객체
- 안드로이드 레트로핏 사용법
- rxjava cold observable
- 서비스 vs 쓰레드
- android ar 개발
- 플러터 설치 2022
- 스택 큐 차이
- jvm이란
- 안드로이드 라이선스 종류
- 안드로이드 라이선스
- 안드로이드 유닛 테스트
- ar vr 차이
- 안드로이드 레트로핏 crud
- 큐 자바 코드
- Rxjava Observable
- 멤버변수
- 서비스 쓰레드 차이
- 2022 플러터 설치
- 안드로이드 os 구조
- rxjava hot observable
- 안드로이드 유닛테스트란
- ANR이란
- rxjava disposable
- android retrofit login
- 클래스
- Today
- Total
나만을 위한 블로그
객체 지향 프로그래밍이란? 본문
위키백과에서 말하는 객체 지향 프로그래밍은 아래와 같다.
객체 지향 프로그래밍(OOP)은 컴퓨터 프로그래밍 패러다임 중 하나다. 객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위(객체)들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고 데이터를 처리할 수 있다.
객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 쓴다. 또한 프로그래밍을 더 배우기 쉽게 하고 소프트웨어 개발과 보수를 간편하게 하며, 보다 직관적인 코드 분석을 가능하게 하는 장점을 갖고 있다. 그러나 지나친 프로그램의 객체화 경향은 실제 세계의 모습을 그대로 반영하지 못한다는 비판을 받기도 한다.
객체 지향 프로그래밍은 데이터 처리 등을 수행하며 상호작용하는 객체들을 써서 프로그램을 설계하는 프로그래밍 패러다임이라는 것 같다.
객체에 대해선 지난번에 포스팅했기 때문에 여기선 객체에 대한 내용은 생략한다.
https://onlyfor-me-blog.tistory.com/280
그럼 객체 지향 프로그래밍은 왜 만들어졌을까? 객체 지향 프로그래밍 이전에는 어떤 프로그래밍 패러다임이 있었고 그것에 문제가 있었을까?
영문 위키백과의 역사 부분을 확인해봤다.
https://en.wikipedia.org/wiki/Object-oriented_programming
객체 지향 프로그래밍의 현대적 의미에서 '객체'와 '지향'을 호출하는 용어는 1950년대 후반, 1960년대 초반에 MIT에서 처음 등장했다. 이미 1960년대에 인공지능 그룹의 환경에서 객체는 속성(attributes)이 있는 식별된 항목을 참조할 수 있었다. 또 다른 MIT의 예시는 Ivan Sutherland가 1960~61년에 만든 Sketchpad다. 스케치 패드에 대한 자신의 논문을 기반으로 한 1963년 기술 보고서의 용어집에서 Sutherland는 객체와 인스턴스의 개념을 정의했지만 그래픽 상호 작용에 특화되었다. 1962년 Kristen Nygaard는 이전 Monte Carlo 시뮬레이션을 사용한 것과 실제 시스템을 개념화한 작업을 기반으로 Norwegian Computing Center에서 시뮬레이션 언어 프로젝트를 시작했다. Ole-Johan Dahl이 참여했으며 Simula 프로그래밍 언어는...(중략)...클래스 및 객체, 상속 같은 오늘날 객체 지향 프로그래밍의 필수 부분인 중요한 개념을 도입했다...(중략)
객체 지향 언어들의 역사까지 같이 나와서 필요해 보이는 부분만 가져왔다. 탄생 배경이 잘 나와있지 않아서 다른 블로그를 확인해봤다.
https://dduddublog.tistory.com/8
초기 프로그래밍은 절차적 프로그래밍이었다. 명시된 입력을 받아서 명시된 순서로 처리한 다음 그 결과를 내는 방식이었다. 프로그램을 어떤 논리로 어떤 순서대로 써내려가는 것이 주요 쟁점이었다. 그러나 간단한 알고리즘이면 몰라도 조금만 복잡해지면 순서도로 나타내지는 게 불가능한 스파게티 코드를 양산하게 된다. 시간이 흐를수록 복잡한 프로그램이 요구됐는데 기존 절차적 프로그래밍으론 작성할 수가 없었다.
이 때 구조적 프로그래밍이 탄생한다. 프로그램을 함수 단위로 나누고 함수끼리 호출하는 방식이다. 프로그램이란 큰 문제를 해결하기 위해 작은 함수로 쪼개는 방식이기 때문에 Top-down(하향식) 방식이라고도 불린다. 그러나 구조적 프로그래밍도 데이터 자체를 구조화하진 못했다. 전역 네임 스페이스는 포화 상태가 되어 가고, GUI 프로그램에선 실행 컨텍스트를 저장할 방법이 없었다.
이것의 대안으로 나온 게 객체 지향 프로그래밍이다. 큰 문제를 쪼개는 게 아니라 먼저 작은 문제들을 해결할 수 있는 객체들을 만든 뒤 이 객체들을 조합해서 큰 문제를 해결하는 Bottom-up(상향식) 해결법을 도입한 것이다. 객체를 독립성과 신뢰성이 보장되게 만들어 두면 재사용성도 높아지므로 개발기간과 비용 또한 줄게 되었다.
이후 객체 지향 프로그래밍 또한 복잡해지면서 디자인 패턴이 대두되었다.
다른 글들도 위와 비슷한 맥락으로 설명하고 있기 때문에 위의 출처만 표기한다.
정리하면 객체 지향 이전에는 절차 지향 프로그래밍 방식이 주류였다. 이 말은 객체 지향 프로그래밍 방식은 상대적으로 절차 지향에 비해 환영받지 못했다는 게 된다.
왜 그럴까? 이유는 아래 3가지다.
- 컴퓨팅 파워가 뒤쳐졌던 70년대에 낮은 하드웨어 성능을 최대한 끌어낼 수 있는 언어는 절차 지향 언어였다.
- 사람은 문제를 이해할 때 인과 관계의 순서로 이해하는 방식이 가장 익숙하다. 절차 지향 언어는 이런 방식을 프로그래밍 언어에 도입한 형태였다.
- 객체 지향 언어는 절차 지향 언어에 비해 상대적으로 이해하기 어렵다.
그런데 지금은 객체 지향 언어가 주류다. 이건 또 왜 그럴까? 이 이유 또한 아래와 같다.
- 컴퓨터 성능이 좋아지면서 연산 능력이 발달했다. 이는 상대적으로 연산량을 많이 요구하는 객체 지향 언어가 활동할 수 있는 배경을 제공했다.
- 절차 지향 언어의 한계가 드러났다. 절차 지향 언어로 개발된 프로그램은 어떤 일부분을 떼서 다른 소프트웨어를 만들기가 어렵다. 함수라는 독립된 단위로 소프트웨어를 나누고 있지만 각 함수는 연쇄 호출되면서 동작하기 때문에, 어떤 부분만을 별도로 나눠서 다른 시스템에 적용시키기 어렵다. 또한 절차 전체에서 메모리를 공유하거나 어떤 절차가 어떤 데이터와 연관되는지 쉽게 알 수 없기 때문에 전체 동작을 이해하기 위해선 각 절차들의 내부를 자주 확인해야 했는데 이 방식으론 큰 소프트웨어를 만들기가 어려웠다.
- 시간이 흐르면서 사람들은 점점 더 많은 기능을 가진 프로그램을 요구했다. 이는 필연적으로 프로그램 구조가 복잡해지는 원인이 되었는데 절차 지향 언어로는 이런 프로그램을 만들기 어려웠다.
위와 같은 이유로 절차 지향 프로그래밍 대신 객체 지향 프로그래밍이 우위를 점하게 되었다.
그럼 객체 지향 프로그래밍의 특징은 뭐가 있을까? 인터넷을 찾아 보면 아래의 4가지를 공통적으로 말하고 있다.
- 추상화
- 캡슐화
- 상속
- 다형성
이제 각 요소가 뭘 말하는지 정리한 후 포스팅을 마무리하겠다.
추상화(Abstraction)
먼저 추상화의 경우, 추상이란 뜻을 먼저 아는 것이 좋겠다. 사전에는 추상의 뜻을 이렇게 말한다.
추상 : 여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출해 파악하는 작용
겹치는 속성이 있으면 그걸 따로 빼내서 뭘 하는 걸 추상이라고 하는 것 같다. 위키백과에서 추상화를 검색하면 이와 비슷하게 말하고 있다.
추상화는 복잡한 자료, 모듈, 시스템 등으로부터 핵심적인 개념 또는 기능을 간추려내는 걸 말한다.
https://en.wikipedia.org/wiki/Abstraction_(computer_science)
추상화는 아래와 같다.
1. 더 중요한 세부 사항에 주의를 집중하기 위해 물체나 시스템 연구에서 물리적, 공간적 또는 시간적 세부 사항 또는 속성을 제거하는 과정. 본질적으로 일반화 과정과 유사하다.
2. 추상화 과정의 결과인 다양한 비논리 객체 또는 연구 시스템의 공통 특징이나 속성을 미러링해 추상적 개념을 생성하는 것
추상화 과정은 모델링이라고도 할 수 있으며 이론 및 디자인의 개념과 밀접한 관련이 있다. 모델은 현실 측면의 일반화에 따라 추상화 유형으로 간주될 수도 있다
정리하면 쓸데없는 정보는 숨기고 중요한 정보만 뽑아내는 걸 추상화라고 한다.
객체 지향 관점에서는 클래스를 정의하는 것이 추상화의 일종이라 할 수 있다.
캡슐화(Encapsulation)
캡슐과 될 화(化)가 붙은 단어니까, 캡슐로 만든다는 걸 것이다.
캡슐? 약의 경우 가루약을 캡슐에 넣는 경우가 있다. 그럼 프로그래밍에서 캡슐화는 어떤 정보들을 하나에 넣어서 마치 캡슐처럼 만들기 때문에 붙은 이름이 아닐까?
위키백과에선 캡슐화를 아래와 같이 설명한다.
https://ko.wikipedia.org/wiki/%EC%BA%A1%EC%8A%90%ED%99%94
캡슐화는 객체 지향 프로그래밍에서 다음 2가지 측면이 있다.
1. 객체의 속성(data fields = 변수)과 행위(methods = 기능)를 하나로 묶고
2. 실제 구현 내용 일부를 외부에 감춰 은닉한다
외부에 감추는 방법으로는 언어적 측면에서 접근지정자(public, private 등)를 둬서 은닉의 정도를 기술해 구현한다. 은닉의 정도를 접근지정자로 기술하고 해당 영역에 들어가는 속성이나 메서드를 제한하면 된다. 접근지정자에 의해 제한된 멤버들은 컴파일러에 의해 판단된다. 언어적 측면에서 접근지정자에 의해 정의된 해당 멤버변수나 멤버함수는 코드 중에 접근방식을 위반한 코드를 작성하면 컴파일 오류로 처리하고 실행코드 생성을 제한한다.
https://en.wikipedia.org/wiki/Encapsulation_(computer_programming)
캡슐화는 해당 데이터에 대해 작동하는 메서드와 데이터를 번들로 묶거나, 일부 객체 구성 요소에 대한 직접적인 접근을 제한하는 걸 말한다. 캡슐화는 클래스 내부의 구조화된 데이터 개체의 값이나 상태를 숨기는 데 사용되며 숨겨진 구현 세부사항을 노출하거나 메서드가 유지관리하는 상태 불변성을 위반할 수 있는 방식으로 클라이언트가 직접 액세스할 수 없게 한다. 일반적으로 클래스에 공개적으로 접근할 수 있는 메서드가 제공되어 보다 추상적으로 상태에 접근하거나 수정한다. 실제론 값에 접근하기 위한 메서드(getter, setter)가 제공되기도 하는데, 추상 캡슐화의 위반은 아니지만 잠재적으로 열악한 객체 지향 프로그래밍 설계 관행(안티패턴)의 기호로 간주되는 경우가 많다.
추상화를 통해 클래스와 객체를 정의했다면 그 객체에 필요한 변수나 메서드를 책임이 있는 객체에 그룹화하는 걸 캡슐화라고 한다.
이렇게 하면 관련된 기능, 특징들이 한 곳에 모이게 되니 재활용하기 편해질 것이다.
또한 수정사항이 생기더라도 그 클래스 안에서만 고치면 되고, 매개변수가 필요한 메서드가 있더라도 그 부분만 수정하면 되기 때문에 상대적으로 오류가 발생할 가능성은 적을 것이다.
상속(Inheritance)
보통 상속은 재산 관련해서 쓰인다. 부모가 자식에게 자신의 재산을 물려주는 뉘앙스의 단어다.
프로그래밍에선 상속을 무슨 의미로 사용하고 있을까?
상속은 객체들 간의 관계를 구축하는 방법이다. 클래스로 객체가 정의되는 고전 상속에서, 클래스는 기반 클래스, 슈퍼 클래스 또는 부모 클래스 등의 기존 클래스로부터 속성(=변수)과 동작(=메서드)을 상속받을 수 있다. 그 결과로 생기는 클래스를 파생 클래스, 서브 클래스 또는 자식 클래스라고 한다. 상속을 통한 클래스들의 관계는 계층을 형성한다...(중략)
https://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)
상속은 객체 또는 클래스를 다른 객체(프로토타입 기반 상속) 또는 클래스(클래스 기반 상속)에 기반해서 유사한 구현을 유지하는 메커니즘이다. 또한 슈퍼 클래스 또는 기본 클래스 같은 기존 클래스에서 새 클래스(하위 클래스)를 파생한 다음 클래스의 계층 구조로 형성하는 것으로 정의된다. 대부분의 클래스 기반 객체 지향 언어에서 상속을 통해 만들어진 객체인 "자식 객체"는 생성자, 소멸자, 오버로드된 연산자 및 친구 함수(friend functions)를 제외하고 "상위 객체"의 모든 속성, 기능을 획득한다. 상속을 통해 개발자는 기존 클래스를 기반으로 하는 클래스를 만들고, 같은 동작을 유지하면서 새로운 구현을 지정하며, 코드를 재사용하고 공용 클래스와 인터페이스를 통해 원본 소프트웨어를 독립적으로 확장할 수 있다.
상속은 1969년 Simula를 위해 발명됐으며 현재 자바, C++, PHP, 파이썬 같은 많은 객체 지향 프로그래밍 언어에서 쓰이고 있다.
상속된 클래스를 부모 클래스(슈퍼 클래스)의 자식(하위) 클래스라고 한다. 상속이라는 용어는 클래스 기반 프로그래밍, 프로토타입 기반 프로그래밍 모두에 느슨하게 사용되지만, 좁은 사용에서 이 단어는 클래스 기반 프로그래밍(한 클래스가 다른 클래스에서 상속됨)을 위해 예약되며, 프로토타입 기반 프로그래밍의 해당 기술은 상속 대신 위임이라고 불린다.
상속은 하위 유형 지정과 혼동되어선 안 된다. 일부 언어에선 상속과 하위 유형 지정이 일치하지만 다른 언어에선 다르다. 일반적으로 하위 유형 지정은 is-a 관계를 설정하는 반면 상속은 구현을 재사용하고 구문 관계를 설정하지만 반드시 의미론적 관계는 아니다. 상속은 행동 하위 유형 지정을 보장하지 않는다. 이런 개념을 구별하기 위해 하위 유형 지정을 인터페이스 상속이라고도 하는 반면, 여기에 정의된 상속을 구현 상속 또는 코드 상속이라고 한다.
사람이라는 클래스를 만들고 남자, 여자 클래스를 만들어 사람 클래스를 상속하게 한다면 사람 클래스는 부모 클래스가 되고, 남자와 여자 클래스는 자식 클래스가 된다.
그래서 남자, 여자 클래스는 모두 사람 클래스가 가진 변수와 메서드를 사용할 수 있다.
그러나 자바의 경우 다중상속은 불가능하게 만들어져 있기 때문에, 한 번에 2가지 클래스를 상속할 수 없다.
이 경우 인터페이스 또는 추상 클래스를 활용해 보완할 수 있다.
다형성(Polymorphism)
다형성에 관해선 예전에 포스팅을 작성한 적이 있다. 그러나 예제 코드를 위주로 쓰인 글이기 때문에 여기서 좀 더 자세히 정리한다. 해당 글은 아래 주소를 클릭해서 볼 수 있다.
https://onlyfor-me-blog.tistory.com/278
다형성은 한자로 多形性이라고 쓴다. 즉 형태가 많은 성질이라는 뜻인데, 사전에선 이렇게 정의하고 있다.
다형성 : 같은 종(種)의 생물이면서도 어떤 형태나 형질이 다양하게 나타나는 현상. 예를 들면 암수에 따라 크기, 형태, 색깔 따위가 차이 나는 것이다
위키백과에선 아래와 같이 말한다.
다형성은 그 프로그래밍 언어의 자료형 체계의 성질을 나타내는 것으로, 프로그램 언어의 각 요소들(상수, 변수, 식, 오브젝트, 함수, 메서드 등)이 다양한 자료형(type)에 속하는 것이 허가되는 성질을 가리킨다. 반대말은 단형성(monomorphism)으로, 프로그램 언어의 각 요소가 한 가지 형태만 가지는 성질을 나타낸다.
https://en.wikipedia.org/wiki/Polymorphism_(computer_science)
다형성은 다른 유형의 엔터티에 대한 단일 인터페이스를 제공하거나 여러 유형을 나타내기 위해 단일 기호를 쓰는 것이다. 다형성이란 개념은 생물학의 원리에서 차용한 것이다...(중략)
이번엔 위키백과를 봐도 무슨 뜻인지 잘 모르겠다. 다른 사람들은 다형성에 대해 어떻게 설명하고 있는지 확인해보자.
https://mainpower4309.tistory.com/11
다형성이란
1. 여러 가지 형태를 가질 수 있는 것
2. 하나의 메서드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것. 대표적으로 오버로딩, 오버라이딩이 있다.
3. 하나의 참조변수로 여러 타입의 객체를 참조할 수 있는 것. 즉, 조상 타입의 참조변수로 자손 타입(상속관계)의 객체를 다룰 수 있는 것이 다형성의 기본 개념이다.
주의점) 자손 타입의 참조변수로 조상 타입의 인스턴스를 참조할 수는 없다.
https://tecoble.techcourse.co.kr/post/2020-10-27-polymorphism/
다형성은 여러 형태를 받아들일 수 있는 성질, 상황에 따라 의미를 다르게 부여할 수 있는 특성 등으로 정의하기도 한다. 정리하면 다형성이란 하나의 타입에 여러 객체를 대입할 수 있는 성질로 이해하면 될 것이다.
다형성을 구현하는 방법에는 오버로딩, 오버라이딩, 함수형 인터페이스 등이 있다.
아무래도 다형성은 말만 보기보다는 코드로 보는 게 이해가 좀 더 쉬울 것이다. 윗부분에 링크 걸어 둔 다형성 포스팅을 참고하거나 다른 분들이 짜 놓은 예제 코드를 보면서 이해하는 게 좋겠다.
'모르는 용어 정리' 카테고리의 다른 글
AR이란? AR/VR 차이 (0) | 2021.10.12 |
---|---|
프로세스 vs 쓰레드 (0) | 2021.10.11 |
서버 사이드 렌더링(SSR) vs 클라이언트 사이드 렌더링(CSR) (0) | 2021.10.11 |
WebRTC란? (0) | 2021.08.29 |
메서드 vs 함수 (0) | 2020.08.07 |