[{"data":1,"prerenderedAt":638},["ShallowReactive",2],{"post-document:\u002Fjava\u002Foop\u002F2026\u002F08\u002F10\u002Fjava-inheritance-interface\u002F":3},{"id":4,"title":5,"body":6,"categories":616,"date":618,"description":619,"extension":620,"image":621,"key_concepts":621,"last_modified_at":621,"legacyPath":622,"meta":623,"navigation":120,"part":625,"path":626,"published":120,"robots":621,"seo":627,"series":628,"stem":629,"strengths":621,"summary":621,"tags":630,"tradeoffs":621,"__hash__":637},"posts\u002Fposts\u002FBackend\u002FJAVA\u002Foop\u002F2026-08-10-java-inheritance-interface.md","Java 객체지향 Part 4: 상속과 인터페이스",{"type":7,"value":8,"toc":609},"minimark",[9,13,18,31,34,38,44,54,83,91,329,337,340,352,356,363,367,370,516,519,591,605],[10,11,5],"h2",{"id":12},"java-객체지향-part-4-상속과-인터페이스",[14,15,17],"h3",{"id":16},"_1-상속","1. 상속",[19,20,21,22,26,27,30],"p",{},"상속은 ",[23,24,25],"code",{},"Superclass","의 상태와 동작을 ",[23,28,29],{},"Subclass","가 물려받아 재사용하고 확장하는 방법이다.",[19,32,33],{},"일반적으로 기능을 물려받는 쪽을 자식 클래스, 물려주는 쪽을 부모 클래스라고 한다.",[14,35,37],{"id":36},"_2-인터페이스","2. 인터페이스",[39,40,41],"blockquote",{},[19,42,43],{},"공통 규칙을 정의하고, 서로 다른 구현 객체를 같은 타입으로 처리해 다형성을 활용할 수 있다.",[45,46,47,51],"ul",{},[48,49,50],"li",{},"클래스가 구현해야 하는 메서드의 규약(Contract)를 정의하는 참조 타입",[48,52,53],{},"메서드 시그니쳐 (이름, 매개변수, 반환형)만 선언하고 실제 구현은 인터페이스를 구현한 클래스가 담당",[55,56,61],"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-java shiki shiki-themes github-light github-dark","public interface Animal {\n    void makeSound();\n}\n","java","",[23,62,63,71,77],{"__ignoreMap":60},[64,65,68],"span",{"class":66,"line":67},"line",1,[64,69,70],{},"public interface Animal {\n",[64,72,74],{"class":66,"line":73},2,[64,75,76],{},"    void makeSound();\n",[64,78,80],{"class":66,"line":79},3,[64,81,82],{},"}\n",[45,84,85,88],{},[48,86,87],{},"class 키워드 대신 interface 키워드 활용",[48,89,90],{},"메소드의 정의만 해두고 구현체는 존재하지 않음",[55,92,94],{"className":57,"code":93,"language":59,"meta":60,"style":60},"\u002F\u002F 1. 인터페이스 선언\ninterface Animal {\n    void makeSound();\n}\n\n\u002F\u002F 2. Dog 구현체\nclass Dog implements Animal {\n\n    @Override\n    public void makeSound() {\n        System.out.println(\"멍멍!\");\n    }\n}\n\n\u002F\u002F 3. Cat 구현체\nclass Cat implements Animal {\n\n    @Override\n    public void makeSound() {\n        System.out.println(\"야옹!\");\n    }\n}\n\n\u002F\u002F 4. Main 클래스\npublic class AnimalSound {\n    public static void main(String[] args) {\n        \u002F\u002F Animal 타입으로 각각의 구현 객체를 참조\n        Animal dog = new Dog();\n        Animal cat = new Cat();\n\n        dog.makeSound(); \u002F\u002F 멍멍!\n        cat.makeSound(); \u002F\u002F 야옹!\n\n        \u002F\u002F Animal 타입을 받는 메서드에 Cat 객체 전달\n        handleAnimalSound(cat);\n    }\n\n    \u002F\u002F Animal을 구현한 객체라면 전달 가능\n    static void handleAnimalSound(Animal animal) {\n        animal.makeSound();\n    }\n}\n",[23,95,96,101,106,110,115,122,128,134,139,145,151,157,163,168,173,179,185,190,195,200,206,211,216,221,227,233,239,245,251,257,262,268,274,279,285,291,296,301,307,313,319,324],{"__ignoreMap":60},[64,97,98],{"class":66,"line":67},[64,99,100],{},"\u002F\u002F 1. 인터페이스 선언\n",[64,102,103],{"class":66,"line":73},[64,104,105],{},"interface Animal {\n",[64,107,108],{"class":66,"line":79},[64,109,76],{},[64,111,113],{"class":66,"line":112},4,[64,114,82],{},[64,116,118],{"class":66,"line":117},5,[64,119,121],{"emptyLinePlaceholder":120},true,"\n",[64,123,125],{"class":66,"line":124},6,[64,126,127],{},"\u002F\u002F 2. Dog 구현체\n",[64,129,131],{"class":66,"line":130},7,[64,132,133],{},"class Dog implements Animal {\n",[64,135,137],{"class":66,"line":136},8,[64,138,121],{"emptyLinePlaceholder":120},[64,140,142],{"class":66,"line":141},9,[64,143,144],{},"    @Override\n",[64,146,148],{"class":66,"line":147},10,[64,149,150],{},"    public void makeSound() {\n",[64,152,154],{"class":66,"line":153},11,[64,155,156],{},"        System.out.println(\"멍멍!\");\n",[64,158,160],{"class":66,"line":159},12,[64,161,162],{},"    }\n",[64,164,166],{"class":66,"line":165},13,[64,167,82],{},[64,169,171],{"class":66,"line":170},14,[64,172,121],{"emptyLinePlaceholder":120},[64,174,176],{"class":66,"line":175},15,[64,177,178],{},"\u002F\u002F 3. Cat 구현체\n",[64,180,182],{"class":66,"line":181},16,[64,183,184],{},"class Cat implements Animal {\n",[64,186,188],{"class":66,"line":187},17,[64,189,121],{"emptyLinePlaceholder":120},[64,191,193],{"class":66,"line":192},18,[64,194,144],{},[64,196,198],{"class":66,"line":197},19,[64,199,150],{},[64,201,203],{"class":66,"line":202},20,[64,204,205],{},"        System.out.println(\"야옹!\");\n",[64,207,209],{"class":66,"line":208},21,[64,210,162],{},[64,212,214],{"class":66,"line":213},22,[64,215,82],{},[64,217,219],{"class":66,"line":218},23,[64,220,121],{"emptyLinePlaceholder":120},[64,222,224],{"class":66,"line":223},24,[64,225,226],{},"\u002F\u002F 4. Main 클래스\n",[64,228,230],{"class":66,"line":229},25,[64,231,232],{},"public class AnimalSound {\n",[64,234,236],{"class":66,"line":235},26,[64,237,238],{},"    public static void main(String[] args) {\n",[64,240,242],{"class":66,"line":241},27,[64,243,244],{},"        \u002F\u002F Animal 타입으로 각각의 구현 객체를 참조\n",[64,246,248],{"class":66,"line":247},28,[64,249,250],{},"        Animal dog = new Dog();\n",[64,252,254],{"class":66,"line":253},29,[64,255,256],{},"        Animal cat = new Cat();\n",[64,258,260],{"class":66,"line":259},30,[64,261,121],{"emptyLinePlaceholder":120},[64,263,265],{"class":66,"line":264},31,[64,266,267],{},"        dog.makeSound(); \u002F\u002F 멍멍!\n",[64,269,271],{"class":66,"line":270},32,[64,272,273],{},"        cat.makeSound(); \u002F\u002F 야옹!\n",[64,275,277],{"class":66,"line":276},33,[64,278,121],{"emptyLinePlaceholder":120},[64,280,282],{"class":66,"line":281},34,[64,283,284],{},"        \u002F\u002F Animal 타입을 받는 메서드에 Cat 객체 전달\n",[64,286,288],{"class":66,"line":287},35,[64,289,290],{},"        handleAnimalSound(cat);\n",[64,292,294],{"class":66,"line":293},36,[64,295,162],{},[64,297,299],{"class":66,"line":298},37,[64,300,121],{"emptyLinePlaceholder":120},[64,302,304],{"class":66,"line":303},38,[64,305,306],{},"    \u002F\u002F Animal을 구현한 객체라면 전달 가능\n",[64,308,310],{"class":66,"line":309},39,[64,311,312],{},"    static void handleAnimalSound(Animal animal) {\n",[64,314,316],{"class":66,"line":315},40,[64,317,318],{},"        animal.makeSound();\n",[64,320,322],{"class":66,"line":321},41,[64,323,162],{},[64,325,327],{"class":66,"line":326},42,[64,328,82],{},[330,331,333,336],"h4",{"id":332},"override-annotation-사용-이유",[23,334,335],{},"@Override"," Annotation 사용 이유",[19,338,339],{},"다음과 같은 이유로 사용 권고",[341,342,343,346,349],"ol",{},[48,344,345],{},"컴파일러 체크 기능",[48,347,348],{},"가독성향상",[48,350,351],{},"리팩토링 안정성",[330,353,355],{"id":354},"인터페이스-메서드-접근자","인터페이스 메서드 접근자",[19,357,358,359,362],{},"인터페이스의 추상 메서드는 기본적으로 ",[23,360,361],{},"public abstract","이며, 명시하지 않아도 자동으로 적용된다.",[14,364,366],{"id":365},"_3-다중-상속","3. 다중 상속",[19,368,369],{},"Java 클래스는 다중 상속을 지원하지 않지만, 여러 인터페이스를 동시에 구현할 수 있다.",[55,371,373],{"className":57,"code":372,"language":59,"meta":60,"style":60},"interface Flyable {\n    void fly();\n}\n\ninterface Swimmable {\n    void swim();\n}\n\nabstract class Bird {\n    public void moving() {\n        System.out.println(\"움직입니다!\");\n    }\n}\n\n\u002F\u002F 하나의 클래스가 두 인터페이스를 모두 구현\nclass Duck extends Bird implements Flyable, Swimmable {\n    @Override\n    public void fly() {\n        System.out.println(\"오리가 하늘을 납니다!\");\n    }\n\n    @Override\n    public void swim() {\n        System.out.println(\"오리가 물 위를 헤엄칩니다!\");\n    }\n}\n\nDuck duck = new Duck();\nduck.fly();\nduck.swim();\nduck.moving();\n",[23,374,375,380,385,389,393,398,403,407,411,416,421,426,430,434,438,443,448,452,457,462,466,470,474,479,484,488,492,496,501,506,511],{"__ignoreMap":60},[64,376,377],{"class":66,"line":67},[64,378,379],{},"interface Flyable {\n",[64,381,382],{"class":66,"line":73},[64,383,384],{},"    void fly();\n",[64,386,387],{"class":66,"line":79},[64,388,82],{},[64,390,391],{"class":66,"line":112},[64,392,121],{"emptyLinePlaceholder":120},[64,394,395],{"class":66,"line":117},[64,396,397],{},"interface Swimmable {\n",[64,399,400],{"class":66,"line":124},[64,401,402],{},"    void swim();\n",[64,404,405],{"class":66,"line":130},[64,406,82],{},[64,408,409],{"class":66,"line":136},[64,410,121],{"emptyLinePlaceholder":120},[64,412,413],{"class":66,"line":141},[64,414,415],{},"abstract class Bird {\n",[64,417,418],{"class":66,"line":147},[64,419,420],{},"    public void moving() {\n",[64,422,423],{"class":66,"line":153},[64,424,425],{},"        System.out.println(\"움직입니다!\");\n",[64,427,428],{"class":66,"line":159},[64,429,162],{},[64,431,432],{"class":66,"line":165},[64,433,82],{},[64,435,436],{"class":66,"line":170},[64,437,121],{"emptyLinePlaceholder":120},[64,439,440],{"class":66,"line":175},[64,441,442],{},"\u002F\u002F 하나의 클래스가 두 인터페이스를 모두 구현\n",[64,444,445],{"class":66,"line":181},[64,446,447],{},"class Duck extends Bird implements Flyable, Swimmable {\n",[64,449,450],{"class":66,"line":187},[64,451,144],{},[64,453,454],{"class":66,"line":192},[64,455,456],{},"    public void fly() {\n",[64,458,459],{"class":66,"line":197},[64,460,461],{},"        System.out.println(\"오리가 하늘을 납니다!\");\n",[64,463,464],{"class":66,"line":202},[64,465,162],{},[64,467,468],{"class":66,"line":208},[64,469,121],{"emptyLinePlaceholder":120},[64,471,472],{"class":66,"line":213},[64,473,144],{},[64,475,476],{"class":66,"line":218},[64,477,478],{},"    public void swim() {\n",[64,480,481],{"class":66,"line":223},[64,482,483],{},"        System.out.println(\"오리가 물 위를 헤엄칩니다!\");\n",[64,485,486],{"class":66,"line":229},[64,487,162],{},[64,489,490],{"class":66,"line":235},[64,491,82],{},[64,493,494],{"class":66,"line":241},[64,495,121],{"emptyLinePlaceholder":120},[64,497,498],{"class":66,"line":247},[64,499,500],{},"Duck duck = new Duck();\n",[64,502,503],{"class":66,"line":253},[64,504,505],{},"duck.fly();\n",[64,507,508],{"class":66,"line":259},[64,509,510],{},"duck.swim();\n",[64,512,513],{"class":66,"line":264},[64,514,515],{},"duck.moving();\n",[19,517,518],{},"클래스는 다중 상속을 지원하지 않는다.",[55,520,522],{"className":57,"code":521,"language":59,"meta":60,"style":60},"class A {\n    void print() {\n        System.out.println(\"A\");\n    }\n}\n\nclass B {\n    void print() {\n        System.out.println(\"B\");\n    }\n}\n\n\u002F\u002F 컴파일 오류: Java 클래스는 두 클래스를 동시에 상속할 수 없다.\nclass C extends A, B {\n}\n",[23,523,524,529,534,539,543,547,551,556,560,565,569,573,577,582,587],{"__ignoreMap":60},[64,525,526],{"class":66,"line":67},[64,527,528],{},"class A {\n",[64,530,531],{"class":66,"line":73},[64,532,533],{},"    void print() {\n",[64,535,536],{"class":66,"line":79},[64,537,538],{},"        System.out.println(\"A\");\n",[64,540,541],{"class":66,"line":112},[64,542,162],{},[64,544,545],{"class":66,"line":117},[64,546,82],{},[64,548,549],{"class":66,"line":124},[64,550,121],{"emptyLinePlaceholder":120},[64,552,553],{"class":66,"line":130},[64,554,555],{},"class B {\n",[64,557,558],{"class":66,"line":136},[64,559,533],{},[64,561,562],{"class":66,"line":141},[64,563,564],{},"        System.out.println(\"B\");\n",[64,566,567],{"class":66,"line":147},[64,568,162],{},[64,570,571],{"class":66,"line":153},[64,572,82],{},[64,574,575],{"class":66,"line":159},[64,576,121],{"emptyLinePlaceholder":120},[64,578,579],{"class":66,"line":165},[64,580,581],{},"\u002F\u002F 컴파일 오류: Java 클래스는 두 클래스를 동시에 상속할 수 없다.\n",[64,583,584],{"class":66,"line":170},[64,585,586],{},"class C extends A, B {\n",[64,588,589],{"class":66,"line":175},[64,590,82],{},[19,592,593,596,597,600,601,604],{},[23,594,595],{},"A","와 ",[23,598,599],{},"B","에 같은 ",[23,602,603],{},"print()"," 메서드가 있으면 어느 메서드를 물려받아야 하는지 모호해지기 때문에 클래스 다중 상속을 허용하지 않는다.",[606,607,608],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":60,"searchDepth":73,"depth":73,"links":610},[611],{"id":12,"depth":73,"text":5,"children":612},[613,614,615],{"id":16,"depth":79,"text":17},{"id":36,"depth":79,"text":37},{"id":365,"depth":79,"text":366},[59,617],"oop","2026-08-10 13:20:00 +0900","Java의 상속, 인터페이스, Override 애너테이션과 다중 구현 방식을 예제로 정리한다.","md",null,"\u002Fjava\u002Foop\u002F2026\u002F08\u002F10\u002Fjava-inheritance-interface\u002F",{"layout":624},"post","4","\u002Fposts\u002Fbackend\u002Fjava\u002Foop\u002F2026-08-10-java-inheritance-interface",{"title":5,"description":619},"Java 객체지향","posts\u002FBackend\u002FJAVA\u002Foop\u002F2026-08-10-java-inheritance-interface",[631,632,633,634,635,636],"Java","OOP","Inheritance","Interface","Override","Polymorphism","PHgErf1IH5AbeYBdawsE5mVyjFwcEoofYiyEn0TtafQ",1788744784922]