TIL, WIL(일기)

230810 2탄.객체지향프로그램(OOP)

도슬 2023. 8. 10. 15:00

▶1탄에 이어서 하나 정리하고 가자.▶

interface sportscar{}
interface a{}
interface b{}
interface c{}
abstract class Car(){}
open class Bus() {}

class ExpressBus: Bus(),Car() {}
class WideBus: Bus(),sportscar{}
class CityBus: Car(),sportscar{}
class VillageBus: Bus(),a,b,c{}

- 자식클래스에서 부모클래스를 상속 받기위해 주로 3가지 방법(인터페이스(interface),추상화 클래스(abstract class),open 클래스) 이 있다.

- 자식클래스에서 추상화 클래스(abstract class),open 클래스 부모2명을 상속받는것은 때려죽여도 불가능하다. 둘중에 하나만 상속 가능하다. 즉, 다중상속이 불가능하다.

- 인터페이스는 위에서 보다시피 다중상속이 가능하다. 

 

3. 인터페이스(추상화클래스와 비슷하지만 다르다.)

fun main(){
    val expressBus = ExpressBus()
    expressBus.oil()
    expressBus.a()
    expressBus.b()
    Sportscar.a()
    Sportscar.b()
    Sportscar.oil()
}
interface Sportscar{
    var z:String
    abstract fun oil()
    fun a(){
        println("안녕")
    }
    open fun b(){}
}
abstract class Bus() {
    val x :String = ""
    fun engineStart() {
        println("부릉부릉")
    }
    open fun departure() {
        println("출발합니다.")
    }
    open fun aircon(){
        println("에어컨이 틀어져있습니다.")
        println("창문을 닫아주세요.")
    }

}

class ExpressBus:Bus(),Sportscar{
    override var z: String = ""

    override fun departure() {
        super.departure()
    }
    override fun oil() {
        println("기름 넣자")
    }
}

▼추상화 클래스와 비슷한점 ▼

ㄱ. 얘는 인스턴스 생성이 불가능한면에서 추상클래스와 똑같다. 위 코드처럼 인터페이스(sportscar)를 상속받은 ExpressBus를 main함수에서 인스턴스화시킨 변수 expressBus를 가지고 expressBus.oil(), expressBus.a(), expressBus.b() 처럼 써야한다.

ㄴ. 추상화 클래스와 동일하게 Sportscar.a(), Sportscar.b(), Sportscar.oil() 이렇게 못쓴다. 인스턴스를 생성할 수 없다.

ㄷ. 추상화메소드(abstract)의 추상메소드(abstract)를 상속받은 자식클래스에서 무조건 써줘야되는것처럼

인터페이스에 선언된 추상메소드(abstract)는 무조건 상속받은 자식 클래스에서 써줘야한다. abstract가 달린 메소드라면 예외는 없다.

ㄹ. 인터페이스(Sportscar)에 보면 추상메소드를 제외한 a메소드와 open메소드b 가있는데 얘들은 abstract가 안달려있다면 상속받은 ExpressBus에서 필요없으면 사용안해도된다. 이 역시 추상클래스의 특성과 동일하다.

 

▼추상화 클래스와 다른점▼

ㅁ. 위 코드를 보면 인터페이스Sportscar에서 z라는 변수가 선언되어있다. 하지만 초기화 시키지는 못했다. 왜냐하면 인터페이스에서는 변수를 선언만 할 수 있지 초기화는 못한다.

ㅂ. 그래서 상속받은 자식클래스(ExpressBus)에서 초기화를 시켜줘야한다. 인터페이스에서 선언된 초기화되지않은 변수는 자식클래스에서 위코드에서 z변수를 오버로드하고 초기화시킨거처럼 무조건 써주고 초기화 해야된다. 안쓰면 에러난다.

ㅅ. 정리하면 abstract메소드, 인터페이스에서 선언된 초기화되지않은 변수는 동일한방식으로 자식클래스에서 무조건 override해줘야한다.(변수는 초기화까지)

ㅇ. 반면 추상화클래스 Bus에서는 x라는 변수가 선언되고 초기화 되어있다. 하지만 인터페이스와달리 자식클래스에서 무조건 override해줘야되는건 아니다. 필요하면 쓰고 필요없으면 안써도된다.

 

 

4. 예제  : 무조건써야되는 변수나 메소드가 없이 필요한것만 써도되는 open클래스로 다루어봄

fun main() {
    val seoulToChunanBus = WideBus("35가 3683","M6000", "서울","천안")
    seoulToChunanBus.routeNumber = "M9000"
    seoulToChunanBus.engineStrart()
    seoulToChunanBus.departure()
}

open class Bus(val licencePlate: String, val departure: String, val arrive: String) {
    fun engineStrart() {
        println("부릉부릉")
        println("$licencePlate 차량이 엔진을 켰습니다.")
    }
    open fun departure() {
        println("출발합니다.")
        println("$departure 에서 $arrive 로 출발합니다.")
    }
}
class WideBus(licencePlate: String, val routeNumber: String, departure: String, arrive: String) :
    Bus(licencePlate, departure, arrive) {
    override fun departure() {
        super.departure()
    }
}

ㄱ. val seoulToChunanBus변수에 WideBus()클래스를 인스턴스화 시켰고 초기화 시킬 값으로 각각 ("35가 3683", "M6000","서울","천안") 을 넣어줬다. 

ㄴ. 이를 위해서 WidBus클래스에는 당연히 초기화 시킬값을 넣어줄 변수들이 있어야한다. 각각 licencePlate, val routeNumber, departure, arrive)에 각각 main함수에서 넣어준다.

ㄷ. 유심히 보자. 자식클래스인 WideBus의 파라미터는 4개,  부모클래스인 Bus클래스로 넘겨주는 파라미터는 3개다.

또한 WideBus만의 특정한 속성이다. 

ㄹ. 자식클래스(WideBus)로써 부모클래스(Bus)의 메소드와 변수를 사용하면서 부모클래스(Bus)에는 없는 변수이지만 자식클래스(WideBus)만의 특정한 속성 val routeNumber역시 상속과 관련된 개념이다. (난 이게 다형성이라고 착각했었다.)

ㅁ. 여기서 말하고 싶은점은 자식클래스(WideBus)만의 특정한 변수를 val로 선언했다는 점이다.

ㅂ. 위 코드에서 다시 맨위쪽에 seoulToChunanBus.routeNumber = "M9000" 이라는 코드를 보자. 이 코드는 WideBus클래스의 routeNumber을 처음 초기화시킬때 M6000으로 초기화시켰는데 M9000으로 다시 초기화 시킨다는 말인데

ㅅ. 다시 내려와서 WideBus에서 해당 변수는 val로 선언되어있다.  이 말은 곧 routeNumber은 상수로써 변할 수 없는 값이기때문에 M6000으로 초기화된값을  M9000으로 다시 초기화 할 수 없다는 말이다. 

ㅇ. WideBus클래스의 routeNumber값을 변경하려면 val을 var로 바꿔줘야한다. 그러면 변경할 수 있다.

ㅈ. 또한 같은 개념으로 부모클래스에서 licence, departure,arrive 변수들을 처음 선언할때 val로 선언했기때문에 역시

위 코드의 두번째줄에서 WideBus에 넣어준 초기값 ("35가3683", "서울","천안" )값 또한 변경(다시 초기화)할 수 없다.

변경하려면 Bus클래스에서 선언해준 val변수들을 var로 변경해줘야 가능하다.

 

 

▶3탄에서는 다형성에 대해서 공부해보자.▶