본문 바로가기

프로젝트형 IoT 서비스 개발 4회차/3. 게이트웨이 디바이스 제어

[Day64] 2022-04-28(목) Kotlin 기본3 - Class - 김서연 강사님

728x90

[1] Kotlin 기본

  1. Class

    1) class 정의 및 객체 생성

createClassTest.kt

// createClassTest.kt
package com.example.kotlinwork.oop

fun main(args: Array<String>) {
    // 사용자정의 클래스를 사용하는 방법
    // 객체생성 = 클래스의 인스턴스화 작업
    // 정의된 클래스를 실제 프로그램 내부에서 사용하기 위해 메모리에 올려놓는 작업
    val obj1:MyClass = MyClass()
    val obj2 = MyClass()    // 객체를 참조하는 변수와 실제 생성되는 객체가 타입이 동일한 경우 참조변수의 타입을 생략할 수 있다.
    println("obj1:$obj1")
    println("obj2:$obj2")

    var obj3:Person = Person()
    obj3.name = "장동건"
    obj3.age = 22
    obj3.telNum = 111111111
    println("Person의 데이터:${obj3.name}, ${obj3.age}, ${obj3.telNum}")
    obj3.print()
}

class MyClass{

}

class Person{
    // DB의 레코드를 모델링한 클래스인 경우 멤버변수가 DB의 컬럼
    // DB의 데이터를 저장하고 가져오기 위해 setter/getter 메소드는 필수로 작성
    //멤버변수 정의
    var name = ""
    var telNum = 0
    var age = 0
    //멤버메소드 - Person 클래스가 갖고 있는 기능
    fun print(){
        println("print=>name:$name, age:$age, telNum:$telNum")
    }
}

    2) 생성자 정의 기본 방법

constructorTest.kt

// constructorTest.kt
package com.example.kotlinwork.oop

fun main(args: Array<String>) {
    var obj1:Customer = Customer()  // 매개변수가 없는 생성자를 호출하며 객체를 생성
    obj1.name = "이민호"   // Customer 클래스에 자동으로 생성되는 setter(setName) 메소드를 호출
    println("성명:${obj1.name}")  // Customer 클래스에 자동으로 생성되는 getter(getName) 메소드를 호출
    var obj2:Customer = Customer("장동건", 20)
    var obj3:Customer = Customer("장동건", 20, "010")
    obj1.print()
    obj2.print()
    obj3.print()
}

// 생성자 작성 방법
// 1. 기본 방법
/*
    - 생성자는 매개변수 갯수, 매개변수 타입을 다르게 추가해서 여러 개를 정의할 수 있다.
    - 클래스 내부에 생성자들 정의하지 않으며 매개변수가 없는 생성자가 제공된다.
    - 클래스를 정의하면 코틀린 내부에서 자바코드로 변환될 때 자동으로 setter, getter 메소드가 만들어진다.
*/
class Customer{
    var name = ""
    var age:Int = 0
    var telNum = ""

    init{
        // 객체가 생성될 때 실행해야 하는 기능 - 코틀린에서는 생성자에 멤버변수 초기화를 정의한다.
        println("객체가 생성될 때 처리해야 하는 일들을 정의")
    }

    constructor(){
        println("매개변수가 없는 생성자")
    }
    constructor(name:String, age:Int){  // 매개변수에 키워드가 없으면, val 키워드로 정의
        // 생성자 내부에서 멤버변수의 값을 초기화
        this.name = name
        this.age = age
        println("매개변수가 2개 생성자")
    }
    constructor(name:String, age:Int, telNum:String){
        this.name = name
        this.age = age
        this.telNum = telNum
        println("매개변수가 3개 생성자")
    }
    fun print(){
        println("name:$name, age:$age, telNum:$telNum")
    }
}

    3) 연습 예제1

MovieTest.kt

// MovieTest.kt
package com.example.kotlinwork.oop

fun main(args: Array<String>) {
    var obj1:Movie = Movie("어거스트 러쉬", "Drama")
    var obj2:Movie = Movie("나는 전설이다", "SF")
    obj1.print()
    println("-----------------------")
    obj2.print()
}

class Movie{
    var title:String = ""
    var genre:String = ""

    constructor(){
        println("기본 생성자")
    }
    constructor(title:String, genre:String){
        this.title = title
        this.genre = genre
    }

    fun print(){
        println("$title($genre) 상영중입니다.")
    }
}

    4) 연습 예제2

Student.kt

// Student.kt
package com.example.kotlinwork.oop

class Student{
    var name:String = ""
    var age:Int = 0
    var id:Int = 0

    constructor(name:String, age:Int, id:Int){
        this.name = name
        this.age = age
        this.id = id
    }

    fun print(){
        println("이   름 : $name    나 이 : $age    학    번 : $id")
    }
}

Teacher.kt

// Teacher.kt
package com.example.kotlinwork.oop

class Teacher{
    var name:String = ""
    var age:Int = 0
    var subject:String = ""

    constructor(name:String, age:Int, subject:String){
        this.name = name
        this.age = age
        this.subject = subject
    }

    fun print(){
        println("이   름 : $name    나 이 : $age    담당과목 : $subject")
    }
}

Staff.kt

// Staff.kt
package com.example.kotlinwork.oop

class Staff{
    var name:String = ""
    var age:Int = 0
    var dept:String =""

    constructor(name:String, age:Int, dept:String){
        this.name = name
        this.age = age
        this.dept = dept
    }

    fun print(){
        println("이   름 : $name    나 이 : $age    부    서 : $dept")
    }
}

SchoolTest.kt

// SchoolTest.kt
package com.example.kotlinwork.ooptest
import com.example.kotlinwork.oop.Student
import com.example.kotlinwork.oop.Teacher
import com.example.kotlinwork.oop.Staff

fun main(args: Array<String>) {
    val obj1:Student = Student("홍길동", 20, 200201)
    val obj2:Teacher = Teacher("이순신", 30, "JAVA")
    val obj3:Staff = Staff("유관순", 40, "교무과")
    obj1.print()
    obj2.print()
    obj3.print()
}

    5) 기본생성자(Primary constructor)

// defaultConstructor.kt
package com.example.kotlinwork.oop

fun main(args: Array<String>) {
    val obj1 = Emp3("이민호", 25, 1000)
    println("=====================================")
    val obj2 = Emp3("BTS")
}
// 2. 코틀린은 주 생성자(기본생성자)를 정의하고 사용할 수 있다.
// class 클래스명 construct(......) { }
//               ------------------
//                      └ 기본생성자
class Emp2 constructor(name:String, age:Int, telNum:Int){

}

// 클래스를 선언하면서 기본생성자를 바로 정의하는 경우 constructor 키워드를 생략할 수 있다.
// 기본생성자에 정의하는 매개변수는 자동으로 멤버변수로 등록된다.
// 기본생성자를 정의하면 매개변수 없는 생성자는 제공되지 않는다.
class Emp3(var name:String, var age:Int, var telNum:Int){
    init{
        println("init 코드 실행")
        println("name:$name")
        println("age:$age")
        println("telNum:$telNum")
    }
    // 기본생성자 이외에 추가하는 생성자를 보조생성자라고 한다.
    // Emp3 클래스에는 생성자가 2개
    // 보조생성자에서 기본생성자를 호출할 수 있다.
    // constructor(.....):this(.....)
    constructor(name:String):this(name, 40, 11){
        println("보조생성자호출")
    }
    // 기본생성자를 정의하는 경우 보조생성자를 정의할 때 반드시 기본생성자를 호출해서 값을 세팅해야 한다.
    constructor(name:String, age:Int):this(name, age, 2000){
        // this.name = name
        // this.age = age
    }
}


// 1. 생성자 정의 - 기본
class Emp{
    var name =""
    var telNum = 0
    var age = 0
    constructor(){

    }

    constructor(name: String, telNum: Int, age: Int) {
        this.name = name
        this.telNum = telNum
        this.age = age
    }
}

    6) 상속

      - 상속 기본 사용법

inheritanceTest.kt

// inheritanceTest.kt
package com.example.kotlinwork.oop

fun main(args: Array<String>) {
    val obj = SubA()
    println("================================")
    println("부모클래스의 멤버:${obj.superVal}")
    obj.superDisplay()
    println("================================")
    println("자식클래스의 멤버:${obj.subVal}")
    obj.subDisplay()
}

// 코틀린에서 만드는 클래스는 final클래스이므로 상속을 하기 위해서는 final을 해제
// open 키워드를 클래스 선언부에 추가
open class SuperA{
    var superVal = 100
    constructor(){
        println("부모클래스의 생성자")
    }
    open fun superDisplay(){
        println("super클래스의 display()")
    }
}

class SubA:SuperA{  // SubA가 Super클래스를 상속한다.
    var subVal = 1000
    constructor():super(){  // SubA의 매개변수 없는 생성자를 호출하기 전에 부모클래스의 생성자를 호출
        println("자식클래스의 생성자")
    }
    fun subDisplay(){
        println("sub클래스의 display()")
    }

    // 메소드 오버라이딩
    // 1. override 키워드를 메소드 선언부에 추가
    // 2. 오버라이드 하려는 부모클래스의 메소드 선언부에 open을 추가한다.
    // 3. 부모클래스의 메소드를 재정의 하면 부모클래스의 메소드가 호출되지 않고 재정의된 메소드가 호출된다.
    override fun superDisplay(){
        println("super클래스의 display() 오버라이딩")
    }
}

 

      - 매개변수 있는 상속

inheritanceTest2.kt

// inheritanceTest2.kt
package com.example.kotlinwork.oop

fun main(args: Array<String>) {
    var obj = Sub("장동건", 50)
    println("name:${obj.name}")
    println("name:${obj.age}")
}

open class Super(var name:String){
    init{
        println("test super")
    }
}

class Sub:Super{
    var age:Int = 0
    constructor(name:String, age:Int):super(name){
        this.age = age
        println("sub 생성자")
    }
    init{
        println("test sub")
    }
    fun display(){
        println("name:$name")
    }
}

 

      - 4) 에서 한 예제를 상속을 이용하여 공통 부분을 부모 클래스로 만들기 및 다형성의 이해

Employee.kt

// Employee.kt
package com.example.kotlinwork.oop2

abstract class Employee {
    var name:String = ""
    var age:Int = 0
    constructor(){

    }
    constructor(name:String, age:Int){
        this.name = name
        this.age = age
    }

    open fun print(){
        print("이   름 : $name    나 이 : $age")
    }

    // 메소드의 내용이 없는 메소드 -> 추상메소드로 정의
    // 추상메소드를 정의하는 경우 메소드 선언부에 abstract
    // 추상메소드를 갖고 있는 클래스는 추상클래스가 되므로 클래스 선언부에도 abstract를 추가
    abstract fun test()
}

Student.kt

// Student.kt
package com.example.kotlinwork.oop2

class Student:Employee{
    var id:Int = 0

    constructor(name:String, age:Int, id:Int):super(name, age){
        this.id = id
    }

    override fun print(){
        super.print()
        println("    학    번 : $id")
    }
}

Teacher.kt

// Teacher.kt
package com.example.kotlinwork.oop2

class Teacher:Employee{
    var subject:String = ""

    constructor(name:String, age:Int, subject:String):super(name, age){
        this.subject = subject
    }

    override fun print(){
        super.print()
        println("    담당과목 : $subject")
    }
}

Staff.kt

// Staff.kt
package com.example.kotlinwork.oop2

class Staff:Employee{
    var dept:String =""

    constructor(name:String, age:Int, dept:String):super(name, age){
        this.dept = dept
    }

    override fun print(){
        super.print()
        println("    부    서 : $dept")
    }
}

Freelancer.kt

// Freelancer.kt
package com.example.kotlinwork.oop2

class Freelancer:Employee{
    var grade:Int = 0
    constructor():super(){

    }
    constructor(name:String, age:Int, grade:Int):super(name, age){
        this.grade = grade
    }

    override fun print(){
        super.print()
        println("    등    급 : $grade")
    }

    override fun test(){
        println("Freelancer클래스의 메소드")
    }
}

UseEmp.kt

// UseEmp.kt
package com.example.kotlinwork.oop2

import java.util.*

fun main(){
    println("""
        |1. Teacher
        |2. Staff
        |3. Student
        |4. Freelancer
    """.trimIndent())
    var sc:Scanner = Scanner(System.`in`)
    print("작업선택:")
    var data:Int = sc.nextInt()
    // 상속 관계에서 부모 타입의 변수로 자식 객체를 참조할 수 있다.
    // 타입이 부모클래스 타입이면 부모가 갖고 있는 메소드, 속성만 접근할 수 있다.
    var obj:Employee? = null
    when(data){
        1 -> obj = Teacher()
        2 -> obj = Staff()
        3 -> obj = Student()
        4 -> obj = Freelancer()
    }
    run(obj!!)
}

fun run(obj: Employee){
        obj.test()
}

    7) 상속과 다형성 연습 예제1

[Content 클래스]
변수
title(String), price(Int)

생성자
1)기본생성자
2) title 을 매개변수로 받는 생성자

메소드
totalPrice()라는 abstract 메소드
show()
=>“title 비디오의 가격은 price 원 입니다.”라고 출력하는 메소드
예) 이끼비디오의 가격은 2000 원 입니다.


[Video 클래스] - Content클래스를 상속받습니다.
변수
genre(String)

생성자
title 과 genre 를 매개변수로 받는 생성자

메소드
- totalPrice()구현
genre 의 값에 따라 다음과 같이 price 변수에 가격을 셋팅하세요.
“new”인 경우 : 2000
“comic”인 경우 : 1500 “child”인 경우 : 1000 나머지 : 500
힌트 : 문자열의 내용이 같은지를 비교하려면 String 클래스의 equals() 메소드를 사용할 수 있습니다.
예) “kotlin”.equals(“kotlin”) : true 리턴
“kotlin”.equals(“jsp”) : false 리턴


[출력값]
변호인 비디오의 가격은 2000 원 입니다.
탐정 비디오의 가격은 1500 원 입니다.
헬로카봇 비디오의 가격은 1000 원 입니다.

[출처] 상속과 다형성의 연습|작성자 heaves1 - https://blog.naver.com/heaves1/222714521608

Content.kt

// Content.kt
package com.example.kotlinwork.oop2

abstract class Content(var title: String) {
    var price:Int = 0

    abstract fun totalPrice()
    fun show(){
        println("$title 비디오의 가격은 $price 원 입니다.")
    }
}

Video.kt

// Video.kt
package com.example.kotlinwork.oop2

fun main(args: Array<String>) {
    var obj1 = Video("변호인","new")
    var obj2 = Video("탐정","comic")
    var obj3 = Video("헬로카봇","child")
    var obj4 = Video("인터스텔라","SF")
    obj1.totalPrice()
    obj2.totalPrice()
    obj3.totalPrice()
    obj4.totalPrice()
    obj1.show()
    obj2.show()
    obj3.show()
    obj4.show()
}

class Video(title: String, var genre: String) : Content(title) {
    override fun totalPrice() {
        price = when(genre){
            "new" -> 2000
            "comic" -> 1500
            "child" -> 1000
            else -> 500
        }
    }
}

    8) 상속과 다형성 연습 예제2

출처 -&nbsp;https://blog.naver.com/heaves1/222714706034

- -,#,+등의 기호는 처리하지 않으셔도 됩니다.

[Shape]
변수
area(Double) - 면적이 저장될 변수
name(String) - Shape 의 이름

메소드
- calculationArea : 면적 계산하는 기능을 수행하는 abstract메소드
면적을 계산해서 area에 저장하기
- print메소드 : 결과와 같이 출력


[Circle]
Shape클래스 상속
변수
radius(Double) - 반지름
메소드
- calculationArea : 오버라이딩해서 면적 구하기

[Rectangular]
Shape클래스 상속
변수
width(Double) - 가로
height(Double) - 세로
메소드
- calculationArea : 오버라이딩해서 면적 구하기

[출처] 클래스 작성 연습 - 상속,다형성|작성자 heaves1 - https://blog.naver.com/heaves1/222714706034

출처 -&nbsp;https://blog.naver.com/heaves1/222714706034

Shape.kt

// Shape.kt
package com.example.kotlinwork.oop2

abstract class Shape {
    var area:Double = 0.0
    var name:String = ""

    constructor(){

    }
    constructor(name:String){
        this.name = name
    }

    abstract fun calculationArea()
    fun print(){
        println("${name}의 면적은 $area")
    }
}

Circle.kt

// Circle.kt
package com.example.kotlinwork.oop2

import kotlin.math.PI

class Circle(var radius:Double):Shape("원") {
    override fun calculationArea() {
        area = PI * radius * radius
    }
}

Rectangular.kt

// Rectangular.kt
package com.example.kotlinwork.oop2

class Rectangular(var width:Double, var height:Double):Shape("직사각형") {
    override fun calculationArea() {
        area = width * height
    }
}

shapeTest.kt

// shapeTest.kt
package com.example.kotlinwork.oop2

fun main(args: Array<String>) {
    val circle = Circle(10.0)
    val rectangular = Rectangular(10.0, 20.0)
    circle.calculationArea()
    rectangular.calculationArea()
    circle.print()
    rectangular.print()
}

 

- 끝 -

728x90