-
생성자, 상속, 인터페이스, 오버라이딩, 오버로딩Android 2024. 3. 6. 23:46
09:00 ~ 11:00 : 알고리즘 27번, 28번 풀기
- 27번 문제
- arr : String = "12345" 라고 할 때, arr[0] 값을 가져올 수는 있지만 arr[0] 값을 바꿀 수는 없었다 (처음 풀 때 이렇게 풀었는데 오류남!)
- 해결 방안 : String 을 .toCharArray() 함수를 활용하여 배열로 바꾼 후에 인덱스로 접근하여 배열의 값을 바꿔야 했다. 또한, 이후 배열을 String() 함수를 이용해 다시 문자열로 바꾸어야 한다!
- String 에 대한 함수로는 lastIndex 함수와 slice 함수가 있다. lastIndex 함수는 마지막 문자의 인덱스 값을 가져오고, slice 함수는 arr.slice(3..5) 이런 식으로 쓰여 인덱스 3 ~ 인덱스 5 값을 반환한다. → 두 함수를 이용하면 굳이 배열로 바꾸지 않아도 문제 해결이 가능하다
- 28번 문제
- arr : IntArray = [ 1, 2, 3 ] 이라고 가정하자. 이때, 배열이 특정 원소 1를 포함하는지 확인하려면 arr.contains(1) 를 하면 되고, 반환 값은 true 이다. 또한, if(1 in arr) = true 도 가능하다.
- 0 부터 9 사이의 값 중 arr 에 포함되지 않는 숫자를 합하는 코드 → (0..9).filterNot(arr::contains).sum()
- (0..9).sum() - arr.sum() 도 가능하다
내가 스스로 문제를 답을 보지 않고 푸는 것도 중요하지만, 풀고 나서도 다른 사람들의 풀이를 1~2 개 참고하면서 다른 접근법을 익혀나가는 것도 중요한 것 같다!
11:00 ~ 13:00 : 코틀린 문법 종합반 강의 듣기
14:00 ~ 15:00 : Zoom 추가 문법 설명회 듣기
15:30 ~ 18:00 & 19:00~19:30 : 코틀린 문법 종합반 강의 듣기
- 클래스(설계도)는 실체화할 때 최초로 실행할 로직이다.
- 클래스 내에는 변수, 생성자, 메소드가 작성된다.
- 생성자는 클래스에 따로 명시하지 않아도 되는 기본생성자와 명시적생성자로 분류된다.
- 기본 생성자 : 명시 X
- 명시적 생성자 : 명시 O
- 주생성자: 클래스 선언부에 생성자 명시, 클래스 내부에 init 생성자 명시
- 부생성자 : 클래스 선언부에 생성자 명시X, 클래스 내부에 constructor 생성자 명시 및 여러 생성자 선언 가능
// 주생성자 class Character(_name: String, _hairColor: String, _height: Double) { init { .. } } // 부생성자 class Character { constructor(_name:String, _hairColor:String, _height:Double) { .. } constructor(_name:String, _hairColor:String, _height:Double, _age:Int, _gender:String) { .. } }
- 사용자로부터 값을 받아올 때는 문자열, 실수형이 가능하다.
// 실수형 var myName = readLine()!! // 정수형 var myAge = readLine()!!.toInt()
// 클래스 선언 방식 var myCharacter = Wizard(myName, myAge, myGender, myMoney, myHp, myMp)
- 상속 : 부모 클래스와 자식 클래스가 존재하며, 부모 클래스에는 앞에 open 키워드를 써준다. 자식 클래스는 콜론 다음에 부모클래스의 이름을 지정한다.
open class Bird { fun fly() { println("새는 날아요~") } } // 전부 Bird 클래스를 상속을 받는다. class Chicken : Bird() {} class Sparrow : Bird() {} class Pigeon : Bird() {}
- 클래스는 인자를 전달받을 수 있으며, 전달 받은 인자는 생성자를 거쳐 클래스 내의 변수에 저장된다. 자식 클래스도 인자를 통해 부모 클래스로 접근할 수 있다.
var bird = Bird("새") var chicken = Chicken("닭") open class Bird(name:String) { var name : String = "" init { this.name = name } } class Chicken(name:String) : Bird(name) {}
- 오버라이딩 : 자식 클래스가 부모 클래스에 선언되어 있는 메소드를 쓰기 싫을 때, 자식 클래스 내에서 같은 이름으로 메소드를 작성할 수 있다 → 자식 클래스의 객체가 fly() 메소드를 호출할 때 부모 클래스의 메소드를 호출하는게 아니라 자식 클래스의 메소드를 호출한다!
- super.fly() 는 오버라이딩시 자동으로 생성되는데 부모객체의 fly 메소드를 부르는 행위로 주석처리한다!
open class Bird(name: String) { open fun fly() { .. } } class Chicken(name: String, age: Int) : Bird(name) { override fun fly() { //super.fly() } }
- 인터페이스 : 인터페이스 내부에는 로직이 존재하지 않는 메소드, 즉 추상 메소드를 선언한다.
- Duck 클래스가 Bird 부모 클래스를 상속 받지만, 부모 클래스 내부에서 필요한 메소드를 찾지 못하는 경우(오리는 날지 못한다...) 따로 인터페이스에서 필요한 메소드를 선언하고 오버라이딩 하는 형식으로 불러쓸 수 있다.
class Duck(name:String) : Bird(name), WaterBirdBehavior { override fun swim() { println("${name}가 수영해요~") } } ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ(서로 다른 파일)ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ interface WaterBirdBehavior { fun swim() }
- 오버 로딩 : 클래스 내에서 전달 인자의 자료형이나 수가 다를 경우 같은 이름의 메소드를 여러번 사용할 수 있다!
class Calculator { fun add(num1: Int, num2: Int): Int { return num1+num2 } fun add(num1: Double, num2: Double): Double { return num1+num2 } }
- 참고할 만한 다른 코드 ...
// 배열에서 원소 값에 접근하는 방식 var names = arrayOf("참새", "꿩", "비둘기") for (name in names) { .. }
결론 : 오버라이딩, 오버로딩, 상속, 인터페이스 네 가지의 개념을 명확하게 구분하여 이해하는 것이 필요하다! 까먹거나 헷갈리기 시작하면 다시 복습하자 !!
19:30~20:30 : 이번주 과제 풀기
계산기 과제를 푸는데 ... 3주차 개념까지 들으면 풀 수 있다고 했는데 막상 직접 풀자니 "어? 생성자 굳이 써야하나?", "인터페이스 어떻게 넣는거지...", "오버라이딩 언제 써야해?!" 등등 생각보다 막막했다 ㅋㅋㅋ 해당 개념을 이해를 해도 코드를 구현할 때 저 개념을 언제, 어떤 자리에 쓰는게 적절한지는 아예 감이 아직 안잡혔다 ㅠㅠ 확실히 강의만 듣지 말고 직접 코드를 손으로 써보는 실습도 매우 매우 중요한 것 같았다..
'Android' 카테고리의 다른 글
CharArray, Zip, Map, Array, Collection (0) 2024.03.08 접근 제한자,지연 초기화, 널 세이프티 (0) 2024.03.07 fold / foldIndexed 함수, 자료형 정리, 증감연산자 (0) 2024.03.05 2024-03-04 BOOTCAMP TIL (3) 2024.03.04 2024/02/29 BOOTCAMP TIL (1) 2024.02.29 - 27번 문제