OOP란 객체 지향 프로그래밍 즉, 절차 지향 프로그래밍이 아닌 객체의 관점에서 프로그래밍을 한다는 것이다.
프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
절차 지향 프로그래밍 VS 객체 지향 프로그래밍
절차 지향 프로그래밍
물이 위에서 아래로 흐르는 것처럼 순차적인 처리를 중요시하는 프로그래밍 기법이다.
가장 대표적인 언어로 C언어가 있다.
컴퓨터의 처리구조와 유사해 실행속도가 빠르다.
코드의 순서가 바뀌면 동일한 결과를 보장하기 어렵다.
객체 지향 프로그래밍
실제 세계의 사물들을 객체로 모델링하여 개발을 진행하는 프로그래밍 기법
가장 대표적인 언어로 C++, Java가 있다.
캡슐화, 상속, 다형성 등과 같은 기법을 이용할 수 있다.
절차 지향 언어보다 실행속도가 느리다.
OOP의 기본 구성 요소
붕어빵 틀 = 클래스, 붕어빵의 실체 = 인스턴스, 붕어빵 한 마리 = 객체, 굽기() = 인스턴스화
클래스(Class)
개념
객체를 만들어 내기 위한 설계도 혹은 틀
연관되어 있는 변수(상태)와 메소드(행위)의 집합
객체(Object)
개념
소프트웨어에서 구현할 대상
클래스에 선언된 모양 그대로 생성된 실체
특징
‘클래스의 인스턴스(instance)’ 라고도 부른다.
객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖는다.
OOP의 관점에서 클래스의 타입으로 선언되었을 때 ‘객체’ 라고 부른다.
인스턴스(Instance)
개념
설계도를 바탕으로 소프트웨어에 구현된 구체적인 실체
즉, 객체를 소프트웨어에 실체화하면 그것을 ‘인스턴스’ 라고 부른다.
실체화된 인스턴스는 메모리에 할당된다.
특징
인스턴스는 객체에 포함된다고 볼 수 있다.
OOP의 관점에서 객체가 메모리에 할당되어 실제 사용될 때 ‘인스턴스’ 라고 부른다.
인스턴스는 어떤 원본(추상적인 개념)으로부터 ‘생성된 복제본’ 을 의미한다.
OOP의 장/단점
장점 👍
코드 재사용이 용이하다.
남이 만든 클래스를 가져와서 이용할 수 있고 상속을 통해 확장해서 사용할 수 있다.
유지보수가 쉽다.
절차 지향 프로그래밍에서는 코드를 수정할 때 일일이 찾아 수정해야하는 반면,
객체 지향 프로그래밍에서는 수정할 부분이 클래스 내부에 멤버 변수 혹은 메서드로 있기 때문에 해당 부분만 수정하면 된다.
대형 프로젝트에 적합하다.
클래스 단위로 모듈화시켜서 개발할 수 있으므로 대형 프로젝트처럼 여러명, 여러 회사에서 개발이 필요할 시 업무 분담하기 쉽다.
단점 👎
처리속도가 절차 지향 프로그래밍에 비해 상대적으로 느리다.
객체가 많으면 용량이 커질 수 있다.
설계시 많은 시간과 노력이 필요하다.
OOP의 특징
추상화 (Abstraction)
캡슐화 (Encapsulation)
상속(재사용성) (Inheritance)
다형성 (Polymorphism)
1. 추상화
어떤 영역에서 필요로 하는 속성이나 행동을 추출하는 작업
인터페이스와 구현을 분리함으로써, 객체가 가진 특성 중 필수 속성만으로 객체를 묘사하고 유사성만을 표현하며 세부적인 상세 사항은 각 객체에 따라 다르게 구현되도록 할 수 있다.
Java에서는 인터페이스, 추상클래스를 활용할 수 있다.
인터페이스
클래스의 템플릿, 껍데기만 있는 클래스라 할 수 있다.
인터페이스는 멤버 변수, 멤버 함수를 가질 수 없고, 추상 메소드와 상수만 가질 수 있다.
여러 클래스의 사용 방법이 같음을 보장한다.
인터페이스를 구현하는 구체 클래스에서 추상 메소드들을 모두 구현해주어야 한다.
인터페이스는 다중 상속이 가능하고, 인터페이스끼리 상속이 가능하다.
추상 클래스
추상 메소드를 하나 이상 가진 클래스이다.
하위 클래스를 참조하여 상위 클래스의 객체를 생성하며, 하위 클래스를 제어하기 위해 사용한다.
추상 클래스의 생성자로 객체 생성이 불가하다.
2. 캡슐화
하나의 객체에 대해 그 객체가 특정한 목적을 위한 필요한 변수나 메소드를 하나로 묶는 것
따라서 클래스를 만들 때 사용할 변수와 그 변수를 가지고 특정한 액션, 즉 메소드를 관련성 있게 클래스에 구성해야한다.
정보은닉
캡슐화를 하는 중요한 목적은 바로 정보은닉이다.
유저 정보를 가지고 있는 User라는 객체에서 유저의 정보가 public으로 선언되어 있다면, 누구든 접근해서 유저 정보를 변경할 수 있다.
그렇기 때문에 private로 해서 데이터를 보호해서 접근을 제한해야한다.
이렇게 보호된 변수는 getter나 setter 등의 메서드를 통해서만 간접적으로 접근이 가능하도록 하는 것이 캡슐화의 중요한 목적이다.
정보은닉이 왜 필요할까?
높은 응집도와 낮은 결합도를 유지할 수 있도록 설계하여 요구사항을 변경할 때 유연하게 대처하기 위해서
한 클래스가 변경이 발생하면 변경된 클래스에 의존하는 다른 클래스들도 변경해야 할 가능성이 커지기 때문이다.
응집도(Cohesion) : 클래스나 모듈 안의 요소들이 얼마나 밀접하게 관련되어 있는지를 나타낸다. 결합도(Coupling) : 어떤 기능을 실행하는 데 다른 클래스나 모듈들에 얼마나 의존적인지를 나타낸다.
캡슐화 -> 정보은닉 (private, getter, setter) -> 높은 응집도, 낮은 결합도
3. 상속
상속이란 기존 상위 클래스에 근거하여 새롭게 클래스와 행위를 정의할 수 있게 도와주는 개념이다.
기존 클래스에 기능을 가져와 재사용할 수 있으면서도 동시에 새롭게 만든 클래스에 새로운 기능을 추가할 수 있게 만들어 준다.
상속의 장점 👍
상위 클래스를 재사용해서 하위 클래스를 빨리 개발할 수 있도록 한다.
반복된 코드의 중복을 줄여준다.
유지 보수의 편리성을 제공해 준다.
객체의 다형성을 구현할 수 있다.
상속의 단점 👎
상위 클래스의 변경이 어려워진다.
부모 클래스에 의존하는 자식 클래스가 많을 때, 부모 클래스의 변경을 자식 클래스에게 많은 영향을 끼친다.
불필요한 클래스가 증가할 수 있다.
유사 기능 확장 시, 필요 이상의 불필요한 클래스를 만들어야 하는 상황이 발생할 수 있다.
상속이 잘못 사용될 수 있다.
같은 종류가 아닌 클래스의 구현을 재사용하기 위해 상속을 받게 되면 문제가 발생할 수 있다.
상속받는 클래스가 부모 클래스와 IS-A 관계가 아닐 때 이에 해당한다.
해결책
객체 조립(컴포지션)을 사용한다.
필드에서 다른 객체를 참조하는 방식으로 구현된다.
상속은 IS-A 관계가 성립하고, 재사용 관점이 아닌 기능의 확장 관점일 때 사용한다.
4. 다형성
다형성은 상속을 통해 기능을 확장하거나 변경하는 것을 가능하게 해준다.
즉, 다형성은 형태가 같은데 다른 기능을 하는 것을 의미한다.
이를 통해 코드의 재사용, 코드 길이 감소가 되어 유지보수가 용이하도록 도와준다.
다형성을 구현하는 방법은 대표적으로 오버로딩, 오버라이딩이 있다.
오버로딩 (Overloading)
같은 이름의 메소드를 사용하지만 메소드마다 다른 용도로 사용되며 그 결과물도 다르게 구현할 수 있게 만드는 개념
오버로딩이 가능하려면 메소드끼리 이름은 같지만 매개변수의 갯수나 데이터 타입이 다르면 오버로딩이 적용
매개 변수는 같고, 리턴 타입이 다를 때는 성립하지 않는다.
public class OverloadingTest{
public void test(){
System.out.println("사용자 없음");
}
public void test(String name){
System.out.println("사용자 이름 = " +name);
}
public void test(String name, int money){
System.out.println("사용자 이름 = "+name+" , 사용료 = "+money);
}
// 리턴 타입이 다르므로 오버로딩 적용 X
public String test(String name){
System.out.println("사용자 이름 = " +name);
return name;
}
}
오버라이딩 (Overriding)
부모 클래스에서 상속받은 자식 클래스에서 부모클래스에서 만들어진 메소드를 자식 클래스에서 다시 재정의해서 사용하는 것을 말한다.
public class Employee{
public String name;
public int age;
public void print(){
System.out.println("사원의 이름 = "+this.name+", 나이 = "+this.age);
}
}
// Emplyee 상속
public class Manager extends Employee{
String jobOfManage;
// Employee의 print() 메소드 오버라이딩
public void print(){
System.out.println("사원의 이름 = "+this.name+", 나이 = "+this.age);
System.out.println("관리자 "+this.name+"은 "+this.jobOfManage+" 담당입니다.");
}
}
OOP
OOP(Object Oriented Programming)란?
OOP란 객체 지향 프로그래밍 즉, 절차 지향 프로그래밍이 아닌 객체의 관점에서 프로그래밍을 한다는 것이다.
프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
절차 지향 프로그래밍 VS 객체 지향 프로그래밍
절차 지향 프로그래밍
객체 지향 프로그래밍
OOP의 기본 구성 요소
클래스(Class)
변수(상태)
와메소드(행위)
의 집합객체(Object)
개념
특징
인스턴스(Instance)
개념
특징
OOP의 장/단점
장점 👍
코드 재사용이 용이하다.
유지보수가 쉽다.
대형 프로젝트에 적합하다.
단점 👎
처리속도가 절차 지향 프로그래밍에 비해 상대적으로 느리다.
객체가 많으면 용량이 커질 수 있다.
설계시 많은 시간과 노력이 필요하다.
OOP의 특징
1. 추상화
어떤 영역에서 필요로 하는 속성이나 행동을 추출하는 작업
인터페이스
와구현
을 분리함으로써, 객체가 가진 특성 중 필수 속성만으로 객체를 묘사하고 유사성만을 표현하며 세부적인 상세 사항은 각 객체에 따라 다르게 구현되도록 할 수 있다.인터페이스
추상 클래스
2. 캡슐화
하나의 객체에 대해 그 객체가 특정한 목적을 위한 필요한 변수나 메소드를 하나로 묶는 것
따라서 클래스를 만들 때 사용할 변수와 그 변수를 가지고 특정한 액션, 즉 메소드를 관련성 있게 클래스에 구성해야한다.
정보은닉
캡슐화를 하는 중요한 목적은 바로 정보은닉이다.
유저 정보를 가지고 있는 User라는 객체에서 유저의 정보가
public
으로 선언되어 있다면, 누구든 접근해서 유저 정보를 변경할 수 있다.그렇기 때문에
private
로 해서 데이터를 보호해서 접근을 제한해야한다.이렇게 보호된 변수는 getter나 setter 등의 메서드를 통해서만 간접적으로 접근이 가능하도록 하는 것이 캡슐화의 중요한 목적이다.
정보은닉이 왜 필요할까?
높은 응집도와 낮은 결합도를 유지할 수 있도록 설계하여 요구사항을 변경할 때 유연하게 대처하기 위해서
한 클래스가 변경이 발생하면 변경된 클래스에 의존하는 다른 클래스들도 변경해야 할 가능성이 커지기 때문이다.
캡슐화 -> 정보은닉 (private, getter, setter) -> 높은 응집도, 낮은 결합도
3. 상속
상속이란 기존 상위 클래스에 근거하여 새롭게 클래스와 행위를 정의할 수 있게 도와주는 개념이다.
기존 클래스에 기능을 가져와 재사용할 수 있으면서도 동시에 새롭게 만든 클래스에 새로운 기능을 추가할 수 있게 만들어 준다.
상속의 장점 👍
상위 클래스를 재사용해서 하위 클래스를 빨리 개발할 수 있도록 한다.
반복된 코드의 중복을 줄여준다.
유지 보수의 편리성을 제공해 준다.
객체의 다형성을 구현할 수 있다.
상속의 단점 👎
상위 클래스의 변경이 어려워진다.
불필요한 클래스가 증가할 수 있다.
상속이 잘못 사용될 수 있다.
해결책
객체 조립(컴포지션)을 사용한다.
상속은 IS-A 관계가 성립하고, 재사용 관점이 아닌 기능의 확장 관점일 때 사용한다.
4. 다형성
다형성은 상속을 통해 기능을 확장하거나 변경하는 것을 가능하게 해준다.
즉, 다형성은 형태가 같은데 다른 기능을 하는 것을 의미한다.
이를 통해 코드의 재사용, 코드 길이 감소가 되어 유지보수가 용이하도록 도와준다.
다형성을 구현하는 방법은 대표적으로 오버로딩, 오버라이딩이 있다.
오버로딩 (Overloading)
같은 이름의 메소드를 사용하지만 메소드마다 다른 용도로 사용되며 그 결과물도 다르게 구현할 수 있게 만드는 개념
오버로딩이 가능하려면 메소드끼리 이름은 같지만 매개변수의 갯수나 데이터 타입이 다르면 오버로딩이 적용
오버라이딩 (Overriding)
부모 클래스에서 상속받은 자식 클래스에서 부모클래스에서 만들어진 메소드를 자식 클래스에서 다시 재정의해서 사용하는 것을 말한다.