객체지향 프로그래밍

imssu·2023년 3월 29일
0

Kotlin

목록 보기
3/3
post-thumbnail

클래스와 생성자


클래스

  • 본문에 입력하는 내용이 없다면 {}생략 가능

  • 클래스의 멤버는 생성자, 변수, 함수, 클래스

class User {
	var str = "string" // 변수
    constructor(name: String) { // 생성자
    	this.name = name
    }
    fun someFun() { // 함수
    	println("이름: $name")
    }
    class SomeClass {} //내부 클래스
}
  • 객체 생성할 때 new 키워드를 사용하지 않음

val user = User("kim")

생성자- 주 생정자/보조 생성자

주 생성자

  • constructor 키워드 사용 -> 클래스 선언부에 선언
  • 선언이 필수가 아니며 선언은 한 클래스에 하나만 가능
  • constructor 키워드는 생략 가능
  • 본문 영역은 init 키워드 사용- 객체를 생성할 때 자동 실행
class User constructor(name: String, count: Int) { //생성자의 매개변수
	init{ //본문
    	println("Hellow")
    }
}

class User() {
} //constructor 키워드 생략

class User {
} //매개변수가 없는 주 생성자 자동 선언
  • 생성자의 매개변수는 생성자에서만 사용할 수 있는 지역변수이므로 본문이 아닌 함수, 클래스에서 사용이 불가함
    -> 매개변수를 클래스의 멤버 변수로 만들면 사용 가능
  • var, val 키워드로 매개변수를 선언하면 클래스의 멤버 변수가 됨
  • 생성자의 매개변수는 그 객체의 필수 정보라고 볼 수 있음
class User(val name: Stirng, val count: Int) {
	fun someFun() {
    	println("이름: $name, 횟수: $count") //Ok
    }
}
fun main() {
	val user = User("Kim", 10)
    user.someFun()
}

보조 생성자

  • 클래스의 본문에 constructor 키워드로 선언
  • 여러 개 추가 가능
  • 이름이 같은 생성자도 생성 가능(다형성, 오버로딩)
  • 보조 생성자로 객체를 생성할 때 주 생성자를 연결해야 함
    -> this() 구문 사용하여 주 생성자 호출/ 주 생성자의 매개 변수가 없다면 생략
class User(name: String) {
	constructor(name: String, count: Int): this(name) {
    ...
    }
}
fun main() {
	val user = User("kim", 10)
}

this() 구문으로 주 생성자를 먼저 호출하고 그 다음 보조 생성자인 constructor 실행


상속

  • 선언부에 상속받을 :(클래스 이름) 입력
  • 기본적으로 다른 클래스를 상속할 수 없음
    -> open 키워드 사용
open class Super(name: String) {
}
class Sub(name: String): Super(name) {
}

open class Super(name: String) {
}
class Sub: Super {
	constructor(name: String): Spuer(name) {
    }
}
  • 오버라이딩/재정의의 이점
    -> 상위 클래스에 정의된 멤버를 하위 클래스에서 자신의 멤버처럼 사용할 수 있음
  • 재정의할 때 주의점
    -> 변수와 함수에도 open override키워드를 각각 붙여주어야 함
open class Super {
	open var someData = 10
    open fun someFun() {
    	println("hello $someData")
    }
}
class Sub: Super() {
	override var someData = 20
    override fun someFun() {
    	println("world $someData")
    }
}
fun main() {
	val obj = Sub()
    obj.someFun()
}

obj의 멤버변수 몇 개?
재정의를 하면 상위 클래스의 멤버 변수의 이름을 복사해서 새로운 멤버 변수를 만들기 때문에 Super의 someData, Sub의 someData로 총 2개 이다.

접근 제한자

클래스의 멤버를 외부 어느 범위까지 이용 가능하게 할지 결정

접근 제한자 최상위에서 이용 클래스 멤버에서 이용
public 모든 파일에서 가능 모든 클래스에서 가능
internal 같은 모듈 내에서 가능 ex) app 파일 내에서(package와 유사)
protected 사용 불가 상속 관계의 하위 클래스에서만 가능
private 파일 내부에서만 이용 클래스 내부에서만 이용

코틀린 클래스 종류

데이터 클래스

  • data 키워드로 선언
  • VO 클래스를 편리하게 이용할 수 있는 방법 제공

    VO 클래스는 ValueObject로 데이터의 묶음을 상수로 사용하는데 용이하다.
    ex) 주소 -> 시, 구, 동

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 = NonDataCalss("Kim", "@.com", 10)
val non2 = NonDataCalss("Kim", "@.com", 10)

val data1 = NonDataCalss("Kim", "@.com", 10)
val data2 = NonDataCalss("Kim", "@.com", 10)

equals() 함수로 비교하면 true일까?
equals() 함수는 객체의 데이터(id)를 비교하는 함수로
data1과 data2는 데이터를 묶어 상수로 취급하기 때문에 자동으로 equals() 함수가 자동으로 재정의가 되어 들어간 데이터 값이 같으면 같은 객체로 보게된다.
따라서 data1과 data2는 true값이 나오지만 non1과 non2는 false가 나오게 된다.
equals() 함수는 클래스의 주 생성자 멤버 변수의 데이터만 대상으로 삼음. 또한 상수를 비교하는 것이기 때문에 선언할 때 var 키워드는 사용하지 않는다.

toString() 함수로 데이터 클래스 객체가 가지는 값을 확인할 수 있다.


오브젝트 클래스

  • 익명 클래스를 만들 목적으로 사용(이름 없는 클래스)
  • 선언과 동시에 객체를 생성-> object 키워드 사용
val obj = object {
	var data = 10
    fun some() {
    	println("hi, $data")
    }
}
fun main() {
	obj.data = 20 //오류
    obj.some()    //오류
}

오류가 나는 이유?
객체의 클래스를 알 수 없기 때문에 최상위인 Any 클래스로 취급하며 data라는 변수나 some() 함수를 찾을 수 없기 때문이다.

그렇다면?
어떤 클래스인지 알려주는 상위 클래스가 필요

open class Super {
	open var data = 10
    open fun some() {
    	println("hi")
    }
}//또는 
interface class Super {
	var data = 10
    fun some() {
    	println("hi")
    }
}

val obj = object: Super() {
	override var data = 10
    override fun some() {
    	println("hi, $data")
    }
}
fun main() {
	obj.data = 20 //오류
    obj.some()    //오류
}

컴페니언 클래스

  • static과 유사
  • 멤버 변수나 함수를 클래스 이름으로 접근할 때 사용
  • companion 키워드 사용
class someClass {
	companion object {
    	var data = 10
        fun some() {
        	println(data)
        }
    }
}
fun main() {
	someClass.data = 30
    someCalss.some()
}	
profile
안녕하세요!

0개의 댓글