📌 추상화, 캡슐화, 상속, 다형성 이란?
객체 지향 프로그래밍(Object-Oriented Programming, OOP)이 가지고 있는 4가지 핵심 개념이다.
1. 추상화란?
"사용자는 설명서를 보고 기능을 사용하고, 내부 구현 방법은 모른다"
자바에서는 인터페이스 키워드 implements를 활용해서 구현할 수 있다.
아래 예시를 보자.
- 사용자는 Car 인터페이스를 보고 "Car 타입에는 return 값이 void인 go() 메서드가 있구나" 하고 생각하고 go() 메서드를 사용한다.
- 개발자는 Car 타입의 실제 구현체인 Avante 클래스에 go() 메서드를 구현한다.
- Car 인터페이스는 앞으로가기, 정지하기와 같이 역할을 나타내고 있다. Aante는 실제 구현을 나타내고 있다.
// Car 타입이 어떤 역할을 할 수 있는지 알려주고 있다(설명서)
public interface Car {
void go();
void stop();
}
// 개발자 : 실제 Car 타입 클래스를 구현한다.
public class Avante implements Car {
@Override
public void go() {
// 앞으로 전진하는 복잡한 기능 구현
}
@Override
public void stop() {
}
}
// 사용할 때에는 go()메서드의 구현내용을 열어보지 않는다. 그냥 사용만 한다.
public static void main(String[] args) {
Car avante = new Avante();
avante.go();
}
2. 캡슐화란?
"필요한 부분만 노출시키고, 중요한 내부 구현은 숨겨라"
캡슐화는 객체의 정보를 감싼다는 의미이다. 즉 공개가 불필요한 내부 내용을 숨길 수 있다.
자바에서 접근제어자(priavte, public, protected)를 통해서 캡슐화를 구현할 수 있다.
아래 예시를 보자.
- 사용자는 자동차의 연료가 얼마 남았는지 궁금할 수 있다. 그래서 public을 통해 남은 연료량을 알려줄 수 있는 메서드인 getFuel()을 통해 공개한다.
- 하지만 남은 연료가 궁금할 뿐, 연료 자체에 사용자가 직접 조작할 일은 없기 때문에 연료값을 나타내는 변수인 fuel은 private을 통해 비공개 처리 하였다.
public class Car {
private int fuel = 5;
public int getFuel() {
return fuel;
}
}
3. 상속이란?
"부모의 기능을 이어받아서 재사용한다"
상속은 부모의 기능을 자식이 이어받아 재사용하거나, 조금씩 내용을 수정/추가할 수 있다.
자바에서는 상속 키워드 extends를 이용해서 구현할 수 있다.
아래 예시는 Animal(부모)를 상속한 Cat(자식 1), Dog(자식 2)를 구현하고 있다.
- Cat은 어떠한 메서드도 구현하지 않았지만 부모의 eat() 메서드를 실행할 수 있다.(재활용)
- 반면에 Dog는 부모의 eat() 메서드를 수정해서 "촵촵"으로 변경하였고, 실제로 eat() 메서드를 실행했을 때 변경된 "촵촵"을 실행한다.
public class Animal { // 부모
void eat() {
System.out.println("냠냠");
}
}
public class Cat extends Animal {
}
public class Dog extends Animal {
@Override
void eat() {
System.out.println("촵촵");
}
}
// 실행
public static void main(String[] args) {
Animal cat = new Cat();
Animal dog = new Dog();
cat.eat(); // -> "냠냠" 출력
dog.eat(); // -> "촵촵" 출력
}
4. 다형성이란?
"같은 이름의 메서드지만 서로 다른 동작을 수행한다"
다형성이란 같은 이름의 메서드지만 서로 다른 동작, 즉 다양한 형태를 가질 수 있다는 것을 의미한다.
자바에서는 메서드 오버로딩과 메서드 오버라이딩을 통해서 다형성을 구현할 수 있다.
- 아래 예시를 보면 Animal 클래스가 eat()이라는 메서드를 구현하는데, 파라미터를 받을 때와 받지 않을 때 2가지의 형태를 가지고 있다.
- 같은 이름의 메서드지만 파라미터가 다르기 때문에 서로 다른 동작을 수행할 수 있다. 이러한 방식을 메서드 오버로딩이라고 한다.
public class Animal {
void eat() {
System.out.println("냠냠");
}
void eat(String sound) {
System.out.println(sound);
}
}
메서드 오버라이딩은 상속에서 봤던 예시와 같이 자식이 메서드를 재정의해서 사용한다.
같은이름과 같은 파라미터를 사용하지만 구현하는 내용에 따라 서로다른 동작을 수행한다.
public class Animal { // 부모
void eat() {
System.out.println("냠냠");
}
}
public class Dog extends Animal {
@Override // 재정의
void eat() {
System.out.println("촵촵");
}
}
'Java' 카테고리의 다른 글
[Java] ConcurrentHashMap (0) | 2024.07.23 |
---|---|
[Java] 오버라이딩을 구현할 때 @Override이 꼭 필요할까? (1) | 2023.10.23 |
[Java] 객체지향과 인터페이스 (0) | 2023.10.20 |
String과 StringBuffer/StringBuilder (0) | 2023.09.12 |