클래스와 설계
: 그룹화할 수 있는 함수와 변수를 한 곳에 모아 놓고 사용하기 쉽게 이름 붙인 것
클래스의 기본 구조
class 클래스명 {
var 변수
fun 함수() {
// 코드
}
}
-length변수로 문자열 길이 알 수 있고
-plus 함수로 문자열을 이어붙일 수 있음
-compareTo는 문자열을 비교하는 기능 제공
class String{
var length: Int
fun plus(other: Any){
// code
}
fun compareTo(other: String){
// code
}
}
클래스 코드 작성
class 클래스이름 {
// 클래스 스코프 (class scope)
}
생성자
*프라이머리 생성자(primary constructor)
class Person 프라이머리 생성자() {
}
class Person constructor(value: String){
// code
}
class Person(value: String){
// code
}
class Person(value: String){
init{
Log.d("class", "생성자로부터 전달받은 값은 ${value}입니다.")
}
}
class Person(val value: String) {
fun process() {
print(value)
}
}
*세컨더리 생성자(secondary constructor)
ex) init블록을 작성하지 않고 constructor 다음에 괄호를 붙여서 코드 작성 o
class Person {
constructor (value: string) {
Log.d("class", "생성자로부터 전달받은 값은 ${value}입니다.")
}
}
class Kotlin {
constructor (value: String){
Log.d("class", "생성자로부터 전달받은 값은 ${value}입니다.")
}
constructor (value: Int){
Log.d("class", "생성자로부터 전달받은 값은 ${value}입니다.")
}
constructor (value1: Int, value2: String){
Log.d("class", "생성자로부터 전달받은 값은 ${value1}, ${value2}입니다.")
}
}
*디폴트 생성자(Default constructor)
: 생성자 작성하지 않는 경우 파라미터가 없는 프라이머리 생성자가 하나 있는 것과 동일
class Student { // 생성자를 작성하지 않아도 기본 생성자가 동작합니다.
init {
// 기본 생성자가 없더라도 초기화가 필요하면 여기에 코드를 작성합니다.
}
}
클래스의 사용
:클래스의 이름에 괄호를 붙여 클래스의 생성자를 호출
(constructor 키워드를 호출하지는 x)
클래스명()
ex) kotlin클래스의 생성자를 호출한 후 생성되는 것= 인스턴스(instance)라고 하는데, 생성된 인스턴스는 변수에 담아둘 수 있음
var kotlin = Kotlin()
=> 붕어빵틀 = 클래스
=> 붕어빵 = 인스턴스
var one = Person("value")
// 또는
var two = Person(1004)
= 클래스의 변수 > 멤버 함수 > ----------프로퍼티(property)
= 클래스의 함수 > 멤버 함수 > ----------메서드 (method)
-> 클래스 안에 정의된 변수 = 프로퍼티(property)
-> 함수 안에 정의된 변수 = 변수 (지역변수)
class 클래스명 {
var 변수A // 프로퍼티: 함수 밖에 있어야 합니다.
fun 함수(){
var 변수B // 변수(또는 지역변수): 함수 안에 있어야 합니다.
}
}
ex) 프로퍼티와 메서드를 사용 위해 다음과 같이 프로퍼티 1개와 메서드 1개를 갖는 클래스를 만듦
class Pig {
var name: String = "Pinky"
fun printName(){
Log.d("class", "Pig의 이름은 ${name}입니다.")
}
}
-위에서 정의한 class를 생성자로 다음과 같이 인스턴스화해서 변수에 담기
var pig = pig()
-인스턴스가 담긴 변수명 다음에 도트 연산자(.)를 붙여서 프로퍼티와 메서드 사용
pig.name = "Pooh"
pig.printName()
/** 실행결과
Pig의 이름은 Pooh입니다.
*/
클래스 안에 정의된 함수와 변수 사용하기
오브젝트
: 클래스 생성자로 인스턴스화 하지 않아도 블록 안의 프로퍼티와 메소드를 호출해서 사용 o
-object는 클래스와 다르게 앱 전체에 1개만 생성
-클래스명 그대로 사용하기 때문에 호출하는 클래스명의 첫 글자는 대문자
object Pig{
var name: String = "Pinky"
fun printName() {
Log.d("class", "Pig의 이름은 ${name}입니다.")
}
}
-object 코드 블록 안의 프로퍼티와 메소드는 클래스명에 도트 연산자를 붙여서 생성자 없이 직접 호출 o
Pig.name = "Mikey"
Pig.printName()
컴패니언 오브젝터 (companion object)
-일반 클래스에 object 기능을 추가하기 위해서 사용
-위에서 작성한 Pig코드를 다음과 같이 companion object블록으로 감싸주면 생성 과정 없이 오브젝트처럼 사용 o
class Pig {
companion object {
var name: String = "None"
fun printName(){
Log.d("class", "Pig의 이름은 ${name}입니다.")
}
}
fun walk() {
Log.d("class", "Pig가 걸어갑니다.")
}
}
-위의 Pig는 class로 선언했기 때문에 일반 함수인 walk()는 생성자인 Pig()를 호출한 다음 변수에 저장한 후 사용 o
// companion object 안의 코드 사용하기
Pig.name = "Linda"
Pig.printName() // Pig의 이름은 Linda입니다.
// companion object 밖의 코드 사용하기
val cutePig = Pig()
cutePig.walk() // Pig가 걸어갑니다.
-Log 클래스의 메소드 d(), e() 모두 object 코드 블록 안에 만들어져 있기 때문에 생성자 없이 바로 호출해서 사용 o
데이터 클래스 (data class)
:간단한 값이 저장 용도로 data class 제공
data class 클래스명(val 파라미터1: 타입, var 파라미터2: 타입)
데이터 클래스를 정의할 때 class 앞에 data 키워드를 사용해야 하고, 생성자 파라미터 앞에 입력하는 var(val) 키워드는 생략 불가능)
생성하는 코드는 일반 클래스와 동일하게 작성
// 정의 - 주로 코드 블록(클래스 스코프)을 사용하지 않고 간단하게 작성합니다.
data class UserData(val name: String, var age: Int)
// 생성 - 일반 class의 생성자 함수를 호출하는 것과 동일합니다.
var userData = UserData("Michael", 21)
// name은 val로 선언되었기 때문에 변경 불가능합니다.
userData.name = "Sindy" // (X)
// age는 var로 선언되었기 때문에 변경 가능합니다.
userData.age = 18 // (O)
toString()메서드와 copy()메서드
-일반 클래스에서 toString()메서드를 호출하면 인스턴스의 '주소 값'을 반환하지만, 데이터 클래스는 '값'을 반환. 실제 값 모니터링할 때 좋음
Log.d("DataClass", "DataUser는 ${dataUser.toString()}")
// DataUser는 DataUser(name=Michael, age=21)
var newData = dataUser.copy()
일반 클래스처럼 사용하기
-일반 클래스와 동일하게 생성자 호출 -> init 블록 동작, 메서드도 사용 o
data class UserData(var name: String, var age: Int){
init{
Log.d("UserData", "initialized")
}
fun process(){
// 클래스와 동일하게 메서드 사용이 가능합니다.
}
} // 클래스가 생성되면 "initialized"가 출력됩니다.
// 메소드 설계
// 특정한 로직을 가지는 소스코드에 별명(이름)을 붙일 수 있어요
// 이름이 붙은 로직은 앞으로 메소드라고 부를 수 있어요
// 코틀린의 메소드 기본 구조
fun 메소드이름(변수명:자료형, 변수명:자료형 ....) : 반환자료형 {
소스코드 로직
}
//ex)
// 두 개의 숫자를 더하는 메소드를 만들고, 전달하는 숫자에 따라 덧셈결과를 알려줘요
// sum메소드는 매개변수로 num1과 num2를 요구해요
// 필수로 매개변수를 넣어줘야 호출할 수 있어요
fun main() {
var num1 = readLine()!!.toInt()
var num2 = readLine()!!.toInt()
// sum이라는 이름의 메소드를 호출!
sum(num1, num2)
}
fun sum(num1:Int, num2:Int) {
var result = num1 + num2
println("num1과 num2의 덧셈결과는 ${result}입니다.")
}
fun main() {
// displayInfo라는 이름의 메소드를 호출!
displayInfo()
}
fun displayInfo() : Unit {
println("오늘의 날씨는 화창합니다")
println("오늘은 검정색을 조심하세요")
}
fun main() {
var myMathScore = readLine()!!.toInt()
var myRank = checkRank(myMathScore)
println("나의 등급은 : ${myRank}")
}
fun checkRank(score:Int) : String {
return when(score) {
in 90..100 -> return "A"
in 80..89 -> return "B"
in 70..79 -> return "C"
else -> return "D"
}
}
if(score >= 90) {
return "A"
} else if(score >= 80) {
return "B"
} else if(score >= 70) {
return "C"
} else {
return "D"
}
}
-속성 properties : var, val 같은 걸로 설정
-메소드 methods : 함수가 들어갈 수 있겠지
-생성자 constructor :
: 주생성자 (초기화코드)
: 부생성자 constructor를 통해서 오버로딩