1. 인터페이스
: 부모 클래스와 별개로 다른 그룹과 겹치는 기능 구현 시 사용...
- 근본적인 공통점을 상속받고, 추가적인 기능들은 인터페이스로 추가
- 추상메소드 사용 권장 (구현 시 정의, 구현 필수)
//인터페이스는 다중구현 가능, 클래스는 다중상속 불가능
//인터페이스는 그 자체의 인스턴스 필드를 갖지 못함
//인터페이스 : 인터페이스 가능
interface WaterBirdBehavior {
//변수 값을 가질 수는 없음. 상수는 가질 수 있어도
fun swim()
//추상메소드 쓰는 게 좋음...
// fun swim() {
// println("수영 합니다")
// }
}
fun main() {
var bird = Bird("새")
var chicken = Chicken("닭")
var duck = Duck("오리")
bird.fly()
chicken.fly()
duck.swim()
}
open class Bird(name:String) {
var name: String = ""
init {
this.name = name
}
fun fly() {
println("${name} 날아요~")
}
}
class Chicken(name: String) : Bird(name) {}
class Duck(name: String) : Bird(name), WaterBirdBehavior {
//java와 다르게 클래스 옆에 implements ~~ 안해도 되나봄
//구현할 때 정의 필수, 구현 필수
override fun swim() {
println("${name}가 수영해요~")
}
}
//프로퍼티는 오직 추상 메서드로 선언(abstract 키워드 없어도 추상)
단, val로 선언된 프로퍼티는 get() 통해 필요한 내용 구현 가능, override 사용하기
interface Pet{
var category: String
fun feeding()
fun patting(){
println("Keep Patting")
}
}
class Cat(override var category: String) : Pet{
override fun feeding(){
println("Feed the cat a tuna can")
}
}
fun main(){
val obj = Cat("small")
println("Pet Category : ${obj.category}")
obj.feeding() //구현된 메서드
obj.patting() //기본 메서드
}
//Pet Category : small
//Feed the cat a tuna can
//Keep Patting
...
interface Pet{
var category: String
val msgTags: String
get()= "I'm your pet"
fun feeding()
fun patting(){
println("Keep patting")
}
}
...
println("${obj.msgTags}")
...
- msgTags 초기화는 불가능하지만 get() 통해 반환값을 지정할 수 있음(value를 저장하지는 못함)
//메서드는 추상, 일반(구현부 포함) 메서드 모두 가능
//인터페이스와 오버로딩
interface Pet{
var category: String
val msgTags: String
get()= "I'm your pet"
var species: String //종을 위한 프로퍼티
fun feeding()
fun patting(){
println("Keep patting")
}
}
open class Animal(val name: String)
class Dog(name: String, override var category: String) : Animal(name), Pet {
override var species: String = "dog"
override fun feeding() {
println("Feed the dog a bone")
}
}
class Cat(name: String, override var category: String) : Animal(name), Pet {
override var species: String = "cat" //프로퍼티를 오버라이딩해 종을 특정
override fun feeding() {
println("Feed the cat a snack")
}
}
class Master{
//species 한 뒤에는
fun playWithPet(pet: Pet){ //인터페이스를 객체로 매개변수를 지정
println("Enjoy with my ${pet.species}")
}
fun playWithPet(dog: Dog){ // 종류에 따라 오버로딩
println("play with Dog")
}
fun playWithPet(cat: Cat){
println("play with Cat")
}
}
fun main(){
val master = Master()
val dog = Dog("탄이", "small")
val cat = Cat("무", "big")
master.playWithPet(dog)
master.playWithPet(cat)
}
- fun playWithPet(pet: Pet) 부분은 해당 객체의 실제 유형에 따라 실행되는 코드가 결정됨
//여러개의 인터페이스를 상속받았는데 이미 구현되어있는 동작을 override하려고 함,
근데 이름이 인터페이스끼리 겹친다면
class 클래스명 : 인페1, 인페2{
override fun jump(){
super<구현된동작을 상속받아올 인터페이스명>.동작이름()
println("do it")
}
}
fun main(){
val ex1 = 클래스명()
ex1.jump()
}
//by 를 통한 인터페이스의 위임
interface A {
fun functionA()
}
interface B {
fun functionB()
}
class C(val a: A, val b: B) {
fun functionC() {
a.functionA()
b.functionB()
}
}
^ 위는 functionA(), functionB() 에 접근하기 위해 a, b 변수(각각의 인터페이스를 구현한 객체)를 사용해야 함
class DelegatedC(a: A, b: B): A by a, B by b{
fun functionC(){
functionA()
functionB()
}
}
^ a, b를 각각 인터페이스 A, B에 위임해서 메서드 사용 시 . 없이도 사용할 수 있게 됨
//인터페이스를 구현한 클래스가 존재할 때, 다른 클래스에서 매개변수에 인터페이스를 위임해 와 사용 가능
interface Nameable{
var name: String
fun fly()
}
class StaffName : Nameable {
override var name: String = "Sean"
override fun fly(){
println("flying")
}
}
class Work: Runnable{ //스레드 실행을 위한 인터페이스
override fun run(){
println("work...")
}
}
//각 매개변수에 해당 인터페이스를 위임
class Person(name: Nameable, work: Runnable): Nameable by name, Runnable by work
fun main(){
val person = Person(StaffName(), Work()) //생성자를 사용해 객체 바로 전달
println(person.name) //여기서 StaffName 클래스의 name에 접근
person.run() //여기서 Work 클래스의 run 접근
person.fly()
}
//Sean
//work...
//flying
//커피메이커 예시
interface Heater{
fun on()
fun off()
fun isHot() : Boolean
}
class ElectricHeater(var heating: Boolean = false) : Heater {
override fun on() {
println("[ElectricHeater] heating...") //5
heating = true
}
override fun off() {
heating = false
println("ElectricHeater 클래스의 off 함수") //9
}
override fun isHot() : Boolean {
println("ElectricHeater 클래스의 isHot 함수") //6
return heating
}
}
interface Pump {
fun pump()
}
class Thermosiphon(heater: Heater) : Pump, Heater by heater { // 위임의 사용
override fun pump() {
if (isHot()) {
println("[Thermosiphon] pumping..."); //7
}
}
}
interface CoffeeModule {
fun getThermosiphon() : Thermosiphon
}
class MyDripCoffeeModule : CoffeeModule {
companion object {
val electricHeater: ElectricHeater by lazy { // lazy를 이용한 지연 초기화 기법 사용
println("MyDripCoffeeModule 클래스의 electricHeater 상수") //4
ElectricHeater()
}
}
private val _thermosiphon : Thermosiphon by lazy {
println("MyDripCoffeeModule 클래스의 private _thermosiphon 상수") //3
Thermosiphon(electricHeater)
}
override fun getThermosiphon() : Thermosiphon {
println("MyDripCoffeeModule 클래스의 getThermosiphon 함수") //2
return _thermosiphon
}
}
class CoffeeMaker(val coffeeModule: CoffeeModule) {
fun brew() {
val theSiphon: Thermosiphon = coffeeModule.getThermosiphon()
theSiphon.on()
theSiphon.pump()
println("Coffee, here! Enjoy!~") //8
theSiphon.off()
}
}
fun main() {
val coffeeMaker = CoffeeMaker(MyDripCoffeeModule()) //여기선 공간만들기인듯
println("순서확인") //1
coffeeMaker.brew()
}
순서확인
MyDripCoffeeModule 클래스의 getThermosiphon 함수
MyDripCoffeeModule 클래스의 private _thermosiphon 상수
MyDripCoffeeModule 클래스의 electricHeater 상수
[ElectricHeater] heating...
ElectricHeater 클래스의 isHot 함수
[Thermosiphon] pumping...
Coffee, here! Enjoy!~
ElectricHeater 클래스의 off 함수
2. 추상 클래스
: 선언 등의 대략적인 설계 명세, 공통의 기능을 구현한 클래스
- 하위 클래스에서 추상 클래스의 내용을 더 구체화해야 함
- abstract 키워드 사용
- 일반적인 객체를 생성하는 방법으로 인스턴스화할 수 없음
- 해당 추상 클래스를 상속하는 하위 클래스가 어떻게 만들어져야 하는지를 나타내는 용도로 사용함
- 클래스, 프로퍼티, 메서드 모두 abstract로 선언할 수 있음 (초기화 or 구현이 필요)
abstract class Printer{
abstract fun print() //추상 메서드
}
val myPrinter = object: Printer(){ //객체 인스턴스
override fun print(){ //추상 메서드 구현
println("printing!")
}
}
fun main(){
myPrinter.print()
}
'언어 > Kotlin' 카테고리의 다른 글
[Kotlin 문법 종합] - 예외처리 # 수정하기 (0) | 2024.03.06 |
---|---|
[Kotlin 문법 종합] - 접근제한자와 관련 용어 정리 (0) | 2024.03.06 |
[Kotlin 문법 종합] - 오버라이딩, 오버로딩 # 수정하기 (0) | 2024.03.05 |
[Kotlin 문법 종합] - 상속 (0) | 2024.03.05 |
[Kotlin 문법 종합] - 생성자, 객체 (#비교 추가하기) @@ 질문하기! (0) | 2024.03.05 |