
❓Java와 Kotlin의 상속 차이점?
Java에서의 상속
- 클래스 상속:
- 단일 상속: 한 클래스는 단 하나의 클래스만 상속받을 수 있음
- 구문: class Child extends Parent
class Parent { // 부모 클래스 내용 } class Child extends Parent { // 자식 클래스 내용 } - 인터페이스 상속:
- 다중 구현: 한 클래스는 여러 인터페이스를 구현할 수 있음
- 구문: class Child extends Parent implements Interface1, Interface2
interface Interface1 { void doSomething(); } interface Interface2 { void doSomethingElse(); } class Child extends Parent implements Interface1, Interface2 { @Override public void doSomething() { // 구현 내용 } @Override public void doSomethingElse() { // 구현 내용 } } - 클래스와 인터페이스 동시 상속:
- 한 클래스는 하나의 클래스를 상속받고 여러 인터페이스를 구현할 수 있음
class Parent { // 부모 클래스 내용 } interface Interface1 { void doSomething(); } interface Interface2 { void doSomethingElse(); } class Child extends Parent implements Interface1, Interface2 { @Override public void doSomething() { // 구현 내용 } @Override public void doSomethingElse() { // 구현 내용 } }
Kotlin에서의 상속
- 클래스 상속:
- 단일 상속: Kotlin에서도 클래스는 단 하나의 클래스만 상속받을 수 있음
- 구문: class Child : Parent()
open class Parent { // 부모 클래스 내용 } class Child : Parent() { // 자식 클래스 내용 } - 인터페이스 상속:
- 다중 구현: Kotlin에서도 한 클래스는 여러 인터페이스를 구현할 수 있음
- 구문: class Child : Interface1, Interface2
interface Interface1 { fun doSomething() } interface Interface2 { fun doSomethingElse() } class Child : Interface1, Interface2 { override fun doSomething() { // 구현 내용 } override fun doSomethingElse() { // 구현 내용 } } - 클래스와 인터페이스 동시 상속:
- Kotlin에서는 한 클래스가 하나의 클래스를 상속받고 여러 인터페이스를 구현할 수 있음
- 구문: class Child : Parent(), Interface1, Interface2
open class Parent { // 부모 클래스 내용 } interface Interface1 { fun doSomething() } interface Interface2 { fun doSomethingElse() } class Child : Parent(), Interface1, Interface2 { override fun doSomething() { // 구현 내용 } override fun doSomethingElse() { // 구현 내용 } }
주요 차이점 요약 정리!
- 클래스 상속:
- Java: 단일 상속, extends 키워드 사용.
- Kotlin: 단일 상속, : 키워드 사용.
- 인터페이스 상속:
- Java: 다중 구현 가능, implements 키워드 사용.
- Kotlin: 다중 구현 가능, : 키워드 사용(쉼표로 구분).
- 클래스와 인터페이스 동시 상속:
- Java: 하나의 클래스를 상속받고 여러 인터페이스를 구현할 수 있음, extends와 implements 키워드 조합 사용.
- Kotlin: 하나의 클래스를 상속받고 여러 인터페이스를 구현할 수 있음, : 키워드 사용(클래스는 괄호로 기본 생성자 호출).
- 구문 차이:
- Java: extends와 implements 키워드를 명확히 구분.
- Kotlin: : 키워드 하나로 클래스 상속과 인터페이스 구현을 처리하며, 클래스는 괄호 ()를 사용하여 기본 생성자를 호출함.
- Kotlin이 더 간결하고 일관된 구문을 제공함으로써 코드의 가독성과 유지보수성을 높이는 데 기여함
❓ Java와 Kotlin의 다중 상속 오버라이딩 규칙 비교
Java에서의 다중 상속 ⇒ 불가능! ⇒ interface로 유사하게 다중 구현!
- Java에서는 다중 상속이 허용되지 않는다. 클래스는 단 하나의 클래스를 상속받을 수 있으며, 여러 클래스로부터 상속받는 것이 불가능하다.
- 그러나 인터페이스를 통해 다중 상속과 유사한 기능을 구현할 수 있다. 인터페이스는 다중 구현이 가능하며, 클래스는 여러 인터페이스를 구현할 수 있다.
다중 상속에서 메서드 충돌이 발생할 경우, Java에서는 다음과 같은 규칙이 적용
- 클래스에서 구현된 메서드가 우선순위를 가진다.
- 동일한 메서드를 여러 인터페이스에서 구현한 경우, 서브클래스에서 명시적으로 오버라이드해야 한다.
- interface Interface1 { default void print() { System.out.println("Interface1"); } } interface Interface2 { default void print() { System.out.println("Interface2"); } } class Child implements Interface1, Interface2 { @Override public void print() { // 동일한 메서드를 여러 인터페이스에서 구현한 경우, 서브클래스에서 명시적으로 오버라이드 Interface1.super.print(); // Interface1의 print() 호출 Interface2.super.print(); // Interface2의 print() 호출 } public static void main(String[] args) { Child child = new Child(); child.print(); } }
Kotlin에서의 다중 상속 ⇒ 불가능! ⇒ 여러 인터페이스 구현으로 다중 상속 모방!
- Kotlin에서는 다중 상속이 지원되지 않지만, 여러 인터페이스를 구현하는 방식으로 다중 상속을 모방할 수 있다.
- 클래스가 여러 인터페이스를 구현하고, 동일한 메서드를 상속받는 경우, Kotlin에서는 명시적으로 오버라이드를 요구한다.
- 또한 super<인터페이스명> 구문을 사용하여 어느 인터페이스의 구현을 호출할지 명시적으로 지정할 수 있다.
- interface Interface1 { fun print() { println("Interface1") } } interface Interface2 { fun print() { println("Interface2") } } class Child : Interface1, Interface2 { override fun print() { // 동일한 메서드 상속받는 경우 명시적 오버라이드, // super<인터페이스명> 구분으로 어느 인터페이스 구현 호출할지 명시적 지정 super<Interface1>.print() // Interface1의 print() 호출 super<Interface2>.print() // Interface2의 print() 호출 } } fun main() { val child = Child() child.print() }
주요 차이점 요약
- 다중 상속:
- Java: 다중 상속을 지원하지 않음. 클래스는 단일 상속만 가능. 인터페이스를 통해 다중 구현을 지원.
- Kotlin: 다중 상속을 지원하지 않음. 클래스는 단일 상속만 가능. 인터페이스를 통해 다중 구현을 지원.
- 오버라이딩 충돌 해결:
- Java: 인터페이스 간의 메서드 충돌이 발생할 경우, 서브클래스에서 명시적으로 오버라이드하고 Interface1.super.methodName()과 같은 구문을 사용하여 특정 인터페이스의 메서드를 호출.
- Kotlin: 인터페이스 간의 메서드 충돌이 발생할 경우, 서브클래스에서 명시적으로 오버라이드하고 super<Interface1>.methodName()과 같은 구문을 사용하여 특정 인터페이스의 메서드를 호출.
- 구문 차이:
- Java: Interface1.super.methodName() 형식을 사용하여 인터페이스의 메서드를 호출.
- Kotlin: super<Interface1>.methodName() 형식을 사용하여 인터페이스의 메서드를 호출.
- 이러한 차이점은 Kotlin이 명시적이고 일관된 구문을 제공하여 코드 가독성과 유지보수성을 높이는 데 기여
- Java와 Kotlin 모두 인터페이스를 통해 다중 상속을 모방할 수 있으며, 명시적 오버라이드를 통해 메서드 충돌을 해결한다.