[Kotlin 문법 종합] - 메소드, 클래스
1. 메소드
: 특정 동작을 하는 소스코드에 이름을 붙임 //ex. sum
(+) 추상화, 간결해짐
(+) 코드의 재사용성
fun 메소드이름(변수명:자료형, 변수명:자료형 ....) : 반환자료형{
//소스코드 로직
} //( ) 안의 것들은 매개변수 parameter
//반환자료형이 없는 경우 Unit 또는 생략 가능 (ex. println)
fun myInfo(): Unit {
//코드
}
(예시 - 점수 입력 후 등급 출력하는 코드)
fun main(){
var myScore = readLine()!!.toInt()
var myRank = turnRank(myScore)
//println("rank : ${myRank}")
}
fun turnRank(score:Int) : String{
return when(score){
in 90..100 -> return 'A' //범위표기법 주목
in 80..89 -> return 'B'
in 70..79 -> return 'C'
else -> return 'D'
}
}
// when에 in 90..100 이런식으로 쓰지 않고
// if에 구간별로 나눈 건
// Kotlin 컨벤션을 따르지 않은 형태...라는데
// 뭔말일까
// 동일한 함수의 다양한 작성법
fun sum(a : Int, b : Int): Int{
var sum = a + b
return sum
}
fun sum(a : Int, b : Int) : Int{
return a + b
}
fun sum(a : Int, b : Int) : Int = a + b
fun sum(a : Int, b : Int) = a + b
// 매개변수의 일부만 전달 시 자동으로 기본값 입력하기
fun exampleAdd(name : String, address : String = "default"){
//address로 넘어오는 값이 없으면 자동으로 "default" 입력함
}
fun main(){
exampleCode(x = 100, y = 200)
exampleCode(x = 100)
}
fun exampleCode(x:Int, y:Int = 300, z:Int = 150){
println(x+y+z)
}
//450
//550
// 가변 인자 Variable Argument
fun main(){
varargExample(1,2,3,4)
varargExample(1,2,3,4,5)
}
fun varargExample(vararg counts: Int){ //counts를 가변인자로 지정, int형 배열
for (num in counts){
print("$num")
}
println("")
}
//1 2 3 4
//1 2 3 4 5
2. 클래스
1. 객체지향 프로그래밍
: 객체(object) 단위로 처리함
- java, c++ 등
*키워드
(1) 클래스
(2) 추상화
(3) 캡슐화 Encapsulation
: 외부의 잘못된 사용으로 객체가 손상되는 것을 막음
(4) 상속 Inheritance
: 코드 재사용 가능, 일괄 업데이트로 관리 타임 짧아짐
(5) 다형성 Polymorphism
: 사용방법이 동일하지만 실행결과가 다양하게 나옴
// 절차지향 프로그래밍 : c, 포트란, 알골 등
// 함수형 프로그래밍 : 스칼라, R 등
2. 클래스
: 프로그램의 각 요소별 설계도
- 정보와 행위(메소드) 작성함
- 하나의 파일에 하나 이상의 클래스 존재 가능
class 클래스이름{
정보 1 //자료형 명시해주기. (생성자 있으면 안해도 ㄱㅊ)
정보 2 //string이면 ""
행위 1
행위 2
}
1. 데이터 클래스 data class
: 정보(프로퍼티)만 가지고 있는 클래스
- 기본 생성자에 1개 이상의 매개변수가 변수나 상수로 존재해야 함
- abstract, open, sealed, inner를 사용할 수 없음
*자동으로 만들어지는 메소드들
(1) hashCode() : 객체 구분을 위한 고유값 리턴. 동일하다면 동일한 정숫값을 생성함
(2) equals() : 동일한 객체인지 비교해 참/거짓을 리턴함
(3) copy() : 현 객체의 모든 정보를 복사 후 새 객체를 리턴함.
(특정 프로퍼티 = "~" 한 경우 빌더 없이 특정 프로퍼티만 변경해 객체 복사함)
(4) toString() : 데이터 객체를 읽기 편한 문자열로 반환
(5) getXXX() / setXXX(매개변수) : 변수의 값 리턴 혹은 설정
(6) //객체 디스트럭처링하기 -> val (가져올 프로퍼티1, _(안가져올경우) = 가져올 해당 객체)
(7) //개별적으로 프로퍼티 가져오기 -> val email2 = 해당객체.component2()
data class 클래스이름 {
정보1
정보2
}
+ 중첩 클래스 (nested)
: 객체 생성 없이 중첩 클래스의 메서드 접근 가능 ( 원래 클래스.Nested.함수명() )
//특정 메서드의 블록이나 init블록 등에 있지 않은 것! (<- 지역 클래스)
- 중첩된 Nested 클래스는 바로 바깥 클래스의 멤버에는 접근 불가능
- but 바로 바깥 클래스가 컴패니언 객체를 갖고있으면 접근 가능 (static처럼 접근 가능하니까)
2. 실드 클래스 sealed class
: 클래스 상속과 관련, 상속받을 수 있는 클래스들을 미리 정의
- 객체를 만들 수 없음 (상속은 가능, 생성자도 기본적으로는 private)
(+) 무분별한 상속을 방지
(+) 컴파일 시점에 생성할 수 있는 자식을 알 수 있어 다형성 구현
sealed class 부모클래스 {
class 자식클래스1 : 부모클래스생성자
class 자식클래스2 : 부모클래스생성자
}
// 1. 실드 클래스 선언 방법 첫번째 스타일
sealed class Result {
open class Success(val message: String): Result()
class Error(val code: Int, val message: String): Result()
}
class Status: Result() // 실드 클래스 상속은 같은 파일에서만
class Inside: Result.Success("Status") // 내부 클래스 상속
// 2. 실드 클래스 선언 방법 두번째 스타일
/*
sealed class Result
open class Success(val message: String): Result()
class Error(val code: Int, message: String): Result()
class Status: Result()
class Inside: Success("Status")
*/
fun main() {
// Success에 대한 객체 생성
val result = Result.Success("Good!")
val msg = eval(result)
println(msg)
}
// 상태를 검사하기 위한 함수
fun eval(result: Result): String = when(result) {
is Status -> "in progress"
is Result.Success -> result.message
is Result.Error -> result.message
// 모든 조건을 가지므로 else 가 필요 없다
}
Good!
3. 오브젝트 클래스 object class
: 프로그램 실행과 동시에 인스턴스화 (java의 static 대신 사용하는 키워드)
//프로그램 메모리에 바로 올라가서 사용 가능하게 됨
//관련해서는 아래 글 이어서 읽기
2024.03.06 - [언어/Kotlin] - [Kotlin 문법 종합] - Single-expression function, 싱글턴 (@@질문하기)
[Kotlin 문법 종합] - Single-expression function, 싱글턴 (@@질문하기)
1. Single-expression function : 람다식을 이용해 메소드를 간결하게 정리 가능 * 람다식 구조 : 다른 함수의 인자로 넘김 / 함수의 결과값으로 반환 / 변수에 저장 하는 함수 {매개변수1, 매개변수2... ->
sugapowderjj.tistory.com
2024.03.15 - [언어/Kotlin] - [Kotlin 공부] object와 싱글톤, object와 compaion
[Kotlin 공부] object와 싱글톤, object와 compaion
dd
sugapowderjj.tistory.com
* 익명 객체와 다름! 익명객체는 아래 v
interface Switcher{
fun on(): String
}
class Smartphone(val model: String){
fun powerOn(): String{
class Led(Val color: String){
fun blink(): Stirng = "Blinking $color on $model"
}
val powerStatus = Led("Red")
val powerSwitch = object : Switcher{ //익명 객체를 사용해 switcher의 on() 구현
override fun on(): String{
return powerStatus.blink()
}
}//익명(object)객체 블록의 끝
}
}
// 인터페이스의 메소드 구현을 익명 객체 안에서 해도 됨 (밖에 따로 만든 걸 받아와도 ㄱㅊ)
4. 열거 클래스 enum class
: 여러 곳에 동일한 상수를 정의하는 등의 경우에 용이한 관리를 위해 사용
- 다양한 자료형을 다루지는 못함. 자료형이 동일한 상수를 나열함
- 프로퍼티 혹은 메서드를 담을 수 있음
- 각 상수의 값은 () 매개변수를 통해 초기화할 수 있음
enum class DayOfWeek(val num: Int){
MONDAY(1), TUESDAY(2), WEDNESDAY(3), THURSDAY(4),
FRIDAY(5), SATURDAY(6), SUNDAY(7)
}
fun main(){
val day=DayOfWeek.MONDAY //Monday의 값 읽기
when(day.num){
1,2,3,4,5 -> println("Weekday")
else -> println("weekend")
}
}
Weekday
enum class Color(val r:Int, val g:Int, val b: Int){
RED(255,0,0), ORANGE(255,165,0), YELLOW(255,255,0),
GREEN(0,255,0), BLUE(0,0,255), INDIGO(75,0,130),
VIOLET(238,130,238); //세미콜론으로 끝 알림
fun rgb() = (r*256 + g) * 256 + b //메서드 포함
}
fun getColor(color : Color) = when (color){
Color.RED -> color.name //이름 가져옴 RED
Color.ORANGE -> color.ordinal //순서 번호 : 1
Color.YELLOW -> color.toString() //문자열 변환
Color.GREEN -> color //기본값 (문자열) GREEN
Color.BLUE -> color.r //r값
Color.INDIGO -> color.g
Color.VIOLET -> color.rgb() //연산 결과
}
fun main(){
println(Color.BLUE.rgb())
println(getColor(Color.RED))
}
255
interface Score {
fun getScore(): Int
}
enum class MemberType(var prio: String) : Score {
NORMAL("Thrid") {
override fun getScore(): Int = 100 //구현된 메서드
},
SILVER("Second") {
override fun getScore(): Int = 500
},
GOLD("First") {
override fun getScore(): Int = 1500
}
}
fun main() {
println(MemberType.NORMAL.getScore())
println(MemberType.GOLD)
println(MemberType.valueOf("SILVER"))
println(MemberType.SILVER.prio)
for (grade in MemberType.values()) { //모든 값을 가져오는 반복문
println("grade.name = ${grade.name}, prio = ${grade.prio}")
}
}
100
GOLD
SILVER
Second
grade.name = NORMAL, prio = Thrid
grade.name = SILVER, prio = Second
grade.name = GOLD, prio = First
//prio는 내가 바꿔 불러도 됨. numnum 이런것도 가능
- Comparable 인터페이스를 구현하는 추상 클래스 //추가 공부 필요...
enum class 클래스1 {
C, JAVA, KOTLIN
}
enum class 클래스2(val code:Int){
C(10),
JAVA(20),
KOTLIN(30)
}
fun main(){
println(클래스1.C.toString()) //C
println(클래스2.KOTLIN.code) //30
println(클래스2.KOTLIN.name) //KOTLIN
}
code: 클래스2 enum 클래스의 생성자에 정의됨. 각 enum 인스턴스에 대해 별도로 값 설정
name: enum 클래스의 속성, enum 상수의 이름을 문자열로 반환