코드테스트 사이트:play.kotlinlang.org
참조:유튜브 디모의 코틀린
//observer(옵저버):이벤트가 일어나는 것을 감시하는 감시자
//이벤트: ex.안드로이드에서, 키의 입력, 터치의 발생, 데이터의 수신 등
// 함수로 직접 요청하지 않았지만 시스템 또는 루틴에 의해서 발생하게 되는
// 동작들
//옵저버 패턴:이벤트가 발생할 때마다 '즉각적으로 처리'할 수 있도록 만드는
// 프로그래밍 패턴
//이벤트 수신하는 클래스와 이벤트 발생 및 전달하는 클래스,총 두개 클래스 필요
//후자 클래스는 전자 클래스를 참조할 수 없어서 둘을 매개하는
// '인터페이스'를 사용함
//후자에서는 자신의 이벤트를 받을 수 있는 인터페이스를 만들어 공개하고,
// 전자는 이를 구현하여 후자에 넘겨줌. 이 인터페이스를 observer라 함
// 또는 listener (in kotlin)
//callback:이벤트를 넘겨주는 행위
//옵저버 패턴을 구현해봅시다~
//이벤트를 수신해서 출력하는 eventprinter클래스와
//숫자를 카운트하여 5의 배수마다 이벤트를 발생시킬 counter클래스
//그리고 이 둘을 연결할 인터페이스인 EventListener 인터페이스
fun main() {
EventPrinter().start()//메인함수에서는 EventPrinter의 인스턴스를
//생성하고 부탁할 start 함수만 호출해주면 됨
}
interface EventListener {//인터페이스로서 이벤트 발생할때
//숫자 반환할 예정
fun onEvent(count: Int)//추상함수(?)만들고 패러미터로 정수 넘겨줌
}
class Counter(var listener: EventListener){
//이벤트 발생 클래스, 이벤트 발생 위해 인터페이스eventlistener를
// 속성으로 받음
fun count(){
for(i in 1..100){//1~100 반복하면서
if(i % 5==0) listener.onEvent(i)
//5의 배수 될때마다 인터페이스의 onevent함수 호출함
}
}
}
class EventPrinter: EventListener{//이름대문자잊지말기
//이벤트를 받아서 화면에 호출할 클래스
//EventListener 인터페이스를 상속하여 구현해야 함
override fun onEvent(count: Int) {//인터페이스의
//on event 함수를 오버라이딩해서
print("${count}-")//받아온 숫자와 대시문자 출력
}
fun start() {//새로운 함수 추가해주고
val counter = Counter(this)//이벤트 발생 클래스인
//Counter 클래스의 인스턴스를 만들어주고
//this라는 키워드로 Eventlistener()의 구현부 넘겨줌(?그냥 넘겨줬단 뜻인듯?)
counter.count()//그리고 count를 시작하게 해보죠(???)
}
//여기서 this는 EventPrinter객체 자신을 나타내지만
//받는 쪽에서 EventListener만 요구했기 때문에
//EventListener구현부만 넘겨주게 됨!
//(아하~ EventPrinter 클래스의 내부에서 this라는 키워드를 써서
//사실상 EventPrinter를 넘겨줘야하는데 EventPrinter가 EventListener를 상속받았으므로
//EventListener만 요구될 때에도 걔를 넘겨줄 수가 있다~)
//이를 '객체지향의 다형성'이라고 함(음...글쿤...)
//상속받아 만들어진 클래스는 수퍼클래스의 기능을 포함하여 제작되었으므로
//수퍼클래스에서 정의한 부분만 따로 넘겨줄 수 있다.
}
//실행해보면 Counter가 5의 배수마다 이벤트를 발생시킨 것을
//EventPrinter 내에서 구현된 EventListener에서 '출력'하고 있음을
//알수있음(마지막 대시 없애는 방법도 고민해봅시다)
//그런데 EventPrinter가 EventListener를 상속받아 구현하지 않고
//'임시로 만든' 별도의 EventListener객체를 대신 넘겨줄 수도 있음!!
//이것을 '이름이 없는 객체'라 하여 '익명 객체'라고 함
//"익명객체"
//EventPrinter클래스 지우고 다시시작~
fun main() {
EventPrinter().start()
}
interface EventListener {
fun onEvent(count: Int)
}
class Counter(var listener: EventListener){
fun count(){
for(i in 1..100){
if(i % 5==0) listener.onEvent(i)
}
}
}
class EventPrinter {//이번엔 EventListener를 상속받지 않고
fun start() {//바로 start함수 만들어보자
val counter = Counter(object:EventListener{
override fun onEvent(count:Int){ //onEvent를 override함
print("${count}-")
}
})//(하나의 파라미터임)
//그리고 카운터 인스턴스 만들 때
//패러미터에 익명 객체 만들어서 넘김
//'오브젝트'라는 키워드 여기서 사용!
//object라 쓰고 이름없이 바로 콜론 쓰고 EventListener를
//상속받게 하고
//object부터 여기까지 긴 문장이 익명함수로 넘길 단 한개의 파라미터임 놀랍게도...
counter.count() //항상 함수에는 ()붙어야한다는 점!!!
}//지난 시간의 object와 형태는 비슷하나 차이는 '이름이 없다는 점'
// 이렇게 만들면 인터페이스를 구현한 객체를 코드 중간에도 '즉시' 생성하여
//사용할 수 있다
}
//observer 패턴은 이벤트를 기반으로 동작하는 모든 코드에서 광범위하게 쓰이는
//방식이므로 그 구조를 이해하는 것이 중요하다
코드실행 안되는데 좀 이해하고 다시 보려고 일단 저장;;;ㅎㅎ^^
드디어 이해했다...(23.05.04.)
'코틀린 문법' 카테고리의 다른 글
6. 형변환과 배열, 타입추론과 함수 (0) | 2023.04.30 |
---|---|
5. 변수와 자료형-코틀린 (0) | 2023.04.30 |
3. 오브젝트-코틀린 6일차-(2) (0) | 2023.04.04 |
2. 고차함수,람다함수, 스코프함수-코틀린 6일차 (0) | 2023.04.04 |
1. 프로젝트 구조, 스코프-코틀린 5일차 (0) | 2023.04.04 |