

클래스는 객체를 정의하는 설계도로, 속성과 메서드를 포함하며 실제 인스턴스를 생성하기 위한 틀을 제공합니다. 클래스는 코드 재사용과 구조화를 가능하게 합니다. 예를 들어, 아래 코드는 Car 클래스를 정의합니다.
class Car(val color: String, val model: String)
인스턴스는 클래스를 실제로 구현한 객체입니다. 클래스가 설계도라면, 인스턴스는 그 설계도를 바탕으로 생성된 실체입니다. 예를 들어, 아래 코드는 Car 클래스의 인스턴스를 생성합니다.
val myCar = Car("red", "Toyota")
오브젝트는 단일 인스턴스를 의미하며, Kotlin에서는 object 키워드를 사용하여 선언합니다. 이는 싱글톤 패턴을 구현할 때 사용됩니다. 예를 들어, 아래 코드는 Singleton이라는 단일 인스턴스를 생성합니다.
object Singleton {
val name = "Singleton"
}
인터페이스는 클래스가 구현해야 하는 메서드 목록을 정의합니다. 인터페이스는 다중 상속을 가능하게 하며, 여러 클래스가 동일한 기능을 구현할 수 있도록 합니다. 예를 들어, 아래 코드는 Drivable 인터페이스를 정의합니다.
interface Drivable {
fun drive()
}
상속은 한 클래스가 다른 클래스의 속성과 메서드를 물려받는 기능입니다. 이는 코드의 재사용성을 높이고, 계층 구조를 통해 코드를 체계적으로 관리할 수 있게 합니다. 예를 들어, 아래 코드는 Animal 클래스를 상속받아 Dog 클래스를 정의합니다.
open class Animal {
fun eat() {
println("Animal is eating")
}
}
class Dog : Animal() {
fun bark() {
println("Dog is barking")
}
}
포함 관계는 클래스가 다른 클래스를 멤버로 포함하는 관계입니다. 이는 상속 대신 사용할 수 있는 강력한 설계 기법으로, 유연성을 높입니다. 예를 들어, 아래 코드는 Car 클래스가 Engine 클래스를 포함합니다.
class Engine(val type: String)
class Car(val engine: Engine)
다형성은 같은 인터페이스를 구현하는 여러 객체가 다른 방식으로 동작할 수 있게 하는 기능입니다. 이는 상속을 통해 구현되며, 코드의 유연성과 확장성을 높입니다. 예를 들어, 아래 코드는 Drivable 인터페이스를 구현한 객체들을 다형성으로 처리하는 방법을 보여줍니다.
fun drive(vehicle: Drivable) {
vehicle.drive()
}
기본적인 클래스입니다. 속성과 메서드를 정의할 수 있으며, 인스턴스를 생성할 수 있습니다.
주로 데이터를 저장하기 위한 클래스입니다. equals, hashCode, toString 메서드가 자동으로 생성됩니다. 예를 들어, 아래 코드는 데이터를 저장하기 위한 User 클래스를 정의합니다.
data class User(val name: String, val age: Int)
상속 가능한 클래스 계층을 제한하기 위해 사용됩니다. 컴파일 시점에 하위 클래스가 확정됩니다. 예를 들어, 아래 코드는 Shape의 하위 클래스들이 제한된 범위 내에서 정의됨을 보장합니다.
sealed class Shape {
class Circle(val radius: Double) : Shape()
class Rectangle(val length: Double, val width: Double) : Shape()
}
Kotlin Data-class
Kotlin sealed-class
Medium
현재 객체를 참조합니다. 클래스의 속성이나 메서드를 가리킬 때 사용됩니다. 예를 들어, 아래 코드는 현재 객체의 name 속성을 참조합니다.
class Person(val name: String) {
fun printName() {
println(this.name)
}
}
부모 클래스의 멤버를 참조할 때 사용됩니다. 메서드 오버라이딩 시 부모 클래스의 메서드를 호출할 때 사용됩니다. 예를 들어, 아래 코드는 부모 클래스의 drive 메서드를 호출합니다.
open class Vehicle {
open fun drive() {
println("Vehicle is driving")
}
}
class Car : Vehicle() {
override fun drive() {
super.drive()
println("Car is driving")
}
}
객체 지향 프로그래밍에서 단일 책임 원칙(single responsibility principle)이란 모든 클래스는 하나의 책임만 가지며, 클래스는 그 책임을 완전히 캡슐화해야 함을 일컫는다. 클래스가 제공하는 모든 기능은 이 책임과 주의 깊게 부합해야 한다.
한 클래스를 한 관심사에 집중하도록 유지하는 것이 중요한 이유는, 이것이 클래스를 더욱 튼튼하게 만들기 때문이다. 앞서 든 예를 계속 살펴보면, 편집 과정에 변경이 일어나면, 같은 클래스의 일부로 있는 출력 코드가 망가질 위험이 대단히 높다.
치환성(영어: substitutability)은 객체 지향 프로그래밍 원칙이다. 컴퓨터 프로그램에서 자료형 𝑆가 자료형 𝑇의 서브타입라면 필요한 프로그램의 속성(정확성, 수행하는 업무 등)의 변경 없이 자료형 𝑇의 객체를 자료형 𝑆의 객체로 교체(치환)할 수 있어야 한다는 원칙이다.
깊이 우선 탐색( - 優先探索, 영어: depth-first search, DFS)은 맹목적 탐색방법의 하나로 탐색트리의 최근에 첨가된 노드를 선택하고, 이 노드에 적용 가능한 동작자 중 하나를 적용하여 트리에 다음 수준(level)의 한 개의 자식노드를 첨가하며, 첨가된 자식 노드가 목표노드일 때까지 앞의 자식 노드의 첨가 과정을 반복해 가는 방식이다.
탐색 과정이 시작 노드에서 한없이 깊이 진행되는 것을 막기 위해 깊이 제한(depth bound)을 사용한다. 깊이 제한에 도달할 때까지 목표노드가 발견되지 않으면 최근에 첨가된 노드의 부모노드로 되돌아와서, 부모노드에 이전과는 다른 동작자를 적용하여 새로운 자식노드를 생성한다.
여기서 부모노드로 되돌아오는 과정을 백트래킹(backtracking)이라 한다.

By Mre - 자작, CC BY-SA 3.0, 링크