코드를 작성하다보니 아래와 같이 변수 선언에 관한것은 이해가 갔다.
var class1 = A() // instance 선언
var class2 : A // 그냥 변수 선언(초기화 안됨)
근데.. 코드를 보다 보면 아래와 같은 코드가 나온다..
이게 무슨 차일까...?? class A의 input를 받아서 class C로 넘겨 주는것 같은데.. input의 타입도 없고.. 뭐야.. 시부렁..
class C(var input: Int) : A(input) {}
class D(var input: Int) : A() {}
여러가지 포스팅과 삽질을 하다가 모든게 코틀린의 복잡한 constructor에서 비롯된다는 것을 알게 되었다.
일단 코틀린은 아래와 같은 규칙(문법)이 존재한다.(근데 잘 안 알려줌-_-)
1. primary constructor, second constructor 개념이 존재
2. second constructor은 primary constructor 를 상속해서 만들어졌다.(굳이 왜??? 문제의 원인-_-)
3. class 선언에 있는 constructor는 primary이다.
4. constructor() 함수로 이루어진 것은 second constructor 이다.
5. primary의 인자가 1개일 경우 second는 인자가 1개 이상이어야 한다.
6. this() 함수를 통하여 상속을 표시(아래 예시를 보라)
class A_Modified(var value3 : Int){
constructor(){} // 불가, primary 상속이 불가능한 형태
constructor(i : Int, j : Int){} // 불가, primary 상속 누락 형태
constructor(i : Int, j : Int) : this(i){} // 가능
}
말로 표현하는것보다 코드로 보는게 이해가 빠를 것 같으니, 자세한 내용은 아래 코드를 참고 하세요.
open class A {
open var value1 = 1
var value2 = 2
constructor(){
}
constructor(i : Int){
this.value1 = i
}
constructor(i : Int, j : Int){
this.value1 = i
this.value2 = j
}
}
// primary constructor에 인자가 1개 있을 경우
open class A_Modified(var value3 : Int) {
open var value1 = 1
var value2 = 2
// constructor(value : Int){ // (var value3 : Int)와 같은 효과이기에 conflict 발생
// this.value3 = value
// }
/* constructor(i : Int, j : Int){ // Primary constructor call expected
primary 상속 누락 형태
그러므로 class 선언에서 사용된 (var value3 : Int) 항목을 강제로 상속 받아야 한다.
*/
constructor(i : Int, j : Int) : this(i){
this.value1 = i
this.value2 = j
}
}
/* 정리
1. primary constructor, second constructor 개념이 존재
2. second constructor은 primary constructor 를 상속해서 만들어졌다.
3. class 선언에 있는 constructor는 primary이다.
4. constructor() 함수로 이루어진 것은 second constructor 이다.
5. primary의 인자가 1개일 경우 second는 인자가 1개 이상이어야 한다.
6. this() 함수를 통하여 상속을 표시
ex)
class A_Modified(var value3 : Int){
constructor(){} // 불가, primary 상속이 불가능한 형태
constructor(i : Int, j : Int){} // 불가, primary 상속 누락 형태
constructor(i : Int, j : Int) : this(i){} // 가능
}
}
*/
// Class A의 property와 이름이 같으면 아래 에러 발생
// 'value1' hides member of supertype 'A' and needs 'override' modifier
//open class B(var value1: Int) : A(value1) {
//}
open class B(override var value1: Int) : A(value1) {
// B class 에서 var value1: Int 를 override 시켜 주고,
// A class 에서 var value1 에 open 키워드를 넣어주면 가능
}
// 상속 받을 때 variable의 이름이 같아야 하며, Class A의 property와 이름은 달라야 한다.
open class C(var input: Int) : A(input) {
}
open class D(var input: Int) : A() {
}
class F(value : Int){ // property 를 상속으로만 접근 하게 제한해 버리는 방법
constructor(v1 : Int, v2:Int) : this(v1){
}
}
fun main(args: Array<String>) {
var class1 = A(0)
var class2 = A()
var class3 : A
var cClass2 = C(10) // A class와 A class의 constructor(input_v : Int) 를 함께 상속한다.
println(cClass2.value1) // 10
println(cClass2.input) // 10
var cClass3 = D(10) // A class와 A class의 constructor() 를 함께 상속한다.
println(cClass3.value1) // 1 // println(cClass2.value1) 와 결과가 다르다!!!!!
println(cClass3.input) // 10
}
출처 : 나