[객체 지향 프로그래밍] 객체 지향 프로그래밍

무1민·2023년 11월 22일
1

객체 지향

목록 보기
1/2
post-thumbnail

IT기업 신입 사원 기술면접에서 자주 나오는 객체지향 프로그래밍에 대해서 들고 와봤다.
정말 기본적인 개념인 만큼, 우리는 이것에 대해 제대로 답변하지 못한다면 안 좋은 인상을 받으면서 면접을 시작할 수 있다..

🎶객체 지향 프로그래밍 (OOP)?

객체 지향 프로그래밍은 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.
Object Oriented Programming의 약자다.

보통 인간 중심적 프로그래밍 패러다임이라고도 한다.
현실 세계의 사물들을 객체라고 보고 그 객체로부터 개발하고자 하는 어플리케이션에 필요한 특징들을 뽑아와 프로그래밍하는 것이다.

😎 OOP의 장점

  • 다른 클래스를 가져와 사용할 수 있고, 상속받을 수 있어 코드의 재사용성이 증가한다.
  • 자주 사용되는 로직을 라이브러리로 만들어두면 계속해서 사용할 수 있어 신뢰성을 확보할 수 있다.
  • 클래스 단위로 모듈화가 가능하여, 대형 프로젝트에 적합하다.
  • 객체 단위로 코드가 나눠져 작성되기 때문에 디버깅이 쉽고 유지보수가 용이하다.
  • 절차 지향 프로그래밍에서는 코드를 수정할 때 일일이 찾아 수정해야 하는 반면, 객체 지향 프로그래밍에서는 수정해야 할 부분이 클래스 내부에 멤버 변수 혹은 메서드로 존재하기 때문에 해당 부분만 수정하면 된다.

😢 OOP의 단점

  • 처리 속도가 상대적으로 느리다.
  • 객체가 많으면 용량이 커진다.
  • 설계 시 많은 노력과 시간이 필요하다.

객체 지향 프로그래밍 키워드

1. 추상화

객체에서 공통된 속성과 행위를 추출하는 것

abstract class Animal{
	String name;
  int legs;
  String howling;
	public void setAnimal(String name, int legs, String howling) {
    	this.name = name;
      this.legs = legs;
      this.howling = howling;
      }
	public abstract void walk();
  public abstract void talk();
	public void run() {
		walk();
		talk();
	}
}
class Dog extends Animal {
	@Override
	public void walk() {
		System.out.println(this.name + "가 나타나 "+this.legs+"개의 다리로 걸어다닙니다.");
	}
    @Override
	public void talk() {
		System.out.println(this.name + "가 " + this.howling + " 소리 내며 울어댑니다.");
	}
}
class Cat extends Animal {
	@Override
	public void walk() {
		System.out.println(this.name + "가 나타나 "+this.legs+"개의 다리로 걸어다닙니다.");
	}
    @Override
	public void talk() {
		System.out.println(this.name + "가 " + this.howling + " 소리 내며 울어댑니다.");
	}
}
public class Main {
    public static void main(String[] args) {
			Dog dog = new Dog();
			dog.setAnimal("개", 4, "멍멍");
			dog.run();
            //
			Cat cat = new Cat();
			cat.setAnimal("고양이", 4, "야옹");
			cat.run();
            //
      duck.run();
    }
}

이때 Dog, Cat 클래스에서 오버라이딩을 하지 않으면 부모 클래스와 비슷한 일을 함에도 계속 새로운 메소드를 만들어줘야 해서 비효율적이다.

2. 캡슐화

객체. 즉, 클래스의 내부 변수와 메소드를 하나로 패키징하는 특징이다.
Java의 경우 접근제어자를 통해 객체의 캡슐화, 은닉화를 구현한다.

  • public : 다른 객체에서 해당 객체의 인스턴스를 생성하여 접근할 수 있다.
  • protected : 해당 객체를 상속받은 객체 내부에서 접근할 수 있다.
  • default : 동일한 패키지 내의 객체에서 인스턴스를 생성하여 접근할 수 있다.
  • private : 선언된 객체 내부에서만 사용 가능하며, 외부에선 어떠한 방법으로 해당 지시자를 가진 변수 혹은 메소드를 사용할 수 없다.
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public void addUser(final String email, final String pw) {
	final String encryptedPassword = passwordEncoder.encryptPassword(pw);
	final User user = User.builder()
			.email(email)
			.pw(encryptedPassword).build();
	userRepository.save(user);
}

위 함수에서 중요한 것은 입력된 비밀번호를 주면 암호화된 비밀번호를 반환받는다는 것이다. 그에 반해 어떠한 암호화 알고리즘을 사용하는지 등은 알 필요가 없으며, 그러므로 PasswordEncoder는 세부 알고리즘을 구현으로 숨겨둔 것이다.

3. 상속

클래스 개념이 도입되면서 상속을 통해 부모클래스의 속성과 기능을 이어받아 사용하는 것을 말한다.
중복되는 기능을 작업하지 않게 해준다.

특히나 JPA를 즐겨쓰는 우리는 이미 많이 쓰고 있다.

public interface UserRepository extends JpaRepository<User, Long> {
    User findByEmail(String email);
}

JpaRepository를 상속받음으로써, 데이터베이스 연산을 위한 많은 코드를 작성할 필요가 없이 간결하고 효율적인 데이터 접근 계층을 구현할 수 있다.

4. 다형성

프로그래밍 언어의 프로그래밍 언어의 자료형 체계의 성질을 나타내는 것으로, 동일한 변수, 함수명 등이 다양한 방법으로 기능하는 것을 말한다.
오버라이딩, 오버로딩의 형태로 제공된다.

public interface PaymentService {
    void processPayment(PaymentDetails paymentDetails);
}
@Service
public class PaymentServiceImpl implements PaymentService {
    @Override
    public void processPayment(PaymentDetails paymentDetails) {
        // 카드 결제 처리 로직
    }
}

이렇게 우리가 service Layer를 구현할 때도 다형성을 잘 적용시켰던 것을 알 수 있다.

다음 시간엔 SOLID 법칙에 대해서 알아보려고 했는데...
마지막에 다형성에 대해서 정리하다가 Service와 ServiceImpl의 관계에 대해서 궁금해졌다. 다음 시간엔 이 부분에 대해서 알아보도록 하겠다.

profile
야호

0개의 댓글