{% hint style="info" %} ์๋ฐ๊ฐ ์ ๊ณตํ๋ ๋ค์ค ๊ตฌํ ๋ฉ์ปค๋์ฆ์ ์ธํฐํ์ด์ค์ ์ถ์ ํด๋์ค {% endhint %}
์๋ฐ8๋ถํฐ๋ ์ธํฐํ์ด์ค๋ ๋ํดํธ ๋ฉ์๋๋ฅผ ์ ๊ณตํ ์ ์๊ฒ๋์ด ์ธํฐํ์ด์ค์ ์ถ์ ํด๋์ค ๋ชจ๋ ์ธ์คํด์ค ๋ฉ์๋๋ฅผ ๊ตฌํ ํํ๋ก ์ ๊ณตํ ์ ์๋ค.
๋์ ๊ฐ์ฅ ํฐ ์ฐจ์ด๋ ์ถ์ ํด๋์ค๊ฐ ์ ์ํ ํ์ ์ ๊ตฌํํ๋ ํด๋์ค๋ ๋ฐ๋์ ์ถ์ ํด๋์ค์ ํ์ ํด๋์ค๊ฐ ๋์ด์ผ ํ๋ค. ์๋ฐ๋ ๋จ์ผ ์์๋ง ์ง์ํ๋ ํฐ ์ ์ฝ์ด๋ค.
์ธํฐํ์ด์ค๋ ์ ์ธํ ๋ฉ์๋๋ฅผ ๋ชจ๋ ์ ์ํ๊ณ ๊ทธ ๊ท์ฝ์ ์งํจ ํด๋์ค๋ผ๋ฉด ๋ค๋ฅธ ์ด๋ค ํด๋์ค๋ฅผ ์์ํด๋ ๊ฐ์ ํ์ ์ผ๋ก ์ทจ๊ธํ๋ค.
{% hint style="success" %} ์ธํฐํ์ด์ค๊ฐ ์๊ตฌํ๋ ๋ฉ์๋๋ฅผ (์์ง ์๋ค๋ฉด) ์ถ๊ฐํ๊ณ , ํด๋์ค ์ ์ธ์ implements ๊ตฌ๋ฌธ๋ง ์ถ๊ฐํ๋ฉด ๋์ด๋ค. {% endhint %}
์๋ฐ ํ๋ซํผ์์๋ Comparable, Iterable, AutoCloseable ์ธํฐํ์ด์ค๊ฐ ์๋ก ์ถ๊ฐ๋์ ๋ ํ์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ง์ ๊ธฐ์กด ํด๋์ค๊ฐ ์ด ์ธํฐํ์ด์ค๋ค์ ๊ตฌํํ ์ฑ ๋ฆด๋ฆฌ์ค๋๋ค.
// ์๋ก์ด ์ธํฐํ์ด์ค Comparable ์ถ๊ฐ
// Employee ํด๋์ค๋ Person์ ์์ํ๋ฉด์ Comparable ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ค
interface Comparable<T> {
int compareTo(T o);
}
// ๊ธฐ์กด ํด๋์ค
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
// Person ํด๋์ค๊ฐ ์ธํฐํ์ด์ค Comparable์ ๊ตฌํํ ์ ์์
class Employee extends Person implements Comparable<Employee> {
private int id;
public Employee(String name, int id) {
super(name);
this.id = id;
}
@Override
public int compareTo(Employee o) {
return Integer.compare(this.id, o.id); // Employee์ id๋ก ๋น๊ต
}
}
public class Main {
public static void main(String[] args) {
Employee e1 = new Employee("Alice", 100);
Employee e2 = new Employee("Bob", 200);
System.out.println(e1.compareTo(e2)); // -1 ์ถ๋ ฅ
}
}๋ฐ๋ฉด ๊ธฐ์กด ํด๋์ค ์์ ์๋ก์ด ์ถ์ ํด๋์ค๋ฅผ ๋ผ์๋ฃ๊ธฐ๋ ์ด๋ ค์ด ๊ฒ ์ผ๋ฐ์ ์ด๋ค. ๋ ํด๋์ค๊ฐ ๊ฐ์ ์ถ์ ํด๋์ค๋ฅผ ํ์ฅํ๊ธธ ์ํ๋ค๋ฉด, ๊ทธ ์ถ์ ํด๋์ค๋ ๊ณ์ธต๊ตฌ์กฐ์ ๋ ํด๋์ค์ ๊ณตํต ์กฐ์์ด์ด์ผ ํ๋ค. ์๋ก ์ถ๊ฐ๋ ์ถ์ ํด๋์ค์ ๋ชจ๋ ์์์ด ์ด๋ฅผ ์์ํ๊ฒ ๋๋ ๊ฒ์ด ๋ค. ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ์ด ์ ์ ํ์ง ์์ ์ํฉ์์๋ ๊ฐ์ ๋ก ๋ง์ด๋ค.
// ์๋ก์ด ์ถ์ ํด๋์ค ์ถ๊ฐ
abstract class Animal {
public abstract void makeSound();
}
// ๊ธฐ์กด ํด๋์ค
class Dog {
public void bark() {
System.out.println("๋ฉ๋ฉ");
}
}
// ๊ธฐ์กด ํด๋์ค
class Cat {
public void meow() {
System.out.println("์ผ์น");
}
}
// ์๋ก์ด ์ถ์ ํด๋์ค๋ฅผ ์ ์ฉํ๊ธฐ ์ด๋ ค์ด ์ํฉ
// Dog๊ณผ Cat์ Animal์ ์์ํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๋ณ๊ฒฝํด์ผ ํจ
class AnimalDog extends Animal {
@Override
public void makeSound() {
System.out.println("๋ฉ๋ฉ");
}
}
class AnimalCat extends Animal {
@Override
public void makeSound() {
System.out.println("์ผ์น");
}
}
public class Main {
public static void main(String[] args) {
AnimalDog dog = new AnimalDog();
AnimalCat cat = new AnimalCat();
dog.makeSound(); // ๋ฉ๋ฉ ์ถ๋ ฅ
cat.makeSound(); // ์ผ์น ์ถ๋ ฅ
}
}์์ ๊ฐ์ ์ฝ๋์ฒ๋ผ ๋๋ฉด, ๊ณ์ธต ๊ตฌ์กฐ๊ฐ ๊ฐ์ ๋ก ๋ณ๊ฒฝ๋๋ฉฐ, ๊ธฐ์กด ์ค๊ณ์ ํธํ๋์ง ์๊ฑฐ๋ ๋ถํ์ํ ์์์ด ๋ฐ์ํ ์ ์๋ค.
{% hint style="info" %}
๋ฏน์ค์ธ์ด๋ ํด๋์ค๊ฐ ๊ตฌํํ ์ ์๋ ํ์
์ผ๋ก, ๋ฏน์ค์ธ์ ๊ตฌํํ ํด๋์ค์ ์๋์ ์ฃผ๋ ๊ธฐ๋ฅ์ธ์ ๋ ํน์ ์ ํ์ ๊ธฐ๋ฅ์ ๋ํ๋ ํจ
{% endhint %}
์ด ์ญํ ์ ๋ณดํต ์ธํฐํ์ด์ค๋ก ๊ตฌํํ ์ ์์ต๋๋ค. ๋ฐ๋ฉด, ์ถ์ ํด๋์ค๋ก๋ ๋ฏน์ค์ธ์ ์ ์ํ ์ ์๋ค๋ ๋ด์ฉ์ ๋ค์ค ์์์ ์ง์ํ์ง ์๋ ์๋ฐ์ ํน์ฑ ๋๋ฌธ์ ๋ฐ์ํ๋ ๋ฌธ์ ์ ๋๋ค.
๐ง ๋ฏน์ค์ธ(Mixin)์ด๋?
๋ฏน์ค์ธ์ ํ๋์ ์ฃผ๋ ํด๋์ค์ ์ ํ์ ์ธ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ ๋ฐฉ์์ผ๋ก, ์ฌ๋ฌ ํด๋์ค์์ ๊ณตํต์ ์ผ๋ก ๊ตฌํํ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์ธํฐํ์ด์ค๋ฅผ ์๋ฏธํ๋ค. ์๋ฅผ ๋ค์ด, Comparable ์ธํฐํ์ด์ค๋ ์ด๋ค ํด๋์ค๋ ์๊ด์์ด, ๊ทธ ํด๋์ค ์ธ์คํด์ค๋ค ์ฌ์ด์ ๋น๊ต ๊ธฐ๋ฅ์ ๋ํ ์ ์๊ฒ ํด์ค๋ค.
๐ง ์ ์ถ์ ํด๋์ค๋ก ๋ฏน์ค์ธ์ ์ ์ํ ์ ์์๊น?
์๋ฐ๋ ๋ค์ค ์์์ ํ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์, ํด๋์ค๊ฐ ์ด๋ฏธ ๋ค๋ฅธ ํด๋์ค๋ฅผ ์์๋ฐ๊ณ ์์ผ๋ฉด ์ถ๊ฐ์ ์ผ๋ก ๋ค๋ฅธ ์ถ์ ํด๋์ค๋ฅผ ์์๋ฐ์ ์ ์๋ค. ํ์ง๋ง ์ธํฐํ์ด์ค๋ ์ฌ๋ฌ ๊ฐ๋ฅผ ๊ตฌํํ ์ ์์ผ๋ฏ๋ก, ์ธํฐํ์ด์ค๋ก๋ ๋ฏน์ค์ธ ์ญํ ์ ํ ์ ์์ง๋ง, ์ถ์ ํด๋์ค๋ก๋ ๋ถ๊ฐ๋ฅํ๋ค.
์ธํฐํ์ด์ค๋ก ๋ฏน์ค์ธ์ ๊ตฌํํ๋ ๊ฒฝ์ฐ์ ์ถ์ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ค ํ ๋์ ๋ฌธ์ ์
1. ์ธํฐํ์ด์ค๋ก ๋ฏน์ค์ธ ๊ตฌํ (๊ฐ๋ฅ)
// Comparable ์ธํฐํ์ด์ค๋ '๋ฏน์ค์ธ' ์ญํ ์ ํ ์ ์๋ค.
interface Comparable<T> {
int compareTo(T o);
}
// ์ฃผ๋ ํด๋์ค: Person
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
// Person ํด๋์ค์ ๋ฏน์ค์ธ ์ธํฐํ์ด์ค(Comparable)๋ฅผ ๊ตฌํํ ์ ์๋ค.
class Employee extends Person implements Comparable<Employee> {
private int id;
public Employee(String name, int age, int id) {
super(name, age);
this.id = id;
}
@Override
public int compareTo(Employee o) {
return Integer.compare(this.id, o.id); // Employee์ id๋ก ๋น๊ต
}
public int getId() {
return id;
}
}
public class Main {
public static void main(String[] args) {
Employee emp1 = new Employee("Alice", 30, 101);
Employee emp2 = new Employee("Bob", 25, 102);
System.out.println(emp1.compareTo(emp2)); // -1 ์ถ๋ ฅ
}
}์ค๋ช :
Personํด๋์ค๊ฐEmployee๋ก ํ์ฅ๋์๊ณ , ์ถ๊ฐ์ ์ผ๋กComparable<Employee>๋ผ๋ ๋ฏน์ค์ธ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ์ ์๋ค.- ์ด๋ฅผ ํตํด
Employeeํด๋์ค ์ธ์คํด์ค๋ค๋ผ๋ฆฌ ๋น๊ตํ ์ ์๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ค.
2. ์ถ์ ํด๋์ค๋ก ๋ฏน์ค์ธ ์ ์ (๋ถ๊ฐ๋ฅ)
// ์ถ์ ํด๋์ค ์ ์
abstract class ComparableMixin {
public abstract int compare(Object o);
}
// ์ด๋ฏธ ์์๋ฐ๊ณ ์๋ ์ฃผ๋ ํด๋์ค
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
// ์๋ฐ๋ ๋ค์ค ์์์ ํ์ฉํ์ง ์์ผ๋ฏ๋ก, Person ํด๋์ค๊ฐ ComparableMixin์ ์์๋ฐ์ ์ ์๋ค.
class Employee extends Person /*, ComparableMixin */ {
private int id;
public Employee(String name, int age, int id) {
super(name, age);
this.id = id;
}
// compare ๋ฉ์๋๊ฐ ํ์ํ์ง๋ง ๋ค์ค ์์ ๋ถ๊ฐ๋ก ์ถ์ ํด๋์ค ์ ์ฉ ๋ถ๊ฐ
/*
@Override
public int compare(Object o) {
Employee emp = (Employee) o;
return Integer.compare(this.id, emp.id);
}
*/
}Employeeํด๋์ค๋ ์ด๋ฏธPersonํด๋์ค๋ฅผ ์์๋ฐ๊ณ ์๊ธฐ ๋๋ฌธ์,ComparableMixin์ด๋ผ๋ ์ถ์ ํด๋์ค๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ์์๋ฐ์ ์ ์๋ค.- ์๋ฐ๋ ๋ค์ค ์์์ ํ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์, ์ด ์ํฉ์์ ์ถ์ ํด๋์ค๋ฅผ ๋ฏน์ค์ธ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
์ธํฐํ์ด์ค๋ ์ฌ๋ฌ ๊ฐ๋ฅผ ๊ตฌํํ ์ ์๊ธฐ ๋๋ฌธ์, ํด๋์ค์ ์ฃผ๋ ๊ธฐ๋ฅ ์ธ์ ์ ํ์ ๊ธฐ๋ฅ์ ๋ฏน์ค์ธ์ผ๋ก ์ ๊ณตํ๋ ๋ฐ ์ ํฉํ๋ค. ์ฆ, Comparable๊ณผ ๊ฐ์ ์ธํฐํ์ด์ค๋ ํด๋์ค์ ํ์ํ ๊ธฐ๋ฅ์ ์์ ๋กญ๊ฒ ์ถ๊ฐํ ์ ์๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉ๋๋ค.
๋ฐ๋ฉด, ์ถ์ ํด๋์ค๋ ํด๋์ค ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐํ๊ฒ ์ ํํ๋ฏ๋ก, ์๋ก์ด ์ถ์ ํด๋์ค๋ฅผ ๋์ ํ์ฌ ๋ฏน์ค์ธ ์ญํ ์ ํ๋ ค๋ฉด ์์ ์ ์ฝ์ ๊ฑธ๋ฆฌ๊ฒ ๋ฉ๋๋ค. ์ด๋ ์๋ฐ๊ฐ ๋ค์ค ์์์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
{% hint style="success" %} ํ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๋ง๋ค ๋, ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๊ณ์ธต์ ์ ์ฝ ์์ด ๋ค์ํ ๊ธฐ๋ฅ์ ์กฐํฉํ ์ ์์ด ์ ์ฐํ๋ค. {% endhint %}
๋ฐ๋ฉด, ํด๋์ค ๊ธฐ๋ฐ์ผ๋ก ๋์ผํ ํ์ ์ ์ ์ํ๋ ค๊ณ ํ๋ฉด ์กฐํฉ์ ์๊ฐ ๊ธ๊ฒฉํ ๋์ด๋๋ฉด์ ๋ณต์กํด์ง๋ ๋ฌธ์ (์กฐํฉ ํญ๋ฐ)๊ฐ ๋ฐ์ํ๋ค.
- ์ธํฐํ์ด์ค์ ์ ์ฐ์ฑ:
- ์ธํฐํ์ด์ค๋ ๋ค์ค ์์์ด ๊ฐ๋ฅํ๋ฏ๋ก, ์ฌ๋ฌ ์ธํฐํ์ด์ค๋ฅผ ์์ ๋กญ๊ฒ ์กฐํฉํ ์ ์๋ค.
- ์๋ฅผ ๋ค์ด, ๊ฐ์(Singer)์ ์๊ณก๊ฐ(Songwriter)๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ๊ฐ ์ ์ํ๊ณ , ๊ฐ์์ด๋ฉด์ ์๊ณก๊ฐ์ธ ์ฌ๋์ ๋ํ๋ด๊ธฐ ์ํด ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๋ค.
- ๋ ๋์๊ฐ,
Singer์Songwriter๋ฅผ ํ์ฅํ๊ณ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ์ 3์ ์ธํฐํ์ด์ค(SingerSongwriter)๋ฅผ ์ ์ํ ์๋ ์๋ค.
// ๊ฐ์ ์ธํฐํ์ด์ค
public interface Singer {
AudioClip sing(Song s); // ๊ฐ์๋ ๋
ธ๋๋ฅผ ๋ถ๋ฆ
}
// ์๊ณก๊ฐ ์ธํฐํ์ด์ค
public interface Songwriter {
Song compose(int chartPosition); // ์๊ณก๊ฐ๋ ๋
ธ๋๋ฅผ ๋ง๋ฆ
}
// ๊ฐ์์ด์ ์๊ณก๊ฐ์ธ ์ธํฐํ์ด์ค
public interface SingerSongwriter extends Singer, Songwriter {
AudioClip strum(); // ์ถ๊ฐ ๊ธฐ๋ฅ: ์
๊ธฐ๋ฅผ ์ฐ์ฃผํ ์ ์์
void actSensitive(); // ์ถ๊ฐ ๊ธฐ๋ฅ: ๊ฐ์ฑ์ ์ธ ํ๋์ ํ ์ ์์
}Singer์Songwriter์ธํฐํ์ด์ค๋ ๊ฐ๊ฐ ๊ฐ์์ ์๊ณก๊ฐ์ ์ญํ ์ ์ ์ํ๋ค.SingerSongwriter์ธํฐํ์ด์ค๋ ๋ ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํ์ฌ ๊ฐ์์ด๋ฉด์ ์๊ณก๊ฐ์ธ ์ฌ๋์ ํํํ๋ค. ๋ํ, ์ ๊ธฐ ์ฐ์ฃผ(strum())์ ๊ฐ์ฑ์ ํ๋(actSensitive()) ๊ฐ์ ์ถ๊ฐ ๊ธฐ๋ฅ๋ ์ ์ํ๋ค.- ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ, ํ๋์ ํด๋์ค๊ฐ ๊ฐ์์ด๋ฉด์ ์๊ณก๊ฐ์ธ ๋์์ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
- ํด๋์ค ๊ณ์ธต ๊ตฌ์กฐ์ ์ ํ:
- ํด๋์ค ๊ธฐ๋ฐ์ผ๋ก ๋น์ทํ ์กฐํฉ์ ๋ง๋ค๋ฉด, ๋ค์ค ์์์ด ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๊ฐ์์ด๋ฉด์ ์๊ณก๊ฐ์ธ ํด๋์ค๋ฅผ ์ ์ํ๋ ค๋ฉด ๋ณ๋์ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
- ์์ฑ์ ์๊ฐ ๋ง์์ง์๋ก, ๋ชจ๋ ์กฐํฉ์ ํด๋์ค๋ก ํํํ๋ ค๋ฉด ๊ทธ๋งํผ ๋ง์ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ผ ํด์ ํด๋์ค ๊ณ์ธต ๊ตฌ์กฐ๊ฐ ๋น๋ํด์ง๋ ๋ฌธ์ (์กฐํฉ ํญ๋ฐ)๊ฐ ๋ฐ์ํ๋ค.
2. ํด๋์ค ๊ธฐ๋ฐ ๊ตฌ์กฐ์ ๋ฌธ์ ์
// ๊ฐ์ ํด๋์ค
class SingerClass {
public AudioClip sing(Song s) {
// ๊ฐ์์ ๋
ธ๋ ๋ถ๋ฅด๊ธฐ ๊ธฐ๋ฅ
}
}
// ์๊ณก๊ฐ ํด๋์ค
class SongwriterClass {
public Song compose(int chartPosition) {
// ์๊ณก๊ฐ์ ์๊ณก ๊ธฐ๋ฅ
}
}
// ๊ฐ์์ด์ ์๊ณก๊ฐ์ธ ํด๋์ค๋ฅผ ๋ง๋ค๋ ค๋ฉด ๋ค์ค ์์์ด ์๋๋ฏ๋ก ๋ถํธํจ์ด ๋ฐ์
class SingerSongwriterClass extends SingerClass {
// ์๊ณก๊ฐ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ค๋ฉด ์ถ๊ฐ ๋ฉ์๋๋ฅผ ์์ฑํด์ผ ํจ
public Song compose(int chartPosition) {
// ์๊ณก๊ฐ์ ์๊ณก ๊ธฐ๋ฅ ์ถ๊ฐ
}
// ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ๋ ์ง์ ๊ตฌํํด์ผ ํจ
public AudioClip strum() {
// ์
๊ธฐ ์ฐ์ฃผ ๊ธฐ๋ฅ
}
public void actSensitive() {
// ๊ฐ์ฑ์ ํ๋ ๊ธฐ๋ฅ
}
}์ค๋ช :
SingerClass์SongwriterClass๋ฅผ ํด๋์ค๋ก ์ ์ํ๋ ค๋ฉด, ๋ค์ค ์์์ด ๋ถ๊ฐ๋ฅํ๋ฏ๋ก ํ๋์ ํด๋์ค์ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ง์ ์ถ๊ฐํด์ผ ํ๋ค.- ์๋ฅผ ๋ค์ด, ๊ฐ์์ด์ ์๊ณก๊ฐ์ธ ํด๋์ค๋ฅผ ์ ์ํ๋ ค๋ฉด,
SingerClass๋ฅผ ์์ํ๊ณ ๋ณ๋๋กSongwriterClass์ ๊ธฐ๋ฅ์ ์ถ๊ฐ๋ก ๊ตฌํํด์ผ ํ๋ค. - ํด๋์ค๊ฐ ๋ง์์ง์๋ก ๊ฐ ์กฐํฉ๋ง๋ค ์๋ก์ด ํด๋์ค๋ฅผ ์ ์ํด์ผ ํ๋ฏ๋ก, ์กฐํฉ์ด ๋ง์์ง๋ฉด ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง๊ณ ๋ณต์กํด์ง๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค.
{% hint style="info" %} ์ฆ, ์ธํฐํ์ด์ค์ ์ฅ์ ์
- ๋ค์ค ์์ ๊ฐ๋ฅ: ์๋ฐ์์ ์ธํฐํ์ด์ค๋ ์ฌ๋ฌ ๊ฐ๋ฅผ ๋์์ ๊ตฌํํ ์ ์๊ธฐ ๋๋ฌธ์, ์ฌ๋ฌ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ์กฐํฉํ ์ ์๋ค.
- ์ ์ฐ์ฑ: ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ๊ณผ ํ์ฅ์ฑ์ด ๋์์ง๊ณ , ๋ค์ํ ๊ธฐ๋ฅ์ ๋ ๋ฆฝ์ ์ผ๋ก ๊ตฌํํ ์ ์๋ค.
- ๋ฎ์ ๊ฒฐํฉ๋: ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ๋ถ๋ฆฌํ ์ ์์ด, ํด๋์ค ๊ฐ ๊ฒฐํฉ๋๊ฐ ๋ฎ์์ง๋ค. {% endhint %}
4) ๋ํผ ํด๋์ค ๊ด์ฉ๊ตฌ์ ํจ๊ป ์ฌ์ฉํ๋ฉด ์ธํฐํ์ด์ค๋ ๊ธฐ๋ฅ์ ํฅ์์ํค๋ ์์ ํ๊ณ ๊ฐ๋ ฅํ ์๋จ์ด ๋๋ค.
ํ์
์ ์ถ์ ํด๋์ค๋ก ์ ์ํด๋๋ฉด ๊ทธ ํ์
์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ์์๋ฟ์ด๋ค. ์์ํด์ ๋ง๋ ํด๋์ค๋ ๋ํผ ํด๋์ค๋ณด๋ค ํ์ฉ๋๊ฐ ๋จ์ด์ง๊ณ ๊นจ์ง๊ธฐ ์ฝ๋ค.
์ธํฐํ์ด์ค์ ๋ฉ์๋ ์ค ๊ตฌํ ๋ฐฉ๋ฒ์ด ๋ช
๋ฐฑํ ๊ฒ์ด ์๋ค๋ฉด, ๋ํดํธ ๋ฉ์๋๋ก ๋ง๋ค ์ ์๋ค. ๊ทธ๋ฌ๋ ๋ํดํธ ๋ฉ์๋๋ ์ ์ฝ์ด ์๋ค.
- equals์ hashcode๋ฅผ ๋ํดํธ ๋ฉ์๋๋ก ์ ๊ณต ์ํจ
- ์ธํฐํ์ด์ค๋ ์ธ์คํด์ค ํ๋๋ฅผ ๊ฐ์ง ์ ์๊ณ , private ์ ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง ์ ์๋ค.
- ๋ณธ์ธ์ด ๋ง๋ ์ธํฐํ์ด์ค๊ฐ ์๋๋ฉด ๋ํดํธ ๋ฉ์๋ ์ถ๊ฐ ๋ถ๊ฐ๋ฅ
๊ทธ๋ฆฌ๊ณ ๋ํดํธ ๋ฉ์๋๋ฅผ ์ ๊ณตํ ๋๋ ์์ํ๋ ค๋ ์ฌ๋์ ์ํ ์ค๋ช
์ @implSpec ์๋ฐ๋
ํ๊ทธ๋ฅผ ๋ถ์ฌ ๋ฌธ์ํํด์ผ ํ๋ค.
{% hint style="success" %} ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค๋ ๋ณต์กํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๋ฐ ํ์ํ ๋ฉ์๋๋ฅผ ๋ฏธ๋ฆฌ ๊ตฌํํด๋๋ ์ถ์ ํด๋์ค๋ก, ์ด๋ฅผ ํ์ฅํ๋ฉด ์ธํฐํ์ด์ค๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค. {% endhint %}
- ์ธํฐํ์ด์ค์ ์ถ์ ํด๋์ค:
- ์ธํฐํ์ด์ค๋ ๋ค์ค ๊ตฌํ์ ๊ฐ๋ฅํ๊ฒ ํด์ค๋ค. ํด๋์ค๋ ๋ค์ค ์์์ด ๋ถ๊ฐ๋ฅํ์ง๋ง, ์ธํฐํ์ด์ค๋ ์ฌ๋ฌ ๊ฐ๋ฅผ ๋์์ ๊ตฌํํ ์ ์๋ค. ๊ทธ๋์ ๋ค์ํ ํ์ ์ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ๋ฐ ์ ํฉํ๋ค.
- ์ถ์ ํด๋์ค๋ ๋จ์ผ ์์๋ง ํ์ฉ๋๊ธฐ ๋๋ฌธ์ ํด๋์ค ๊ณ์ธต ๊ตฌ์กฐ์ ์ ํ์ด ์๋ค. ๋ํ, ํ ๋ฒ ์์๋๋ฉด ๋ค๋ฅธ ์ถ์ ํด๋์ค๋ฅผ ํจ๊ป ์์ํ ์ ์์ด์ ํ์ฅ์ฑ์ด ๋จ์ด์ง๋ค.
- ๋ํดํธ ๋ฉ์๋
{% hint style="info" %} ๋ชฉ์ : ์ธํฐํ์ด์ค์์ ์ผ๋ถ ๋ฉ์๋์ ๊ธฐ๋ณธ ๊ตฌํ์ ์ ๊ณตํ์ฌ, ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํ๊ฑฐ๋ ๊ตฌํํ ๋, ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ชจ๋ ๋ฉ์๋๋ฅผ ๋ฐ๋์ ๊ตฌํํ ํ์๋ฅผ ์์ ์ค๋ค. {% endhint %}
-
๋์ ์๊ธฐ: ์๋ฐ 8
-
ํ์ง๋ง ๋ํดํธ ๋ฉ์๋๋ก
equals,hashCode,toString๊ฐ์ Object ๋ฉ์๋๋ฅผ ์ ๊ณตํ ์ ์๋ค. ์ด๋ฌํ ๋ฉ์๋๋ค์ ์ฌ์ ํ ์ถ์ ํด๋์ค์์ ๊ตฌํํด์ผ ํ๋ค. -
์ฌ์ฉ ์:
public interface MyInterface { // ์ถ์ ๋ฉ์๋ void abstractMethod(); // ๋ํดํธ ๋ฉ์๋ default void defaultMethod() { System.out.println("This is a default method."); } }
-
์ฃผ์ ์ฅ์
- ๊ธฐ์กด ์ธํฐํ์ด์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ค.
- ๋ค์ค ์์์ด ๊ฐ๋ฅํ์ฌ, ์ฌ๋ฌ ์ธํฐํ์ด์ค์์ ๋ํดํธ ๋ฉ์๋๋ฅผ ์์๋ฐ์ ์ ์๋ค.
- ๊ธฐ์กด ํด๋์ค๋ฅผ ์ ์งํ ์ฑ ํ์ ํธํ์ฑ์ ๋ณด์ฅํ๋ฉด์๋ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋ค.
- ๊ณจ๊ฒฉ ๊ตฌํ(Skeletal Implementation)
{% hint style="info" %} ๋ชฉ์ : ์ธํฐํ์ด์ค์์ ์ผ๋ถ ๋ฉ์๋์ ๊ธฐ๋ณธ ๊ตฌํ์ ์ ๊ณตํ์ฌ, ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํ๊ฑฐ๋ ๊ตฌํํ ๋, ํ๋ก๊ทธ๋๋จธ๊ฐ ๋ชจ๋ ๋ฉ์๋๋ฅผ ๋ฐ๋์ ๊ตฌํํ ํ์๋ฅผ ์์ ์ค๋ค. {% endhint %}
- ๋์ ์๊ธฐ: ์๋ฐ 1.2 (์ปฌ๋ ์ ํ๋ ์์ํฌ)
- ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค๋ ๋ณต์กํ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๋ฐ ํ์ํ ๋ง์ ๋ฉ์๋๋ฅผ ๋ฏธ๋ฆฌ ๊ตฌํํด๋๋ ์ถ์ ํด๋์ค์ด๋ค. ์ด ํด๋์ค๋ ํ ํ๋ฆฟ ๋ฉ์๋ ํจํด์ ๋ฐ๋ฅธ๋ค.
- ์ธํฐํ์ด์ค๋ฅผ ์ง์ ๊ตฌํํ๋ ๊ฒ๋ณด๋ค ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค๋ฅผ ํ์ฅํ๋ฉด ์ธํฐํ์ด์ค์ ๊ตฌํ ๋ถ๋ด์ด ํฌ๊ฒ ์ค์ด๋ ๋ค.
- ์ปฌ๋ ์
ํ๋ ์์ํฌ์์ ์ ๊ณตํ๋
AbstractCollection,AbstractSet,AbstractList,AbstractMap๋ฑ์ด ๋ํ์ ์ธ ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค์ ์
- ๊ณจ๊ฒฉ ๊ตฌํ์ ์ ์ฝ ์ฌํญ
- ์์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋ฉฐ, ๋จ์ผ ์์๋ง ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์, ํด๋์ค๋ ํ ๋ฒ์ ํ๋์ ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค๋ง ํ์ฅํ ์ ์๋ค.
- ์ถ์ ํด๋์ค๋ก ๊ตฌํ๋๊ธฐ ๋๋ฌธ์, ํ๋๋ฅผ ๊ฐ์ง ์ ์๊ณ ,
protected๋private์ ๊ทผ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
- ๊ณจ๊ฒฉ ๊ตฌํ์ ์ฅ์
- ๋ณต์กํ ์ธํฐํ์ด์ค์ ๊ตฌํ์ ๋จ์ํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ปฌ๋ ์
ํ๋ ์์ํฌ์
AbstractList๋List์ธํฐํ์ด์ค์ ๋ณต์กํ ๋ฉ์๋๋ค(์:contains,isEmpty)์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ์ฌ, ํ์ ํด๋์ค๊ฐ ๊ฐ๋จํ๊ฒ ํ์ํ ๋ฉ์๋๋ง ๊ตฌํํ ์ ์๋๋ก ๋์์ค๋ค. - ํ๋๋ฅผ ํฌํจํ ์ ์๊ณ ๋ด๋ถ ๊ตฌํ์ ์บก์ํํ ์ ์๋ค.
- protected ๋ฉ์๋๋ ํ๋๋ฅผ ์ ๊ณตํ์ฌ ํ์ ํด๋์ค๊ฐ ์ ์ฐํ๊ฒ ์ฌ์ฉํ๊ฑฐ๋ ์ฌ์ ์ํ ์ ์๋ค.
- ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค ์์ฑ ๋ฐฉ๋ฒ:
abstract class AbstractList<E> implements List<E> {
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(Object o) {
for (E e : this) {
if (e.equals(o)) return true;
}
return false;
}
// ์ถ๊ฐ์ ์ผ๋ก ๋ ๋ง์ ๋ฉ์๋๋ฅผ ๊ณจ๊ฒฉ ๊ตฌํ์ผ๋ก ์ ๊ณต
}- ๋จผ์ ์ธํฐํ์ด์ค๋ฅผ ๋ถ์ํด, ๊ธฐ๋ฐ ๋ฉ์๋๋ฅผ ์ ์ ํ๊ณ , ์ด ๋ฉ์๋๋ค์ ๊ณจ๊ฒฉ ๊ตฌํ์์ ์ถ์ ๋ฉ์๋๋ก ๋จ๊ธด๋ค.
- ๊ทธ๋ค์, ๊ธฐ๋ฐ ๋ฉ์๋๋ค๋ก ๊ตฌํํ ์ ์๋ ๋ฉ์๋๋ ๋ํดํธ ๋ฉ์๋๋ก ์ ๊ณตํ๋ค.
equals,hashCode,toString๋ฑ Object ๋ฉ์๋๋ ๋ํดํธ ๋ฉ์๋๋ก ์ ๊ณตํ ์ ์์ผ๋ฏ๋ก, ์ถ์ ํด๋์ค์์ ๊ตฌํํด์ผ ํ๋ค.
1. ๊ณจ๊ฒฉ ๊ตฌํ์ ํ์ฉํ List ๊ตฌํ
๋ค์ ์ฝ๋๋ int[] ๋ฐฐ์ด์ ๋ฐ์ List<Integer> ํํ๋ก ๋ณํํ๋ ๊ณจ๊ฒฉ ๊ตฌํ์ ์ฌ์ฉํ๋ ์์
// ๊ณจ๊ฒฉ ๊ตฌํ์ ์ฌ์ฉํด ์์ฑํ List ํด๋์ค
static List<Integer> intArrayAsList(int[] a) {
Objects.requireNonNull(a); // null ๊ฐ ๋ฐฉ์ง
return new AbstractList<>() {
@Override
public Integer get(int i) {
return a[i]; // ์คํ ๋ฐ์ฑ
}
@Override
public Integer set(int i, Integer val) {
int oldVal = a[i];
a[i] = val; // ์คํ ์ธ๋ฐ์ฑ
return oldVal; // ์คํ ๋ฐ์ฑ
}
@Override
public int size() {
return a.length;
}
};
}- ์ค๋ช
: ์ด ์ฝ๋๋
int[]๋ฐฐ์ด์ ๋ฐ์List<Integer>ํํ๋ก ๋ณํํ๋ ์ด๋ํฐ1 ์ญํ ์ ํ๋ค.AbstractList๋ ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค๋ก, ์ด๋ฅผ ์์๋ฐ์ ํ์ํget(),set(),size()๋ฉ์๋๋ฅผ ๊ตฌํํ๋ค. ์ด๋ ๊ฒ ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค๋ฅผ ํ์ฉํ๋ฉด ๋ฆฌ์คํธ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ๋ฐ ํ์ํ ์์ ์ด ํฌ๊ฒ ์ค์ด๋ ๋ค.
2. ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค์ ์์ (Map.Entry)
๋ค์ ์ฝ๋๋ ์๋ฐ์ Map.Entry ์ธํฐํ์ด์ค๋ฅผ ์ํ ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค
public abstract class AbstractMapEntry<K,V> implements Map.Entry<K,V> {
// ๋ณ๊ฒฝ ๊ฐ๋ฅํ ์ํธ๋ฆฌ๋ ์ด ๋ฉ์๋๋ฅผ ์ฌ์ ์ํด์ผ ํ๋ค.
@Override
public V setValue(V value) {
throw new UnsupportedOperationException(); // ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ ์์ ํ ์ ์์
}
// equals ๋ฉ์๋์ ์ผ๋ฐ ๊ท์ฝ์ ๊ตฌํํ๋ค.
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Map.Entry)) return false;
Map.Entry<?,?> e = (Map.Entry<?,?>) o;
return Objects.equals(e.getKey(), getKey()) &&
Objects.equals(e.getValue(), getValue());
}
// hashCode ๋ฉ์๋์ ์ผ๋ฐ ๊ท์ฝ์ ๊ตฌํํ๋ค.
@Override
public int hashCode() {
return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
}
// toString ๋ฉ์๋ ๊ตฌํ
@Override
public String toString() {
return getKey() + "=" + getValue();
}
}- ์ค๋ช
: ์ด ํด๋์ค๋
Map.Entry์ธํฐํ์ด์ค์ ๊ณจ๊ฒฉ ๊ตฌํ์ด๋ค.equals,hashCode,toString๋ฉ์๋๋ฅผ ๊ตฌํํด๋์์ผ๋ฉฐ,setValue()๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ ์์ ํ ์ ์๋๋ก ์์ธ๋ฅผ ๋์ง๊ฒ ๋์ด ์๋ค. ํ์ ํด๋์ค๋ ์ด ๋ฉ์๋๋ค์ ์ฌ์ ์ํ ์ ์๋ค.
3. ๋จ์ ๊ตฌํ์ ์ (AbstractMap.SimpleEntry)
๋จ์ ๊ตฌํ์ ๊ณจ๊ฒฉ ๊ตฌํ๊ณผ ์ ์ฌํ์ง๋ง, ์ถ์ ํด๋์ค๊ฐ ์๋๋ฉฐ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ๊ตฌํ
public class SimpleEntry<K,V> implements Map.Entry<K,V> {
private final K key;
private V value;
public SimpleEntry(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
V old = this.value;
this.value = value;
return old;
}
}- ์ค๋ช
:
SimpleEntry๋ ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค๋ ์๋์ง๋ง,Map.Entry์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ธ ํด๋์ค์ ๋๋ค. ์ด๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๊ฑฐ๋, ํ์์ ๋ฐ๋ผ ํ์ฅํ ์ ์๋ค.
{% hint style="success" %} ๋ํดํธ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ถ์ ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค(AbstractCharacter)๋ฅผ ๊ตฌํํ์ฌ ์ค๋ณต์ ์์จ ์ ์๋ค. {% endhint %}
| ํน์ง | ๋ํดํธ ๋ฉ์๋ | ๊ณจ๊ฒฉ ๊ตฌํ (Skeletal Implementation) |
|---|---|---|
| ๊ตฌํ ์์น | ์ธํฐํ์ด์ค ์์์ ์ ๊ณต | ์ถ์ ํด๋์ค์์ ์ ๊ณต |
| ์์ ๊ตฌ์กฐ | ๋ค์ค ์์ ๊ฐ๋ฅ (์ฌ๋ฌ ์ธํฐํ์ด์ค์์ ๋ํดํธ ๋ฉ์๋ ์์) | ๋จ์ผ ์์ (ํ ๋ฒ์ ํ๋์ ๊ณจ๊ฒฉ ๊ตฌํ ํด๋์ค๋ง ์์ ๊ฐ๋ฅ) |
| ํ๋ ์ฌ์ฉ | ์ธ์คํด์ค ํ๋ ์ฌ์ฉ ๋ถ๊ฐ | ์ธ์คํด์ค ํ๋ ์ฌ์ฉ ๊ฐ๋ฅ |
| ๋ฉ์๋ ์ ๊ณต ๋ฒ์ | ์ฃผ๋ก ๊ฐ๋จํ ๋ฉ์๋ ๊ตฌํ (๊ตฌํ ์ฝ๋๊ฐ ์ ์) | ๋ณต์กํ ๋ฉ์๋ ๊ตฌํ ๊ฐ๋ฅ (๊ตฌํ ์ฝ๋๊ฐ ๋ง์ ์ ์์) |
| ์ฃผ๋ ํ์ฉ | ์ฃผ๋ก ์์ ๊ธฐ๋ฅ ์ถ๊ฐ ๋๋ ๊ฐ๋จํ ๊ธฐ๋ณธ ๋์ ์ ๊ณต | ์ธํฐํ์ด์ค์ ๋ณต์กํ ๋์์ ๊ตฌํํ๋ ๋ฐ ์ฌ์ฉ |
| Object ๋ฉ์๋ ์ ์ฝ | equals, hashCode, toString์ ๊ตฌํ ๋ถ๊ฐ |
equals, hashCode, toString์ ๊ตฌํ ๊ฐ๋ฅ |
| ํ์ ํธํ์ฑ | ๊ธฐ์กด ์ธํฐํ์ด์ค์ ์๋ก์ด ๋ฉ์๋๋ฅผ ์ถ๊ฐํ ๋ ์ ์ฉ | ํด๋์ค ํ์ฅ์ ํตํด ์์๋ ๋ฉ์๋๋ฅผ ๊ตฌํ |
{% hint style="success" %} ์ผ๋ฐ์ ์ผ๋ก ๋ค์ค ๊ตฌํ์ฉ ํ์ ์ผ๋ก๋ ์ธํฐํ์ด์ค๊ฐ ๊ฐ์ฅ ์ ํฉํ๋ค. {% endhint %}
๋ณต์กํ ์ธํฐํ์ด์ค๋ผ ๋ฉด ๊ตฌํํ๋ ์๊ณ ๋ฅผ ๋์ด์ฃผ๋ ๊ณจ๊ฒฉ ๊ตฌํ์ ํจ๊ป ์ ๊ณตํ๋ ๋ฐฉ๋ฒ์ ๊ผญ ๊ณ ๋ คํด๋ณด์. ๊ณจ๊ฒฉ ๊ตฌํ์ ๊ฐ๋ฅํ ํ ์ธํฐํ์ด์ค์ ๋ํดํธ ๋ฉ์๋๋ก ์ ๊ณตํ์ฌ ๊ทธ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๋ชจ๋ ๊ณณ์์ ํ์ฉํ๋๋ก ํ๋ ๊ฒ์ด ์ข๋ค. ๊ฐ๋ฅํ ํ์ด๋ผ๊ณ ํ ์ด์ ๋, ์ธํฐํ์ด์ค์ ๊ฑธ๋ ค ์๋ ๊ตฌํ์์ ์ ์ฝ ๋๋ฌธ์ ๊ณจ๊ฒฉ ๊ตฌํ์ ์ถ์ ํด๋์ค๋ก ์ ๊ณตํ๋ ๊ฒฝ์ฐ๊ฐ ๋ ํํ๊ธฐ ๋๋ฌธ์ด๋ค.
Footnotes
-
์ด๋ํฐ(Adapter)๋ ์ํํธ์จ์ด ๋์์ธ ํจํด ์ค ํ๋๋ก, ์๋ก ํธํ๋์ง ์๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ํด๋์ค๋ค์ด ํจ๊ป ๋์ํ ์ ์๋๋ก ๋ณํํด์ฃผ๋ ์ญํ ์ ํฉ๋๋ค. ์ฆ, ๊ธฐ์กด ํด๋์ค์ ์ธํฐํ์ด์ค๋ฅผ ํด๋ผ์ด์ธํธ๊ฐ ์ํ๋ ๋ค๋ฅธ ์ธํฐํ์ด์ค๋ก ๋ณํํด์ฃผ๋ ์ญํ ์ ํฉ๋๋ค.
์ด ํจํด์ ํธํ๋์ง ์๋ ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง ํด๋์ค๋ค์ด ํจ๊ป ์ฌ์ฉํ ์ ์๋๋ก ์ค๊ฐ์์ ๋ณํ ์์ ์ ์ฒ๋ฆฌํด์ฃผ๋ ์ผ์ข ์ "๋ณํ๊ธฐ" ์ญํ ์ ํ๋ ๊ฒ์ ๋๋ค. ์๋ฐ์์๋ ํนํ ์ปฌ๋ ์ , ์คํธ๋ฆผ, ๋ฐฐ์ด ๋ฑ์ ๋ณํํ ๋ ์ด๋ํฐ ํจํด์ ์์ฃผ ์ฌ์ฉํฉ๋๋ค.
์ด๋ํฐ ํจํด์ ์ฌ์ฉ ๋ชฉ์ :
- ํธํ๋์ง ์๋ ์ธํฐํ์ด์ค๋ฅผ ์ฐ๊ฒฐํ์ฌ ๊ธฐ์กด ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์๋ก์ด ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ํฉ๋๋ค.
- ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ธฐ ์ํด, ๊ธฐ์กด ํด๋์ค๋ฅผ ์์ ํ์ง ์๊ณ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ํ์ฉํ ์ ์๋๋ก ๋์์ค๋๋ค.
์์๋ก ์ค๋ช ํ ์ฝ๋์์ ์ด๋ํฐ์ ์ญํ :
static List<Integer> intArrayAsList(int[] a) { return new AbstractList<>() { @Override public Integer get(int i) { return a[i]; // int ๋ฐฐ์ด์ ๊ฐ์ Integer๋ก ๋ณํํ์ฌ ์ ๊ณต } @Override public Integer set(int i, Integer val) { int oldVal = a[i]; a[i] = val; // Integer ๊ฐ์ int ๋ฐฐ์ด์ ์ ์ฅ return oldVal; } @Override public int size() { return a.length; // ๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ ๋ฆฌ์คํธ์ ํฌ๊ธฐ๋ก ๋ฐํ } }; }์ด ์ฝ๋๋
int[]๋ฐฐ์ด์ ๋ฐ์ **List<Integer>**๋ก ๋ณํํด์ค๋๋ค. ์ฆ, ๋ฐฐ์ด์ ๋ฆฌ์คํธ์ฒ๋ผ ๋ค๋ฃฐ ์ ์๋๋ก ๋ณํํ๋ ์ด๋ํฐ ์ญํ ์ ํฉ๋๋ค.int[]๋ฐฐ์ด์ ๊ธฐ๋ณธ ์๋ฃํ์ ์ฌ์ฉํ๊ณ , **๋ฆฌ์คํธ(List)**๋ ์ ๋ค๋ฆญ ํ์ ์ ์ฌ์ฉํฉ๋๋ค.- ์ด ๋ ๊ฐ์ง๋ ํธํ๋์ง ์๋ ์๋ฃ๊ตฌ์กฐ์ด๋ฏ๋ก, ์ด๋ํฐ ํจํด์ ํตํด ๋ฐฐ์ด์ ๋ฆฌ์คํธ๋ก ๋ณํํ์ฌ ์๋ก ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์๊ฒ ๋ง๋ค์ด ์ค๋๋ค.
์ด๋ํฐ ํจํด์ ์ผ๋ฐ์ ์ธ ๊ตฌ์กฐ:
- ํด๋ผ์ด์ธํธ(Client): ๊ธฐ์กด ํด๋์ค์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ค๋ ์ฝ๋์ ๋๋ค.
- ์ด๋ํฐ(Adaptee): ๊ธฐ์กด ํด๋์ค, ์ฆ ๋ณํํด์ผ ํ๋ ๋์์ ๋๋ค.
- ์ด๋ํฐ(Adapter): ์ด๋ํฐ์ ์ธํฐํ์ด์ค๋ฅผ ํด๋ผ์ด์ธํธ๊ฐ ์ํ๋ ์ธํฐํ์ด์ค๋ก ๋ณํํ๋ ํด๋์ค์ ๋๋ค.
์ด๋ํฐ ํจํด์ ๊ฐ๋จํ ์:
// ๊ธฐ์กด ํด๋์ค class OldSystem { public void oldMethod() { System.out.println("Old method is called"); } } // ์ด๋ํฐ ์ธํฐํ์ด์ค interface NewSystem { void newMethod(); } // ์ด๋ํฐ ํด๋์ค class Adapter implements NewSystem { private OldSystem oldSystem; public Adapter(OldSystem oldSystem) { this.oldSystem = oldSystem; } @Override public void newMethod() { oldSystem.oldMethod(); // ๊ธฐ์กด ๋ฉ์๋๋ฅผ ์๋ก์ด ๋ฉ์๋๋ก ๋ณํ } } // ํด๋ผ์ด์ธํธ ์ฝ๋ public class Main { public static void main(String[] args) { OldSystem oldSystem = new OldSystem(); NewSystem adapter = new Adapter(oldSystem); adapter.newMethod(); // ์ด๋ํฐ๋ฅผ ํตํด oldMethod()๋ฅผ ํธ์ถ } }์ ์์์์,
OldSystem์ ๊ธฐ์กด ์์คํ ์ ํํํ๊ณAdapter๋ ์ด๋ฅผNewSystem์ธํฐํ์ด์ค์ ๋ง๊ฒ ๋ณํํด์ค๋๋ค. ์ด๋ ๊ฒ ํ๋ฉดOldSystem์ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ ๋ ์๋ก์ด ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค. โฉ