# **코틀린 vs 자바: 객체지향 프로그래밍(OOP) 비교** 코틀린과 자바는 둘 다 객체지향 프로그래밍(OOP)을 지원하는 언어지만, 코틀린은 더 간결하고 유연한 문법을 제공한다. 이번 글에서는 **클래스 선언, 생성자, 상속, 접근 제어자, 데이터 클래스, 객체 선언** 등을 중심으로 자바와 코틀린의 차이점을 비교하겠다. --- ## **1. 클래스 선언 방식 차이** 자바에서는 클래스를 선언할 때 `class` 키워드를 사용하고, **필드와 생성자를 분리**해서 작성하는 것이 일반적이다. ### **자바의 클래스 선언** ```java public 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; } } ``` ### **코틀린의 클래스 선언** 코틀린에서는 **주 생성자(Primary Constructor)**를 **클래스 헤더에 직접 정의**할 수 있다. ```kotlin class Person(val name: String, val age: Int) ``` > **차이점 요약:** > - **자바:** 필드, 생성자, 게터를 따로 작성해야 함. > - **코틀린:** `val` 또는 `var`을 사용하면 **자동으로 필드와 게터 생성**. --- ## **2. 생성자 (Constructors)** 자바에서는 **기본 생성자**와 **매개변수가 있는 생성자**를 따로 정의해야 한다. ### **자바의 생성자 오버로딩** ```java public class Car { private String model; public Car() { this.model = "Unknown"; } public Car(String model) { this.model = model; } } ``` 코틀린에서는 **기본값을 지정**할 수 있어 생성자 오버로딩을 줄일 수 있다. ### **코틀린의 기본값 제공 방식** ```kotlin class Car(val model: String = "Unknown") ``` > **차이점 요약:** > - 자바는 **생성자 오버로딩**이 필요하지만, > - 코틀린은 **기본값을 제공하면 생성자 하나로 해결 가능**. --- ## **3. 상속 (Inheritance)과 `open` 키워드** 자바에서 클래스를 상속하려면 `extends` 키워드를 사용하고, **메서드 오버라이딩 시 `@Override`를 명시**해야 한다. ### **자바의 상속** ```java public class Animal { public void makeSound() { System.out.println("Some sound"); } } public class Dog extends Animal { @Override public void makeSound() { System.out.println("Bark!"); } } ``` 코틀린에서는 클래스가 **기본적으로 `final`이므로 상속을 허용하려면 `open` 키워드를 붙여야 한다**. ### **코틀린의 상속** ```kotlin open class Animal { open fun makeSound() { println("Some sound") } } class Dog : Animal() { override fun makeSound() { println("Bark!") } } ``` > **차이점 요약:** > - **자바:** 모든 클래스가 기본적으로 **상속 가능**(`final`이 아님). > - **코틀린:** 모든 클래스가 기본적으로 **`final`이며, 상속하려면 `open`을 붙여야 함**. > - **오버라이딩 시 자바는 `@Override` 사용**, 코틀린은 **`override` 키워드 필수**. --- ## **4. 접근 제어자 (Access Modifiers)** 자바와 코틀린 모두 **`public`, `protected`, `private`** 접근 제어자를 제공하지만, 코틀린에는 **추가로 `internal`이 있다**. | 접근 제어자 | 자바 | 코틀린 | |------------|------|--------| | `public` | 모든 곳에서 접근 가능 | 동일 | | `protected` | 같은 패키지 + 하위 클래스에서 접근 가능 | 하위 클래스에서만 접근 가능 (패키지 무관) | | `private` | 같은 클래스 내에서만 접근 가능 | 동일 | | `default` (생략 시) | 같은 패키지 내에서 접근 가능 | `internal` (같은 모듈 내에서 접근 가능) | ### **코틀린의 `internal` 키워드** ```kotlin internal class InternalClass { fun greet() = "Hello" } ``` > - `internal`은 **같은 모듈 내에서만 접근 가능**(자바에는 해당 없음). --- ## **5. 데이터 클래스 (Data Class)** 자바에서는 **`equals()`, `hashCode()`, `toString()` 메서드를 직접 구현**해야 한다. ### **자바의 데이터 클래스를 수동 구현** ```java public class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; User user = (User) obj; return age == user.age && Objects.equals(name, user.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "User{name='" + name + "', age=" + age + "}"; } } ``` 코틀린에서는 **`data` 키워드를 추가하는 것만으로 자동 생성**된다. ### **코틀린의 데이터 클래스** ```kotlin data class User(val name: String, val age: Int) ``` > **차이점 요약:** > - 자바에서는 `equals()`, `hashCode()`, `toString()`을 직접 작성해야 함. > - 코틀린에서는 `data class`만 선언하면 자동 생성됨. --- ## **6. 싱글턴 (Singleton) 객체 선언** 자바에서 싱글턴 패턴을 구현하려면 **`static` 키워드를 사용하거나, `enum`을 활용**해야 한다. ### **자바의 싱글턴 패턴** ```java public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton getInstance() { return INSTANCE; } } ``` 코틀린에서는 **`object` 키워드를 사용하면 자동으로 싱글턴이 된다**. ### **코틀린의 싱글턴** ```kotlin object Singleton { fun greet() = "Hello" } println(Singleton.greet()) // Hello ``` > **차이점 요약:** > - 자바는 **싱글턴을 만들기 위해 보일러플레이트 코드 필요**. > - 코틀린은 `object`를 사용하면 자동으로 싱글턴 객체 생성됨. --- ## **정리: 자바 vs 코틀린 OOP 차이점** | 기능 | 자바 | 코틀린 | |------|------|--------| | **클래스 선언** | 필드 + 생성자 + 게터 필요 | `class Person(val name: String)` | | **생성자 오버로딩** | 여러 개의 생성자 정의 필요 | 기본값 사용 가능 | | **상속** | 기본적으로 가능 (`final`을 붙여야 제한) | 기본적으로 `final`, `open`을 붙여야 상속 가능 | | **데이터 클래스** | `equals()`, `hashCode()`, `toString()` 직접 구현 | `data class`로 자동 생성 | | **싱글턴 패턴** | `static` 필드 사용 | `object` 키워드 사용 | | **`protected` 접근 제어자** | 같은 패키지 + 하위 클래스 접근 가능 | 오직 하위 클래스만 접근 가능 | 코틀린은 **객체지향 프로그래밍을 더 간결하고 효율적으로 작성할 수 있도록 개선**된 언어다. 다음에는 어떤 개념을 비교해볼까?