class User {
var name = "gildong"
constructor(name: String) {
this.name = name
}
fun some() {
...
}
class SomeClass { }
}
constructor는 코틀린의 생성자
class User constructor() { ... }
class User() { ... } // constructor 생략 가능
class User { ... } // 주 생성자가 없으면 자동으로 매개변수 없는 주생성자 생성
class User(name: String, count: Int) { ... } // 주 생성자의 매개변수
class User(name: String, count: Int) {
init {
println(" init ")
}
}
class User(name: String, count: Int) {
init {
println("name : $name, count : $count") // 성공
}
fun some() {
println("name : $name, count : $count") // 오류
}
}
생성자의 매개변수는 지역변수로, 다른 함수에서는 사용 불가능
class User(name: String, count: Int) {
var name: String
var count: Int
init {
this.name = name
this.count = count
}
}
클래스 멤버 변수 선언해주면 매개변수 사용이 가능
class User(val name: String, val count: Int) {
fun some() {
println(" ,,, ")
}
}
주 생성자에서만 유일하게 var이나 val 키워드로 매개변수를 선언 할 수 있음
class User(name: String) {
constructor(name: String, count: Int) { // 오류
...
}
}
주 생성자가 있으면 보조 생성자에서 주 생성자를 호출 해줘야함
class User(name: String) {
constructor(name: String, count: Int): this(name) {
...
}
}
보조 생성자 선언부에 this(name)만 추가하면 주 생성자가 호출됨
class User(name: String) {
constructor(name: String, count: Int): this(name) {
...
}
constructor(name: String, count: Int, email: String): this(name, count) {
...
}
}
위와 같이 그 위의 보조 생성자를 다시 불러오면 됨
open class Super { // 상속할 수 있게 open 키워드 이용
}
class Sub: Super() { // Super를 상속받아 Sub 클래스 선언
}
open class Super(name: String) {
}
/* 1 */
class Sub(name: String): Super(name) {
}
/* 2 */
class Sub: Super {
constructor(name: String): super(name) {
}
}
하위 클래스의 보조 생성자가 있다면 클래스 선언부에 꼭 생성자 호출문을 작성할 필요는 없음
open class Super {
open var data = 10
open fun some() {
println(" ... ")
}
}
class Sub: Super() {
override var data = 20
override var some() {
println("$data")
}
}
open 키워드를 선언하지 않으면 하위 클래스에서 재정의 할 수 없음
접근 제한자 | 최상위에서 이용 | 클래스 멤버에서 이용 |
---|---|---|
public | 모든 파일에서 가능 | 모든 클래스에서 가능 |
internal | 같은 모듈 내에서 가능 | 같은 모듈 내에서 가능 |
protected | 사용 불가 | 상속 관계의 하위 클래스에서만 가능 |
private | 파일 내부에서만 이용 | 클래스 내부에서만 이용 |
open class Super {
var publicData = 10
protected var protectedData = 20
private var privateData = 30
}
class Sub: super() {
fun subFun() {
publicData++ // 성공
protectedData++ // 성공
privateData++ // 오류
}
}
fun main() {
var obj = Super()
obj.publicData++ // 성공
obj.protectedData++ // 오류
obj.protectedData++ // 오류
}
class NonDataClass(val name: String, val email: String, val age: Int)
data class DataClass(val name: String, val email: String, val age: Int)
data키워드를 이용해 자주 사용하는 데이터를 객체로 묶어 줌
val non1 = NonDataClass("gildong", "aaa@a.com", 10)
val non2 = NonDataClass("gildong", "aaa@a.com", 10)
val data1 = DataClass("gildong", "aaa@a.com", 10)
val data2 = DataClass("gildong", "aaa@a.com", 10)
non1.equals(non2) // false
data1.equals(data2) // true
위 처럼 data 클래스를 이용하면 객체의 데이터를 비교할때 편리
하지만, equals()를 사용한 데이터 비교는 주 생성자에서 선언한 멤버 변수의 데이터만 비교 대상으로 삼음
data class DataClass(val name: String, val email: String, val age: Int) {
lateinit var address: String
constructor(name: String, email: String, age: Int, address: String): this(name. email, age) {
this.address = address
}
}
fun main() {
val obj1 = DataClass("gildong", "aaa@a.com", 10, "seoul")
val obj2 = DataClass("gildong", "aaa@a.com", 10, "busan")
obj1.equals(obj2) // true
}
이처럼 equals()는 주 생성자의 멤버 변수가 같은지만 판단함
class NonDataClass(val name: String, val email: String, val age: Int)
data class DataClass(val name: String, val email: String, val age: Int)
val non = NonDataClass("gildong", "aaa@a.com", 10)
val data = DataClass("gildong", "aaa@a.com", 10)
non.toString() // com.example.androidlab.....
data.toString() // DataClass(name=gildong, email=aaa@a.com, age=10)
이 처럼 데이터 클래스의 toString() 함수는 객체가 포함하는 멤버 변수의 데이터를 출력
val obj = object {
var data = 10
fun some() {
println("...")
}
}
fun main() {
obj.data = 20 // 오류
obj.some() // 오류
}
오브젝트 클래스를 선언했지만 그 안의 변수나 함수를 사용하는데에는 오류가 발생함. 그 이유로는 타입을 명시하지 않아 Any로 취급이 되는데,
Any타입에는 선언한 변수나 함수들이 없기 때문에 오류가 발생하는 것임
open class Super {
open var data = 10
open fun some() {
println("$data")
}
}
val obj = object: Super() {
override var data = 20
override fun some() {
println("$data")
}
}
fun main() {
obj.data = 30 // 성공
obj.some() // 성공
}
Super 클래스를 상속 받았기 때문에 클래스 내에 선언된 멤버에 접근이 가능하게 됨
class MyClass {
companion object {
var data = 10
fun some() {
println(data)
}
}
}
fun main() {
MyClass.data = 20 // 성공
MyClass.some() // 성공
}
클래스 내부에서 companion object {} 형태로 선언하게 되면 클래스 이름으로 멤버에 접근 가능
Do it! 깡쌤의 안드로이드 프로그래밍 with 코틀린 (개정판)