객체지향프로그래밍(OOP: Object Oriented Programming)

Lucas.Choi·2024년 9월 16일

객체지향

목록 보기
2/2

객체 지향 프로그래밍은 현실 세계의 모든 사물들을 소프트웨어의 코드로 표현하기 위해 각 사물들을 객체(Object)로 보고, 해당 객체의 핵심적인 개념 및 기능만을 추출하는 추상화(Abstraction)를 통해 소프트웨어를 모델링하는 패러다임을 말한다.

객체 지향적 설계를 통해 소프트웨어를 설계 및 개발하면, 코드의 재사용을 통해 반복적인 코드를 최소화하고, 보다 유연하고 변경에 용이한 프로그램을 작성할 수 있다.

객체 지향의 특징 (캡.상.추.다.)

1. 캡슐화

서로 연관이 있는 속성과 기능들을 하나의 캡슐로 만들어 외부로부터 데이터를 보호하는 것
1. 데이터 보호 - 외부로부터 클래스에 정의된 속성과 기능들을 보호
2. 데이터 은닉 - 내부의 동작은 감추고 외부에는 필요한 부분만 노출

2. 상속

클래스 간 공유될 수 있는 속성과 기능들을 상위 클래스로 추상화하여, 해당 상위 클래스로부터 상속받은 여러 개의 하위 클래스들이 모두 상위 클래스의 속성과 기능들을 간편하게 사용하도록 하기 위한 기능

  • 상위 클래스의 특성을 하위 클래스에서 상속하고 추가로 필요한 특성을 더하여 확장
  • 상속관계에서는 "하위 클래스는 상위 클래스이다."를 반드시 만족(is-a 관계)
    - 객체 is a 클래스
    	- 김연아 is a 사람 -> 김연아는 한 명의 사람이다.
    - 하위 클래스 is a kind of 상위 클래스
    	- 펭귄 is a kind of 동물 -> 펭귄은 동물의 한 분류이다.

3. 추상화

특정 사물이나 표상을 해당 표상의 성질, 공통성, 본질에 착안하여 소프트웨어의 모델로 추출

  1. 데이터 추상화 - 객체들의 공통 특징을 묶어 이름을 붙이는 것
    ex) 스마트폰 객체를 추상화를 통해 정보 분리를 하면 스마트폰 => 휴대폰 => 통신기기 => 전자제품으로 추상화할 수 있다.
# 전자제품
public class Electronics {
	// 전원기능
	power() {}
}

# 통신기기 (전자제품을 상속)
public class CommunicationDevice extends Electronics {
	// 통화기능
	call() {}
}

# 휴대폰 (통신기기를 상속)
public class MobilePhone extends CommunicationDevices {
	// 카메라 기능
	camera() {}
    
    // 게임 기능
    game() {}
}

# 스마트폰 (휴대폰을 상속)
public class SmartPhone extends MobilePhone {
	// 추가 기능
    additionalFunction() {}
    
    // 스마트폰은 상위 객체의 기능을 상속을 통해 모두 사용할 수 있다.
    // 사용 가능 기능
    // power, call, camera, game
}
  1. 제어 추상화 - 어떤 클래스를 사용하는 사용자에게 해당 메서드의 작동 방식과 같은 내부 로직을 숨기는 것 (사용자 입장에서는 원하는 결과 값만을 필요로 하기 때문에 내부 로직을 알아야 할 필요가 없다.)
SmartPhone phone = new SmartPhone;

phone.power();
// 전원을 켜거나 끄기 위한 기능을 사용하는데
// Electronic power()의 내부 로직을 알아야 할 필요가 없음
  1. 데이터를 하나로 뭉치기 위한 객체의 경우 - 캡슐화 원칙 일부 위배
    • 캡슐화 원칙에는 일부 위배되긴 하지만 다른 목적을 가진 클래스와 객체를 추상화하는 기법으로 이러한 경우는 행위가 아닌 데이터가 위주이다.
    • 캡슐화의 원칙을 준수하여 모든 필드를 private로 직접 접근을 막고, 각 필드값을 변경하거나 반환하는 메서드를 세트로 미리 작성 (getter, setter)
    • 주로 계층 간 데이터를 주고받을 목적으로 사용
    • 캡슐화 원칙에 따라 작성을 하긴 하지만, 실제로는 캡슐화가 의미가 없을 정도로 필드명을 그대로 사용한 설정자와 접근자로 인해 캡슐화 효과가 없다 - 유지 보수성 약화
    • 하지만 데이터를 주로 다루는 객체의 경우 행위를 추상화하지 않고 미리 모든 필드에 접근 가능성을 염두해 두고 작성해 두는 관례로 인해 현재도 많이 사용되고 있음(엄밀히 말하자면 EJB의 java bean 작성 규칙에 따르는 것)

4. 다형성

어떤 객체의 속성이나 기능이 상황에 따라 여러 가지 형태를 가질 수 있는 성질

public class Animal {
	public String name; // 이름
    
    public void showInfo() {
    	System.out.println(name); // 이름 출력
    }
}
  1. 오버로딩
    한 클래스 내에 동일한 메서드 명으로 기술하는 것
  • 사용 이유
    1. 메서드에 사용되는 이름을 절약할 수 있다.
    2. 메서드를 호출할 때, 전달해야 할 매개변수의 타입이나 개수에 대해 크게 신경 쓰지 않고 호출할 수 있음.
public class Penguin extends Animal {
	public String habitat; // 서식지
   
   public Penguin(String name) {
   	this.name = name;
   }
   
   // 오버로딩 - 중복 정의 : 같은 메서드 이름, 다른 인자 리스트
   public Penguin(String name, String habitat) {
   	this.name = name;
       this.habitat = habitat;
   }
}
  • 사용 조건
    1. 클래스 내에서 메서드명 동일
    2. 매개변수의 개수 또는 타입이 다름
    3. 리턴 타입은 오버로딩 구현에 영향을 주지 않음
      ex) 매개변수가 같고 리턴 타입이 다른 경우, 오버로딩 성립이 안됨
class Overloading {
	// 리턴 타입이 달라도 오버로딩은 성립
    int print(int a, int b) {
    	return a + b;
    }
    
    // 매개변수는 같지만 리턴 타입이 다른 경우
    // 오버로딩이 성립하지 않음
    void print(int a, int b) {
    	System.out.println(a + b);
    }
    
    // 리턴 타입이 다른 경우
    // 위 경우는 매개변수의 타입이 다르므로 오버로딩 성립
    double print(double a, double b) {
    	return a + b;
    }
}
  1. 오버라이딩
    상속받은 부모 클래스에서 이미 정의된 메서드를 자식 클래스에서 재정의하는 것 (단, private 제외)
  • 자식 클래스에서 메서드를 재정의하면 부모 클래스의 메서드가 아닌 자식 클래스의 메서드가 실행 (즉, 재정의된 메서드가 우선권을 가짐)
  • @Override라는 어노테이션을 사용(어노테이션은 오버라이딩을 검증하는 기능)
public class Penguin extends Animal {
	public String habitat; // 서식지
    
    // 오버라이딩 - 재정의 : 상위 클래스의 메서드와 같은 이름, 같은 인자 리스트
    @Override
    public void showInfo() {
    	System.out.println(name + " " + habitat);
    }
}
  • 사용 조건
    1. 부모 클래스의 메서드와 이름이 동일
    2. 매개변수의 타입, 개수, 순서가 일치
    3. 리턴 타입이 동일
    4. 접근 제한자는 부모 클래스의 메서드와 같거나 더 넓은 범위
    5. 부모 메서드의 예외와 같거나 예외의 개수를 줄일 수 있음.

0개의 댓글