1. interface
인터페이스 : 클래스에 준비되어야할 프로퍼티나 메소드를 정의해둔것
클래스와 다르게 메소드에는 구체적인 기능을 쓰는게 아니다!
메소드는 이름만 갖고있다. (이 이름으로 통일할꺼야! )
(자바에서는 implement로 구현된다. kotlin에서는 : 으로 가져온다. 상속과 똑같음)
인터페이스는 다중구현이 가능하다. (클래스는 다중상속이 불가능하다.)
인터페이스를 받은 클래스는, 인터페이스에 준비되어있는 프로퍼티나 메소드를 오버라이드해서 사용해야한다.
fun main() {
val me = Person("고양이", "cat@cat.cat")
val you = Student("갈색푸들")
val he = Person("코코")
val she = Student("테나아",30)
val data : Array<Human> = arrayOf<Human>(me,you,he,she)
for (ob in data)
ob.say()
}
interface Human {
val name : String
fun say() //이름만 있고 기능은 없는 추상메소드
}
class Person : Human{
override var name : String
var mail : String
constructor (name : String = "이름없음", mail : String = "메일없음"){
this.name = name
this.mail = mail
}
override fun say(){
println("name : $name , mail : $mail ")
}
}
class Student : Human{
override var name : String
var grade : Int
constructor (name : String = "이름없음", grade : Int = 1){
this.name = name
this.grade = grade
}
override fun say(){
println("name : $name , grade : $grade ")
}
}
//output
name : 고양이 , mail : cat@cat.cat
name : 갈색푸들 , grade : 1
name : 코코 , mail : 메일없음
name : 테나아 , grade : 30
Student / Person class 둘 다 Human을 implement하고 있다.
전혀 다른 class이지만 인터페이스를 이용하여서, 배열로 묶고 출력하였다.
val data : Array<Human> = arrayOf<Human>(me,you,he,she)
for (ob in data)
ob.say()
Array<Human> 을 보면, 인터페이스인 Human이 class처럼 들어가있다. 인터페이스는 class처럼 기능한다!
Array<Human>은 Human 인터페이스를 끼워넣은것을 보관하는 배열을 만들수있게되었다.
=> 즉! Human을 끼워넣은 class라면 전부 보관가능하다는 얘기임. (class Person : Human / class Student : Human)
인터페이스를 쓰면 상속받지 않은 클래스를 한번에 묶어서 다룰수있다.
2. SAM interface (Single Abstract Method)
SAM 인터페이스는 오직 한개의 메소드만 준비해둔다.
자바나 코틀린에서는 SAM 인터페이스를 자주보게된다.
통상 인터페이스를 탑재한 class를 정의하고, 그 객체를 사용하는게 많다.
그리고 메소드가 1개뿐이라서 인터페이스를 이용하기 위해 쓰는 코드가 인터페이스 본체보다 더 긴 경우도 있다.
(1) 파라미터가 1개일때
fun main() {
val a = Human { println("Hello $it !")}
a.say("cat")
val b = Human { println("안녕하세요 $it !")}
b.say("고양이")
}
fun interface Human{
fun say(name : String)
}
//output
Hello cat !
안녕하세요 고양이 !
Human 인터페이스를 어떤식으로 탑재하는가..? { } 를 이용한다.
val a = Human { println("Hello $it !")}
val b = Human { println("안녕하세요 $it !")}
Human 뒤의 { } 람다식이다. (함수라는것임~)
즉, { } 안에 들어가는 함수가 그모습 그대로 Human 인터페이스의 say( ) 메소드로써 탑재된 class가 on demand로 생성되고,
그 객체가 반환되어 변수에 대입되는것임.
(그 인터페이스를 탑재한 클래스의 객체를 만들어서 작업하게 되는 형식임)
파라미터가 하나라면 it으로 통일된다.
※SAM 인터페이스에서는 파라미터 디폴트값을 설정불가
(2) 파라미터가 복수일때
fun main() {
val a = Human {
name: String, age : Int ->
println("Hello $name , $age !")}
a.say("cat",1)
val b = Human {
name: String, age : Int ->
println("안녕하세요 $name , $age !")}
b.say("고양이",5)
}
fun interface Human{
fun say(name : String, age : Int)
}
//output
Hello cat , 1 !
안녕하세요 고양이 , 5 !
3.추상클래스
추상클래스는 추상메소드를 갖고있는 클래스이다.
(=> 인터페이스는 메소드 탑재를 강제한다. 이것과 비슷한게 추상클래스이다. )
추상클래스를 상속 받으면, 그 안에 있는 추상메소드를 반드시 오버라이드해야한다.
클래스를 만드는 이유는? 객체를 만들고 그 클래스안에 적혀있는 기능을 쓰려고
기본클래스 new해서(자바에서는.. 코틀린은 아님) 객체를 만듬
추상클래스 : 객체를 new 해서(자바에서는.. 코틀린은 아님) 만드는 목적이 없음.
※추상메소드 : 강제화된 이름을 정할때 쓰는것. 모두 다 say()라고 이름을 강제화 시킴 ! 이름 규격화
제품의 규격을 만드는중~
fun main() {
val h = Person("안녕")
h.say()
val a = Student("학생")
a.say()
}
abstract class Human(name : String){
var name = name
abstract fun say()
}
class Person(name:String) : Human(name){
override fun say(){
println("Hello $name")
}
}
class Student(name : String) : Human(name){
override fun say(){
println("안녕 $name")
}
}
//output
Hello 안녕
안녕 학생
Person과 Student는 Humam 추상메소드를 상속받았다. (추상클래스도 일반클래스랑 똑같은 방법으로 상속받는다.)
추상클래스에는 추상메소드 말고 다른게 써져있는 경우도 있다. 이거는 오버라이드 할 필요는 없다.
4. 데이터 클래스
data class save(var name : String, var age : Int)
주생성자로써 사용되고, 동시에 그대로 프로퍼티로써 객체안에 값으로도 보관 가능하다.
fun main() {
val h = Attr("안","@com")
say(h)
}
data class Attr(val name : String, val mail : String, val age : Int = 0)
fun say(attr : Attr){
println("""
name : ${attr.name},
${attr.mail},
${attr.age} """)
}
// output
name : 안,
@com,
0
5. Object 클래스
클래스에는 객체를 만들지않고 , 클래스에서 직접 메소드를 부를 수 있다. kotlin에서는 이것을 object라는 것으로 부른다.
오브젝트는 객체를 만들지 않고, 클래스에서 직접 프로퍼티나 메소드를 불러낸다.
fun main() {
Human.set("고양이",10)
Human.say()
}
object Human {
var name : String = ""
var age : Int = 0
fun set(name : String, age : Int){
this.name = name
this.age = age
}
fun say(){
println("$name $age 살")
}
}
//output
고양이 10 살
set함수는 이미 존재하는 name, age에 다른 값을 셋팅할 수 있는 함수이다.
name과 age를 받고나면 순서대로 say( ) 를 출력할때 적용되고, main함수에서는 최종값을 불러오게 된다.
※val human = Human( ) 이라 쓰면 에러가 난다.
6. 싱글톤과 동반객체(Companion object)
클래스 중에서는 , 얼마나 객체를 만들어도 그 값이 항상 일정하게 얻어지는것이 있다. 이걸 싱글톤이라고 부른다.
=> 객체를 1개만 만드는 것이다! 특정 클래스의 객체가 오직 하나만 생성된다.
동반객체는 클래스 내부에서 정의되는 객체이다. 싱글톤과 같은 효과를 갖고있음
fun main() {
Human.set("켄수",23)
var x = Human()
x.say()
var y = Human()
y.say()
}
class Human {
fun say(){
println("안녕 나는 ${Human.name} 이고 ${Human.age}살이야")
}
companion object{
var name = ""
var age = 0
fun set(name : String, age : Int){
this.name = name
this.age = age
}
}
}
//output
안녕 나는 켄수 이고 23살이야
안녕 나는 켄수 이고 23살이야
Human.name과 Human.age는 객체로 만들어진게 아니라 class안에 있는거다
fun say(){
println("안녕 나는 ${Human.name} 이고 ${Human.age}살이야")
}
7. 열거형 클래스 (enum class)
몇 개 열거된 것중에 하나를 고른다.
fun main() {
val t = Human.banana
val s = Human.valueOf("apple")
println(t)
println(s)
}
enum class Human {banana, orange, apple}
//output
banana
apple
valueOf는 파라미터에 지정된 텍스트를 기준으로 값을 설정한다.
fun main() {
val t = Human.a
val h = Human.a2
val s = Human.valueOf("a3")
println(t)
println(h.label+h.age)
s.show()
}
enum class Human (val label : String, val age : Int){
a("1번",0),
a2("2번",1),
a3("3번",2);
fun show(){
println("<<${this} ${this.name} ${this.age}>>")
}
}
//output
a
2번1
<<a3 a3 2>>
'Kotlin' 카테고리의 다른 글
Kotlin13. class의 다른 확장 - Pair, 확장메소드/프로퍼티.. (0) | 2023.08.13 |
---|---|
Kotlin12. class의 다른 확장 - Delegation, observable... (0) | 2023.08.13 |
Kotlin10. class와 OOP (0) | 2023.08.06 |
Kotlin9. 재귀함수, 꼬리재귀 (0) | 2023.08.01 |
Kotlin8. 람다식 , 고차함수 (0) | 2023.08.01 |