캡슐화
연관된 데이터(변수)와 기능(메소드)을 하나로 묶고, 불필요한 요소를 외부에 노출되지 않도록 설계하는 방식을 뜻한다. 자바에서는 접근 제어자(public, private, default, protected)를 통해 캡슐화를 구현할 수 있다.
class Student {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class 캡슐화_예제 {
public static void main(String[] args) {
Student s1 = new Student();
// 직접적인 접근은 할 수 없다.
// s1.id = 1;
// s1.name = "choi";
// public 접근 제어자인 getter와 setter를 통해 값에 접근할 수 있다.
s1.setId(1);
s1.setName("choi");
}
}
이 밖에도 캡슐화를 통해 다음과 같은 효과를 얻을 수 있다.
- 느슨한 결합
- 재사용
- 정보은닉
추상화
추상화는 클래스들의 공통적인 요소를 뽑아서 상위 클래스를 만들어내는 것이다. 한 마디로 추상화는 공통적인 속성과 기능을 정의함으로써 코드의 중복을 줄이고, 클래스 간 관계를 효과적으로 설정하고, 유지보수를 용이하게 하는 것이다.
자바에서는 추상 클래스와 인터페이스라는 문법 요소를 통해 추상화를 구현할 수 있다.
상속
기존의 클래스에 기능을 추가하거나 재정의하여 새로운 클래스를 정의하는 것을 의미한다. 상속을 이용하면 기존에 정의되어 있는 클래스의 모든 필드와 메서드를 물려받을 수 있다. 이로 인하여 다음과 같은 장점을 얻을 수 있다.
- 기존에 작성된 클래스를 재활용할 수 있다.
- 자식 클래스 설계 시 중복되는 멤버를 미리 부모 클래스에 작성해 놓으면, 자식 클래스에서는 해당 멤버를 작성하지 않아도 된다.
- 클래스 간의 계층적 관계를 구성함으로써 다형성의 문법적 토대를 마련한다.
다형성
하나의 객체나 메서드가 여러 가지 다른 형태를 가질 수 있는 것을 뜻한다.
자바에서는 이러한 다형성을 이용하여 부모-자식 관계의 클래스들이 존재할 때, 부모 클래스로 자식 클래스들을 서로 다르게 동작시킬 수 있다.
만약 새, 고양이, 강아지라는 클래스가 있고 모두 cry()라는 울음소리를 낼 수 있는 메서드가 있다고 가정해 보자.
각 각의 클래스를 만들고 cry()를 호출하기 위해서는 아래와 같은 코드가 될 것이다.
class Bird {
void cry() {
System.out.println("짹짹");
}
}
class Cat {
void cry() {
System.out.println("야옹");
}
}
class Dog {
void cry() {
System.out.println("멍멍");
}
}
public class 다형성_예제 {
public static void main(String[] args) {
Bird bird = new Bird();
Cat cat = new Cat();
Dog dog = new Dog();
bird.cry(); // 짹짹
cat.cry(); // 야옹
dog.cry(); // 멍멍
}
}
하지만, 부모 클래스를 정의한 후 다형성을 활용한다면 아래와 같이 보다 간결한 코드를 만들 수 있게 될 것이다.
abstract class Animal {
void cry() {}
}
class Bird extends Animal {
void cry() {
System.out.println("짹짹");
}
}
class Cat extends Animal {
void cry() {
System.out.println("야옹");
}
}
class Dog extends Animal {
void cry() {
System.out.println("멍멍");
}
}
public class 다형성_예제 {
public static void main(String[] args) {
Animal[] animals = new Animal[]{new Bird(), new Cat(), new Dog()};
for (Animal animal : animals) {
animal.cry(); // 짹짹, 야옹, 멍멍
}
}
}
이 밖에도 오버라이딩과 오버로딩도 다형성의 일종이라고 볼 수 있다.
'OOP' 카테고리의 다른 글
[OOP] 정적 바인딩 vs 동적 바인딩 (4) | 2024.11.06 |
---|---|
[OOP] SOLID, 좋은 객체지향 설계의 5가지 원칙 (1) | 2024.09.22 |