๋ชฉํ
์๋ฐ์ ์ธํฐํ์ด์ค์ ๋ํด ํ์ตํ์ธ์.
ํ์ตํ ๊ฒ (ํ์)
- ์ธํฐํ์ด์ค ์ ์ํ๋ ๋ฐฉ๋ฒ
- ์ธํฐํ์ด์ค ๊ตฌํํ๋ ๋ฐฉ๋ฒ
- ์ธํฐํ์ด์ค ๋ ํผ๋ฐ์ค๋ฅผ ํตํด ๊ตฌํ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
- ์ธํฐํ์ด์ค ์์
- ์ธํฐํ์ด์ค์ ๊ธฐ๋ณธ ๋ฉ์๋ (Default Method), ์๋ฐ 8
- ์ธํฐํ์ด์ค์ static ๋ฉ์๋, ์๋ฐ 8
- ์ธํฐํ์ด์ค์ private ๋ฉ์๋, ์๋ฐ 9
์ถ์ ํด๋์ค์ ์ธํฐํ์ด์ค์ ์ฐจ์ด์
์ถ์ ํด๋์ค(abstract class) | ์ธํฐํ์ด์ค(interface) |
1. ์ผ๋ฐ ๋ฉ์๋ ํฌํจ๊ฐ๋ฅ | 1. ๋ชจ๋ ๋ฉ์๋๋ ์ถ์๋ฉ์๋ ์๋ฐ 8 ์ดํ ๋ถํฐ default ,static ๋ฉ์๋ ์ถ๊ฐ๊ฐ๋ฅ |
2. ๋ค์ค์์ ๋ถ๊ฐ๋ฅ | 2. ๋ค์ค์์ ๊ฐ๋ฅ |
3. ์์, ๋ณ์ ํ๋ ํฌํจ๊ฐ๋ฅ | 3. ์์ํ๋๋ง ํฌํจ๊ฐ๋ฅ |
์ถ์ ํด๋์ค๋ IS - A ์ด๋ค. ( ๊ฐ๋ ๋๋ฌผ์ด๋ค. )
์ธํฐํ์ด์ค๋ HAS - A ์ด๋ค. ( ๊ฐ๋ ์์์ ํ ์ ์๋ค. )
๊ฐ๋ ๋๋ฌผ์ธ ๊ฒ์ ํ์คํ์ง๋ง, ์ด๋ค ๊ฐ๋ ์์์ ํ ์๋ ์๊ณ , ๋ชป ํ ์๋ ์๋ค.
์ธํฐํ์ด์ค ์ ์ํ๋ ๋ฐฉ๋ฒ
- ์ธํฐํ์ด์ค๋ฅผ ์ ์ํ ๋์๋ ํค์๋ interface ๋ฅผ ์ฌ์ฉํ๋ค.
- ๋ชจ๋ ํ๋๋ public final static ์ด๋ค.
- ๋ชจ๋ ๋ฉ์๋๋ public abstract ์ด๋ค.
๋ณ์ a์๋ final static ์ ๋ถ์ฌ์ฃผ๊ณ , b์๋ ์๋ต์ ํด๋ดค๋ค.
๋ฉ์๋ cry์ feed๋ ๋ง์ฐฌ๊ฐ์ง๋ก ํ๋๋ ์๋ต์ ํ๋ค.
๊ทธ๋ ์ง๋ง ์ปดํ์ผ ์๋ฌ๊ฐ ๋์ง ์๊ณ ์ ์คํ์ด ๋์๋ค. ์๊ทธ๋ด๊น??
์๋ ๋ฐ์ดํธ ์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด ๋ชจ๋ ํ๋, ๋ฉ์๋์ ์๋์ผ๋ก ์ถ๊ฐ๊ฐ ๋์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก ์ถ๊ฐ๋ฅผ ํด์ค๋ค. ์ฆ, ์๋ต์ด ๊ฐ๋ฅํ๋ค๋ ์๋ฏธ์ด๋ค.
์ธํฐํ์ด์ค ๊ตฌํํ๋ ๋ฐฉ๋ฒ
๊ตฌํ์ ํ ๋์๋ ํด๋์ค๋ฅผ ์์๋ฐ๋ ๊ฒ์ฒ๋ผ extends(์์) ๋์ implements(๊ตฌํ) ๋ฅผ ์ฌ์ฉํ๋ค.
public interface Animal {
void cry();
}
public class Cat implements Animal {
public void cry() {
System.out.println("๋์น๋์น");
}
}
์ธํฐํ์ด์ค ๋ ํผ๋ฐ์ค๋ฅผ ํตํด ๊ตฌํ์ฒด๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
์ธํฐํ์ด์ค๋ ๋คํ์ฑ์ ์ด์ฉํด ๊ตฌํํ ์ ์๋ค.
์์ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๋ถ๋ชจํด๋์ค์ ์ฐธ์กฐ๋ณ์๋ก ์ฐธ์กฐํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค๋ ์๋ฏธ์ด๋ค.
์ธํฐํ์ด์ค๋ ๊ฐ์ฒด์ ํ์ ์ผ๋ก๋ง ์ฌ์ฉ๋๋ค.
์ด ๋ง์ ์์์์์ ๊ฐ์ด ๋ณ์ ์ ์ธ ์์ ๊ฐ์ฒด์ ํ์ ์ผ๋ก ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ ์ ์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ธํฐํ์ด์ค ํ์ ์ด ์์ ๋๋ ํญ์ ์ธํฐํ์ด์ค ํ์ ๊ธฐ๋ฐ์ผ๋ก ์ฝ๋ฉํด์ผ ํ๋ค.
List ์ธํฐํ์ด์ค๋ฅผ ์๋ฅผ ๋ค์ด๋ณด์.
List๋ฅผ ๊ตฌํํ ๊ตฌํ์ฒด๋ค์ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์๋ค. (์: ArrayList, LinkedList ..๋ฑ๋ฑ) ์๋์ ๊ฐ์ด ์ ์ธํ ์ ์๋ค.
// ์ข์ ์ : ๊ฐ์ฒด ํ์
์ ์ธํฐํ์ด์ค๋ก ์ ์ธ.
List<Integer> list = new ArrayList<Integer>();
// ๋์ ์ : ๊ฐ์ฒด ํ์
์ ํด๋์ค๋ก ์ ์ธ
ArrayList<Integer> list = new ArrayList<Integer>();
์ธํฐํ์ด์ค ๋ก ๊ฐ์ฒด ํ์ ์ ์ ์ธํ๊ฒ ๋๋ค๋ฉด, ์ถํ์ ํด๋์ค๋ฅผ ๊ต์ฒดํ ์ผ์ด ์๊ฒผ์ ์์ ํด๋์ค๋ง ๋ฐ๊ฟ๋ผ๋ฉด ๋๋ค. ์์คํ ์ด ์ ์ฐํด์ง๊ฒ ๋ง๋๋ ๊ฒ์ด๋ค.
์ต๋ช ๊ตฌํ ๊ฐ์ฒด
์ธํฐํ์ด์ค๋ ์์น์ ์ผ๋ก ๊ฐ์ฒดํ ๋ ์ ์์ง๋ง, ์ต๋ช ๊ฐ์ฒด๋ฅผ ํตํด์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ์ผํ์ฉ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๋ค.
public interface MusicPlayer {
void play();
}
// .. main
MusicPlayer mp = new MusicPlayer() {
@Override
public void play() {
System.out.println("play the music!");
}
};
์ธํฐํ์ด์ค์ ์ ์ธ๋ ์ถ์ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ ํด์ฃผ๋ฉด ๋๋ค.
์ธํฐํ์ด์ค ์์
- ์ธํฐํ์ด์ค ๋ผ๋ฆฌ ์์์ ํ ๋์๋ extends ํค์๋๋ฅผ ์ฌ์ฉํ๋ค.
public interface A {
...
}
public interface B {
...
}
/* ๋ค์ค ์์ ๊ฐ๋ฅ */
public interface C extends A, B {
...
}
- ์ธํฐํ์ด์ค๋ ๋ค์ค ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
- implements A, B, C ...
public interface Animal {
void cry();
}
public interface Pet {
void play();
}
public class Cat implement Animal, Pet {
public void cry() {
System.out.println("๋์น");
}
public void play() {
System.out.println("play!!");
}
}
- ํด๋์ค์ ์ธํฐํ์ด์ค๋ฅผ ๋์์ ์์(extends), ๊ตฌํ(implements)ํ ์ ์๋ค.
public class Animal {
public void cry() {
}
}
public interface Pet {
void play();
}
public class Cat extends Animal implements Pet {
public void cry() {
System.out.println("๋์น");
}
public void play() {
System.out.println("play!!");
}
}
์ธํฐํ์ด์ค์ ๊ธฐ๋ณธ ๋ฉ์๋ (Default Method), ์๋ฐ 8
- ์๋ฐ 8 ์ดํ๋ก ์ธํฐํ์ด์ค๋ ๊ธฐ๋ณธ ๋ฉ์๋(Default Method) ๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋์๋ค.
- ๊ธฐ์กด์๋ ์ธํฐํ์ด์ค ๋ด์ ์๋ ๋ฉ์๋๋ฅผ ์ ๋ถ ๋ค ์ค๋ฒ๋ผ์ด๋ฉ ํด์ผ๋ง ํ์ง๋ง, ๊ธฐ๋ณธ ๋ฉ์๋๋ ๋ฐ๋์ ๊ตฌํํ ํ์ ์๋ค.
- ๊ธฐ๋ณธ ๋ฉ์๋ (Defalut Method) ๋ ๊ตฌํ๋ถ(body) ๋ฅผ ๊ฐ์ง๊ฒ ๋๋ค.
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๋์๋ ํญ์ ์ถ์ ๋ฉ์๋๋ฅผ ์ ๋ถ ๋ค ์ค๋ฒ๋ผ์ด๋ฉ ํด์ผ๋ง ํ๋ค.
ํ์ง๋ง ๋ด๊ฐ ํ์ํ ๋ฉ์๋(๊ธฐ๋ฅ)๋ง ์ค๋ฒ๋ผ์ด๋ฉ ํ๊ณ ์ถ๋ค๋ฉด??
(๊ธฐ์กด ๋ฐฉ๋ฒ) : ์ค๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ Adapter ํด๋์ค๋ฅผ ์์ฑํ๋ค.
public interface JoinMember {
void preJoin();
void afterJoin();
}
๋ง์ฝ ๋ด๊ฐ preJoin ๋ง ๊ตฌํํ๊ณ ์ถ๋ค๋ฉด? ๋ชจ๋ ๋ฉ์๋๋ฅผ ์ ๋ถ ๋น ๋ฉ์๋๋ก ์ ์ํ๋ค.
public class MemberAdapter implements JoinMember {
public void preJoin() { // ๋น ๋ฉ์๋ ์ ์ }
public void afterJoin() { // ๋น ๋ฉ์๋ ์ ์ }
}
MemberAdapter๋ฅผ ์์๋ฐ์์ ํ์ํ ๋ฉ์๋๋ง ์ค๋ฒ๋ผ์ด๋ฉ ํ๋ฉด ๋๋ค!
public class HelloMember extends MemberAdapter {
/* ํ์ํ ๊ธฐ๋ฅ๋ง ์ค๋ฒ๋ผ์ด๋ฉ */
@Override
public void preJoin() {
System.out.println("hello, member");
}
}
( ์๋ฐ 8 ์ดํ default ๋ฉ์๋ ์ฌ์ฉ ๊ฐ๋ฅ ! )
public interface Camera {
void takePhoto();
/* default Method */
default void takeVideo() {
System.out.println("take a Video!");
}
}
public interface MusicPlayer {
void playMusic();
}
public class SmartPhone implements Camera, MusicPlayer{
@Override
public void takePhoto() {
}
// takeVideo ๋ฉ์๋๋ฅผ ๊ตฌํํ์ง ์์๋ ๋๋ค.
@Override
public void playMusic() {
}
}
๋ง์ฝ interface์ ๋์ผํ default ๋ฉ์๋๊ฐ ์ ์ธ๋์ด ์๋ค๋ฉด?
์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์, ๋ฌด์กฐ๊ฑด overriding์ ํด์ผํ๋ค.
public interface Camera {
void takePhoto();
default void takeVideo() {
System.out.println("take a Video!");
}
default void print() {
System.out.println("camera");
}
}
public interface MusicPlayer {
void playMusic();
default void print() {
System.out.println("Music");
}
}
public class SmartPhone implements Camera, MusicPlayer{
@Override
public void takePhoto() {
}
// print()๋ฅผ ๊ตฌํํ์ง ์์ผ๋ฉด?
@Override
public void playMusic() {
}
}
๋์ผํ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉ(Overriding) ํ์ง ์์ผ๋ฉด? ์๋์ฒ๋ผ ์ปดํ์ผ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค!
์ธํฐํ์ด์ค์ static ๋ฉ์๋, ์๋ฐ 8
์ธํฐํ์ด์ค์ ์ถ์์ฑ์ ํด์น๋ค๋ ์ด์ ๋ก ์ ์ฝ์ ๊ฑธ์ด์์ง๋ง, ์๋ฐ 8 ๋ถํฐ๋ ๊ฐ๋ฐ์ ์ ์ฐ์ฑ์ ์ํด static ๋ฉ์๋๋ฅผ ์ ์ธํ ์ ์๊ฒ ๋์๋ค.
- static ๋ฉ์๋๋ ์ค๋ฒ๋ผ์ด๋ฉ์ด ๋ถ๊ฐ!
- default ๋ abstract ๋ฉ์๋๋ ๋ชจ๋ instance ๋ฉ์๋ ์ฒ๋ผ ์ฒ๋ฆฌ๋๋ค.
- default ๋ฉ์๋๋ฅผ static ๋ฉ์๋๋ก ๋ฎ์ผ๋ ค ํ๋ฉด ์๋๋ค -> ์ปดํ์ผ ์๋ฌ!
public interface MusicPlayer {
static void info() {
System.out.println("Music Player!");
}
}
public class Main {
public static void main(String[] args){
MusicPlayer.info(); // Music Player!
}
}
์ธํฐํ์ด์ค์ private ๋ฉ์๋, ์๋ฐ 9
์๋ฐ 9 ์ดํ๋ก private ๋ฉ์๋ ์ ๊ทผ์ ์ด์๋ ์ฌ์ฉํ ์ ์๊ฒ ๋์๋ค.
public interface Camera {
default void print() {
..
}
private void info() {
..
}
}
์ธํฐํ์ด์ค์์๋ default, static, private ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์๋๋ฐ, ์ถ์ํด๋์ค๊ฐ ํ์๊ฐ ์์ด์ง๋ ๊ฒ์ธ๊ฐ?
- ์ํ ์กด์ฌ ์ฌ๋ถ์ ๋ฐ๋ผ์
์ธํฐํ์ด์ค๋ ํ๋์ ์์๋ง ์ ์ธ ๊ฐ๋ฅํ๊ณ , private String ์ฒ๋ผ ์ ์ธ์ด ๋ถ๊ฐ๋ฅ ํ๋ค!
์ถ์ ํด๋์ค๋ ์คํ ์ค ๋ณ๊ฒฝ์ด ํ์ํ ๋, ์ฌ์ฉํ ์ ์๋ค.
public abstract clas AbstractJoinMember implements JoinMember {
private String message = "hello"; // ์ด๋ฐ๊ฒ ๊ฐ๋ฅ
@Override
public void preJoin() {
System.out.println(message);
}
public void setMessage(String message) {
this.message = message; // ์ด๋ฐ๊ฒ ๊ฐ๋ฅ
}
}
์ด๋ฐ ์ ๋๋ฌธ์ ์์ง ๊น์ง๋ ์ถ์ ํด๋์ค์๋ ํจ์ฉ๊ฐ์น๊ฐ ์๋ค!
์ ๋ฆฌ
public interface ์ธํฐํ์ด์ค๋ช
{
// ์์ : ๊ฐ์ ์ ํด์คํ
๋ ์ ๊ณตํด์ฃผ๋ ๊ฐ์ ๋ณ๊ฒฝํ์ง ๋ง๊ณ ์ฌ์ฉํด๋ผ.
ํ์
์์๋ช
= ๊ฐ;
// ์ถ์ ๋ฉ์๋ : ๊ฐ์ด๋๋ง ์คํ
๋ ๊ตฌํ๋ถ๋ ์์์ ๊ตฌํํด๋ผ.
ํ์
๋ฉ์๋๋ช
(๋งค๊ฐ๋ณ์ ...);
// ๋ํดํธ ๋ฉ์๋ : ๊ตฌํ๋ถ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธํฐํ์ด์ค์์ ์ ๊ณตํ์ง๋ง, ํ์ํ๋ฉด ์ค๋ฒ๋ผ์ด๋ฉํด์ ์ฌ๊ตฌํํด๋ผ.
default ํ์
๋ฉ์๋๋ช
(๋งค๊ฐ๋ณ์ ...) {
// ๊ตฌํ๋ถ
}
// ์ ์ ๋ฉ์๋ : ์ธํฐํ์ด์ค์์ ์ ๊ณตํด์ฃผ๋ ๊ฒ์ผ๋ก ๋ฌด์กฐ๊ฑด ์ฌ์ฉ. ์ค๋ฒ๋ผ์ด๋ฉ ๋ถ๊ฐ!
static ํ์
๋ฉ์๋๋ช
(๋งค๊ฐ๋ณ์ ...) {
// ๊ตฌํ๋ถ
}
}
REFERENCES
- www.notion.so/Java-8-0cc8c251d5374ac882a4f22fa07c4e6a
- github.com/ByungJun25/study/tree/main/java/whiteship-study/8week#Interface-%EB%A0%88%ED%8D%BC%EB%9F%B0%EC%8A%A4%EB%A5%BC-%ED%86%B5%ED%95%B4-%EA%B5%AC%ED%98%84%EC%B2%B4-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
- kils-log-of-develop.tistory.com/437
- leegicheol.github.io/whiteship-live-study/whiteship-live-study-08-interface/
- www.tcpschool.com/java/java_polymorphism_interface
- docs.oracle.com/javase/tutorial/java/IandI/interfaceAsType.html
- velog.io/@jaden_94/8%EC%A3%BC%EC%B0%A8-%ED%95%AD%ED%95%B4%EC%9D%BC%EC%A7%80#5-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EB%A9%94%EC%86%8C%EB%93%9C-default-method-%EC%9E%90%EB%B0%94-8