7.0 KiB
코틀린 vs 자바: 객체지향 프로그래밍(OOP) 비교
코틀린과 자바는 둘 다 객체지향 프로그래밍(OOP)을 지원하는 언어지만, 코틀린은 더 간결하고 유연한 문법을 제공한다.
이번 글에서는 클래스 선언, 생성자, 상속, 접근 제어자, 데이터 클래스, 객체 선언 등을 중심으로 자바와 코틀린의 차이점을 비교하겠다.
1. 클래스 선언 방식 차이
자바에서는 클래스를 선언할 때 class 키워드를 사용하고, 필드와 생성자를 분리해서 작성하는 것이 일반적이다.
자바의 클래스 선언
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)**를 클래스 헤더에 직접 정의할 수 있다.
class Person(val name: String, val age: Int)
차이점 요약:
- 자바: 필드, 생성자, 게터를 따로 작성해야 함.
- 코틀린:
val또는var을 사용하면 자동으로 필드와 게터 생성.
2. 생성자 (Constructors)
자바에서는 기본 생성자와 매개변수가 있는 생성자를 따로 정의해야 한다.
자바의 생성자 오버로딩
public class Car {
private String model;
public Car() {
this.model = "Unknown";
}
public Car(String model) {
this.model = model;
}
}
코틀린에서는 기본값을 지정할 수 있어 생성자 오버로딩을 줄일 수 있다.
코틀린의 기본값 제공 방식
class Car(val model: String = "Unknown")
차이점 요약:
- 자바는 생성자 오버로딩이 필요하지만,
- 코틀린은 기본값을 제공하면 생성자 하나로 해결 가능.
3. 상속 (Inheritance)과 open 키워드
자바에서 클래스를 상속하려면 extends 키워드를 사용하고, 메서드 오버라이딩 시 @Override를 명시해야 한다.
자바의 상속
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 키워드를 붙여야 한다.
코틀린의 상속
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 키워드
internal class InternalClass {
fun greet() = "Hello"
}
internal은 같은 모듈 내에서만 접근 가능(자바에는 해당 없음).
5. 데이터 클래스 (Data Class)
자바에서는 equals(), hashCode(), toString() 메서드를 직접 구현해야 한다.
자바의 데이터 클래스를 수동 구현
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 키워드를 추가하는 것만으로 자동 생성된다.
코틀린의 데이터 클래스
data class User(val name: String, val age: Int)
차이점 요약:
- 자바에서는
equals(),hashCode(),toString()을 직접 작성해야 함.- 코틀린에서는
data class만 선언하면 자동 생성됨.
6. 싱글턴 (Singleton) 객체 선언
자바에서 싱글턴 패턴을 구현하려면 static 키워드를 사용하거나, enum을 활용해야 한다.
자바의 싱글턴 패턴
public class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return INSTANCE;
}
}
코틀린에서는 object 키워드를 사용하면 자동으로 싱글턴이 된다.
코틀린의 싱글턴
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 접근 제어자 |
같은 패키지 + 하위 클래스 접근 가능 | 오직 하위 클래스만 접근 가능 |
코틀린은 객체지향 프로그래밍을 더 간결하고 효율적으로 작성할 수 있도록 개선된 언어다.
다음에는 어떤 개념을 비교해볼까?