PHpullh

LANGUAGE COMPARISON

Class를 언어별로 비교하기

같은 개념을 실제 예제로 나란히 확인하고, 각 언어의 개별 설명으로 이어갈 수 있습니다.

Kotlin

Destructuring & 구조 분해

컴포넌트 함수를 통해 객체를 여러 변수로 한 번에 분해합니다.

// Pair, Triple
val pair = Pair("Kotlin", 2024)
val (lang, year) = pair
println("$lang $year")

// data class는 자동으로 componentN() 생성
data class Point(val x: Int, val y: Int)
val (x, y) = Point(10, 20)
println("x=$x, y=$y")

// 특정 항목 무시: _
data class User(val id: Int, val name: String, val email: String)
val (_, name, _) = User(1, "Alice", "a@test.com")
println(name)

// Map 순회에서 destructuring
val map = mapOf("a" to 1, "b" to 2)
for ((key, value) in map) {
    println("$key → $value")
}

// withIndex destructuring
listOf("x", "y", "z").forEachIndexed { idx, item ->
    println("$idx: $item")
}

Python

클래스 & __init__ & 프로퍼티

Python OOP의 핵심. __init__ , @property , @classmethod , @staticmethod .

from datetime import date

class Person:
    # 클래스 변수 (모든 인스턴스 공유)
    species = "Homo sapiens"

    def __init__(self, name: str, birth_year: int):
        # 인스턴스 변수
        self.name = name
        self._birth_year = birth_year   # 관례적 protected
        self.__secret = "비밀"           # name mangling (private)

    # @property — getter
    @property
    def age(self) -> int:
        return date.today().year - self._birth_year

    # @property.setter
    @age.setter
    def age(self, value: int):
        if value < 0:
            raise ValueError("나이는 0 이상")
        self._birth_year = date.today().year - value

    # @classmethod — cls 인자, 클래스 메서드
    @classmethod
    def from_string(cls, data: str) -> "Person":
        name, year = data.split(",")
        return cls(name.strip(), int(year.strip()))

    # @staticmethod — self/cls 없음, 유틸리티
    @staticmethod
    def is_adult(age: int) -> bool:
        return age >= 18

    def __repr__(self) -> str:
        return f"Person(name={self.name!r}, age={self.age})"

p1 = Person("Alice", 1993)
p2 = Person.from_string("Bob, 1990")
print(p1.age)               # 계산된 나이
print(Person.is_adult(20))  # True
print(repr(p1))

Go

함수 — 다중 반환값 & Named Return

Go 함수의 핵심 특징: 여러 값을 반환하고, 에러를 마지막 반환값으로 처리합니다.

package main

import (
	"errors"
	"fmt"
	"strconv"
)

// 다중 반환값 — Go의 관용구
func divide(a, b float64) (float64, error) {
	if b == 0 {
		return 0, errors.New("0으로 나눌 수 없습니다")
	}
	return a / b, nil
}

// Named return values
func minMax(nums []int) (min, max int) {
	min, max = nums[0], nums[0]
	for _, n := range nums[1:] {
		if n < min { min = n }
		if n > max { max = n }
	}
	return // naked return
}

// 가변 인자
func sum(nums ...int) int {
	total := 0
	for _, n := range nums { total += n }
	return total
}

// 함수를 값으로 (일급 함수)
func apply(fn func(int) int, vals []int) []int {
	result := make([]int, len(vals))
	for i, v := range vals {
		result[i] = fn(v)
	}
	return result
}

func main() {
	// 에러 처리 패턴
	result, err := divide(10, 3)
	if err != nil {
		fmt.Println("에러:", err)
	} else {
		fmt.Printf("%.4f
", result)
	}

	_, err = divide(5, 0)
	if err != nil { fmt.Println(err) }

	// Named return
	lo, hi := minMax([]int{3, 1, 4, 1, 5, 9, 2, 6})
	fmt.Println("min:", lo, "max:", hi)

	// 가변 인자
	fmt.Println(sum(1, 2, 3, 4, 5))
	nums := []int{1, 2, 3}
	fmt.Println(sum(nums...)) // 슬라이스 전개

	// 고차 함수
	doubled := apply(func(n int) int { return n * 2 }, nums)
	fmt.Println(doubled)

	_ = strconv.Itoa(0)
}

Java

Sealed Class & Pattern Matching (Java 17/21)

대수적 데이터 타입을 Java에서 구현하는 Sealed Class와 패턴 매칭.

// Sealed class (Java 17+)
public sealed interface Shape
    permits Circle, Rectangle, Triangle {}

public record Circle(double radius) implements Shape {}
public record Rectangle(double w, double h) implements Shape {}
public record Triangle(double base, double height) implements Shape {}

// Pattern Matching for switch (Java 21)
public class PatternMatching {

    static double area(Shape shape) {
        return switch (shape) {
            case Circle c       -> Math.PI * c.radius() * c.radius();
            case Rectangle r    -> r.w() * r.h();
            case Triangle t     -> 0.5 * t.base() * t.height();
            // else 불필요 — sealed로 완전성 보장
        };
    }

    // Guarded patterns (Java 21)
    static String classify(Shape shape) {
        return switch (shape) {
            case Circle c when c.radius() > 10  -> "대형 원";
            case Circle c                        -> "소형 원";
            case Rectangle r when r.w() == r.h() -> "정사각형";
            case Rectangle r                     -> "직사각형";
            case Triangle t                      -> "삼각형";
        };
    }

    // instanceof Pattern Matching (Java 16+)
    static void printInfo(Object obj) {
        if (obj instanceof String s && !s.isBlank()) {
            System.out.println("문자열 길이: " + s.length());
        } else if (obj instanceof Integer i && i > 0) {
            System.out.println("양의 정수: " + i);
        }
    }

    public static void main(String[] args) {
        Shape[] shapes = {
            new Circle(5), new Rectangle(3, 4), new Triangle(6, 8)
        };
        for (var s : shapes) {
            System.out.printf("%s → %.2f%n", classify(s), area(s));
        }
        printInfo("Hello");
        printInfo(42);
    }
}

PHP

anonymous class 빠르게 만들기

가벼운 테스트용 객체나 어댑터를 익명 클래스로 빠르게 만드는 예제입니다.

<?php
$logger = new class {
    public function info(string $message): void {
        echo "[info] {$message}
";
    }
};

$logger->info('boot');