8. class의 기본 구조
▷ 객체를 생성하고 이를 instance로 만들어서 사용함
▷ 기능/역할은 fun으로 정의해서 사용함
fun main() {
var a = Person("park bo yong", 20050104)
var b = Person("동욱", 20030107)
a.intro()
b.intro()
}
class Person (var name: String, val birthday: Int){
fun intro(){
println("${name}은 ${birthday}에 출생했습니다.")
}
}
9. class의 생성자
▷ class 이름 옆에 괄호 안에 정의: 생성자를 통해 값을 반환 받음
▷ 새로운 instance를 만들기 위해 호출하는 특수한 함수로 instance의 속성을 초기화
▷ instance 생성시 구문을 수행하는 기능은 넣을 수 없음(fun 없이 print하면 애러 남)
· init를 사용하면 가능함
· init 함수는 패러미터나 반환형이 없는 특수한 함수로 생성자로 instance가 만들어질 때 호출되는 함수
▷ contructor를 통해 기본 값 지정
class Person (var name: String, val birthday: Int){
init {
println("${this.name}은 ${this.birthday}에 출생했습니다.")
}
constructor(name: String): this(name, 1996) {
println("보조 생성자가 사용되었습니다.")
}
}
// this는 instance 자신의 속성이나 함수를 호출하기 위해 class 내부에서 사용되는 키워드
class Human constructor(val name: String = "이름 없음") {
fun eatSome(){ println("밥을 먹음") }
}
fun main(){
val human = Human("KIM")
val noName = Human() //생성자에서 기본 값을 지정해서 애러 없음
val name = human.name
human.eatSome()
println("His name is $name")
}
10. class의 상속
▷ 필요한 이유 : 이미 존재하는 것을 확장하거나 여러 개의 class의 공통점을 찾아서 …
▷ open 상태이어야 상속될 수 있음 : open은 class가 상속될 수 있도록 붙어주는 키워드
▷ 상속의 2가지 규칙
· 서브 class는 수펴 class에 존재하는 속성과 ‘같은 이름’의 속성을 가질 수 없음
· 서브 class가 생성될 때는 반드시 수퍼class의 생성자까지 호출되어야 함(변수 정의 없음)
open class Human constructor(val name: String = "기본 이름") {
constructor(name: String, age: Int) : this(name){
println("name is $name and age is $age")
}
init { //객체 생성시에 실행되는 구문, constructor 보다 먼저 실행됨
println("Human instance 생성되면 기본으로 실행됨")
}
fun eatSome(){ println("밥을 먹음") }
open fun singOverOpen(){ println("sing a song") }
}
class Korean : Human(){
override fun singOverOpen(){
super.singOverOpen() // mother 것을 사용
println("노래를 합니다.")
println("My name is $name")
}
}
fun main(){
val human = Human("KIM")
val noName = Human() //생성자에서 기본 값을 지정해서 애러 없음
human.eatSome()
val humanAge = Human("Woo", 53)
println("His name is ${human.name}")
val korean = Korean()
korean.singOverOpen()
}
11. 오버라이딩과 추상화
override
▷ 서브 class에서는 슈퍼 class에서 정의한 함수와 같은 함수를 정의할 수 없음
· 그러나 오버라이딩(슈퍼 클래서에서 허용)하면 사용 가능
· 수퍼 class에서 open을 붙이고 서브 class에서 override를 붙여서 구현하면됨
fun main() {
var a = Tiger("호돌이", 3)
a.eat()
var b = Animal("복슬이", 2, "강아지")
b.eat()
}
open class Animal (var name: String, val age: Int, var type: String){
open fun eat(){
println("${name}이가 먹는 중 입니다.")
}
}
class Tiger(name: String, age: Int) : Animal(name, age, "호랭이"){
override fun eat(){
println("${name}이는 고기를 먹는다.")
}
}
abstract
▷ 수퍼class에서는 함수의 구체적인 구현은 없고(내용은 없고)
· 각 서브 class가 비어 있는 함수의 내용을 채우게 함
fun main() {
var a = Rabbit("토고라", 3)
a.eat()
a.sneaf()
}
abstract class Animal (var name: String, val age: Int, var type: String){
abstract fun eat()
fun sneaf(){
println("킁..")
}
}
class Rabbit(name: String, age: Int) : Animal(name, age, "토끼"){
override fun eat(){
println("'${name}'는 당근을 먹는다.")
}
}
interface
▷ 다른 데서는 추상함수로만 이루 어진 추상 함수이나 kotlin에서는 추상함수와 일반함수 모두를 가질수 있음
· 추상함수는 생성자를 가질 수 있으나 interface는 가질 수 없음
▷ interface에서
· 구현부가 있는 함수 → open 함수로 간주
· 구현부가 없는 함수 → abstract 함수로 간주
· 키워드가 없어도 포함된 모든 함수를 서브 class에서 구현 및 재정의가 가능
▷ 한번에 여러 interface를 상속받을 수 있음// 좀더 유연한 설계가 가능
fun main() {
var dog = Dog()
dog.run()
dog.eat()
}
interface Runner {
fun run()
}
interface Eater {
fun eat(){ print("음식을 먹음") }
}
class Dog : Runner, Eater {
override fun run(){ println("빨리 뜀") }
}
// interface에서 같은 함수를 물려 받아 사용할 때 override로 재정의 해서 사용해야함
▷ 오버라이딩은 이미 구현이 끝난 함수를 서브 class에 변경할 때
▷ 추상화는 형식만 선언하고 나머지는 서브 class에 구현할 때
▷ interface는 서로 다른 기능들을 여러 개 물려주어야 할 때
'kotlin' 카테고리의 다른 글
Kotlin String (0) | 2023.01.14 |
---|---|
Kotlin List (0) | 2023.01.14 |
Kotlin class-03; Object, companion object, Generic (0) | 2023.01.14 |
Kotlin class-02 (0) | 2023.01.14 |
Kotlin 기본 형, loop ,if (0) | 2023.01.14 |