→ 생성자는 하나의 primary constructor 와 다수의 secondary constructor 로 나뉨
→ primary constructor (주생성자)
constructor 키워드 사용 (생략 가능)
함수 인자처럼, class명 우측에 구현
primary constructor 에는 어떤 실행문도 올 수 없음. 실행문은 init 블록에 담기
인자를 받아서 초기화 or 인자 받으면서 초기화 (보통 후자로 많이 함!! val 키워드 사용)
// 1. 인자를 받아서 property 초기화
class InitOrderDemo(name: String) {
init {
println("First initializer block that prints ${name}")
}
val _name = name
init {
println("Second initializer block that prints ${name.length}")
}
}
fun main(args: Array<String>) {
val person = InitOrderDemo("Ready Kim")
}
// 결과 (위에서 아래로 실행됨 알수있다)
First property: Ready Kim
First initializer block that prints Ready Kim
Second property: 9
Second initializer block that prints 9
// 2. 인자받음과 동시에 property 초기화
class InitOrderDemo(val name: String) {
}
fun main(args: Array<String>) {
val person = InitOrderDemo("Ready Kim")
}
→ secondary constructor (부생성자)

class Animal(_nLeg:Int, _color:String) {
var name : String = ""
var nLeg = _nLeg
var color = _color
init {
println("=== Primary Init block ===")
println("nLeg: $nLeg, color: $color, name: $name")
// Do something!!
}
constructor(_nLeg:Int, _color:String, _name:String) : this(_nLeg, _color) {
println("=== Secondary constructor start ===")
this.name = _name
println("nLeg: $nLeg, color: $color, name: $name")
println("=== Secondary constructor end ===")
}
}
fun main(){
val myAnimal = Animal(4, "yellow", "Smith")
}
// 결과
=== Primary Init block ===
nLeg: 4, color: yellow, name:
=== Secondary constructor start ===
nLeg: 4, color: yellow, name: Smith
=== Secondary constructor end ===
val product = Product(”패션”, “겨울패딩”)
기본값 설정 가능
생성자 인자 변수 순서 바꿔도, 네이밍 통해서 대입 가능
class Person (var name:String = "개발자", var age:Int = "20")
val p0 = Person() // name="개발자", age=20
val p1 = Person("김철수") // name="김철수", age=20
val p2 = Person("김영희", 25) // name="김영희", age=25
val p3 = Person(age=30, name="도라에몽") // name="도라에몽", age=30
→ 모든 클래스는 명시적 또는 암시적으로 Any를 상속함
equals / hashCode() / toString() 만 존재
자바의 java.lang.Object와는 다름
class Person // 암시적 Any 상속
class Person : Any // 명시적 Any 상속
→ open 키워드 vs final 키워드
// 상속 가능
open class Beginner(...) {
...
}
class Soldier (...) : Beginner(...){
...
}
// 상속 불가능
class Beginner(...) {
...
}
class Soldier (...) : Beginner(...){
...
}
→ 상속 인자
open class Animal(var name:String, var age:Int, var type:String){
fun introduce() {
println("저는 ${type} ${name}이고, ${age}살 입니다.")
}
}
class Dog (name:String, age:Int, sex :String) : Animal(name, age, "개"){ // var, val을 쓰지않고 Animal 클래스 생성자에 직접 넘겨준다.
fun bark(){ // Dog만 가능하다.
println("멍멍")
}
}
class Cat(name:String, age:Int,color : String) : Animal(name, age, "고양이"){
fun meow(){
println("야옹")
}
}
// 초보자 클래스
open class Beginner(
var name: String, //이름
var hp: Int, //체력
var mp: Int, //마나
var experience: Int //경험치
) {
//일반 공격
open fun attack(monster: Monster) {
monster.hp -= 10 // 몬스터에게 10에 데미지를 입힌다.
}
}
// 전사 클래스
open class Soldier (name: String, hp: Int, mp: Int, experience: Int) : Beginner(name, hp, mp, experience){
// 전사 일반 공격
override fun attack(monster: Monster) {
super.attack(monster!!)
}
}
→ open 키워드 vs final 키워드
// 오버라이드 가능
open class Beginner(...) {
open fun attack(){}
}
class Soldier (...) : Beginner(...){
override fun attack(){}
}
// 오버라이드 불가능
open class Beginner(...) {
fun attack(){}
}
class Soldier (...) : Beginner(...){
override fun attack(){}
}
super 키워드
this 키워드
// 부모클래스
// open 키워드를 붙여야 상속 가능
open class Fruit(val name: String){
init{
println("Suplerclass 초기화")
}
open fun introduce(){
println('나는 과일이야!')
}
}
// 자식클래스
class Apple(name: String) : Fruit(name){
val text="name"
init{
println("subclass 초기화"
}
override fun introduce() {
super.introduce()
println("그 중에 나는 $this.text야")
}
}
// 메인함수
fun main(){
val apple = Apple('red apple')
apple.introduce()
}
// 실행결과
Superclass 초기화
subclass 초기화
나는 과일이야!
그 중에 나는 사과야