본문 바로가기
IT

[ 코틀린 ] 상속 클래스 추상 클래스

by hak0205 2023. 2. 6.
반응형

코틀린 상속 클래스(Inheritance Class)와 추상 클래스(Abstract Class)에 대한 설명입니다.

상속 클래스는 부모클래스가 자식클래스에게 무언가를 물려주는 것입니다.

추상 클래스는 대략적인 설계의 명세와 공통의 기능을 구현한 클래스입니다.

 

 

상속 클래스

Kotlin은 상속을 지원하므로 기존 클래스(슈퍼클래스)의 하위 클래스인 새 클래스를 만들 수 있습니다. 하위 클래스는 상위 클래스의 속성과 메서드를 상속하며 새 속성과 메서드를 추가하거나 상위 클래스에서 상속된 항목을 재정의할 수도 있습니다. 상속 클래스(Inheritance Class)에는 몇 가지 주요 기능이 있습니다.

 

상속클래스의 장점입니다.

  1. 코드 재사용성: 상속을 통해 하위 클래스는 상위 클래스에서 속성과 메서드를 상속받을 수 있습니다. 이를 통해 코드를 재사용하고 여러 클래스에서 코드 중복을 방지할 수 있습니다. 예를 들어 유사한 기능을 필요로 하는 여러 클래스가 있는 경우 공유 기능이 있는 슈퍼클래스를 생성하고 다른 클래스가 이 클래스에서 상속하도록 할 수 있습니다.
  2. 다형성: 다형성은 서로 다른 유형의 개체를 동일한 유형인 것처럼 처리할 수 있도록 하는 개체 지향 프로그래밍의 핵심 기능입니다. Kotlin에서 다형성은 상속을 통해 이루어집니다. 하위 클래스는 상위 클래스의 메서드를 재정의하고 자체 구현을 제공할 수 있습니다. 이를 통해 클래스 설계에 더 큰 유연성을 제공하고 다양한 개체와 함께 작동하는 코드를 더 쉽게 작성할 수 있습니다.
  3. 코드 구성: 상속은 클래스를 다음과 같이 구성하는 방법을 제공합니다. 계층 구조. 이를 통해 클래스 간의 관계와 클래스 간의 관계를 더 쉽게 이해할 수 있습니다.
  4. 확장성: 상속을 사용하면 클래스를 수정하지 않고도 기존 클래스의 기능을 확장할 수 있습니다. 원래 수업. 이는 타사 라이브러리로 작업하거나 클래스의 소스 코드에 액세스 할 수 없을 때 유용할 수 있습니다. 기존 클래스의 하위 클래스를 만들고 필요한 추가 기능을 추가할 수 있습니다.

 

다음은 Kotlin에서 상속을 사용할 때의 몇 가지 단점입니다.

  1. 복잡성 : 상속은 복잡한 클래스 계층으로 이어질 수 있으므로 코드를 이해하고 유지 관리하기가 더 어려워집니다.
  2. 긴밀한 결합 : 상속은 클래스 간의 긴밀한 결합으로 이어져 향후 코드를 변경하거나 리팩터링 하기 어렵게 만듭니다.
  3. 깨지기 쉬운 기본 클래스 문제 : 상위 클래스를 변경하면 하위 클래스에 의도하지 않은 결과가 발생하여 버그 및 유지 관리 문제가 발생할 수 있습니다.
  4. 성능 오버헤드 : 상속은 특히 다음을 사용할 때 성능 오버헤드를 추가할 수 있습니다. 재정의된 메서드에 대한 가상 메서드 디스패치.
  5. 유연하지 않은 디자인 : 상속은 쉽게 수정하거나 확장할 수 없는 경직된 디자인으로 이어질 수 있습니다.

다음은 코틀린 상속 클래스(Inheritance Class)의 예제입니다. 예제를 보시면 이해도가 높아질 것입니다.

// Superclass
open class Vehicle {
   // Properties and methods
}

// Subclass
class Car: Vehicle() {
   // Properties and methods specific to Car
}

// Subclass
class Bike: Vehicle() {
   // Properties and methods specific to Bike
}

이 예에서 Car 및 Bike Class는 : 기호를 사용하여 Vehicle 슈퍼클래스에서 상속됩니다. Vehicle class 선언 전의 open 키워드는 해당 클래스가 열린 클래스임을 나타내며, 이는 해당 클래스가 상속될 수 있음을 의미합니다.

 

기본적으로 코틀린의 클래스는 최종 클래스이므로 상속할 수 없습니다. Car 그리고 Bike 클래스는 Vehicle 클래스의 모든 속성과 메서드를 상속하며, 필요한 경우 이를 직접 사용하거나 재정의할 수 있습니다.

 

예를 들어, Vehicle 클래스에 startEngine() 메서드가 있는 경우 Car 및 Bike 클래스가 이 메서드를 직접 사용할 수 있습니다. 그러나 자동차 클래스가 startEngine() 메서드의 다른 구현을 필요로 하는 경우 다음과 같이 재정의할 수 있습니다.

 

class Car: Vehicle() {
   override fun startEngine() {
      // Code to start the engine for a car
   }
}

요약하면, Kotlin에서의 상속은 기존 클래스를 기반으로 하는 새로운 클래스를 만들 수 있게 해 주며, 코드를 재사용하고 계층 구조로 클래스를 구성할 수 있는 방법을 제공합니다.


추상클래스

추상 클래스(Abstract Class)는 자체적으로 인스턴스화할 수 없으며 하위 클래스로 지정되는 클래스입니다. 여러 하위 클래스에서 공유할 수 있는 기본 구현을 제공합니다. 추상 클래스는 추상적 방법과 구체적인 방법을 모두 가질 수 있습니다.

 

추상 메서드는 abstract 키워드로 표시되며 본문이 없습니다. 구체적인 메서드에는 본문이 있으며 하위 클래스에서 호출할 수 있습니다.

 

다음은 Kotlin의 추상 클래스 장점입니다.

  1. 코드 재사용성 : 추상 클래스는 여러 하위 클래스에서 상속할 수 있는 공통 기능 집합을 정의하는 방법을 제공합니다. 이렇게 하면 코드를 한 번 작성하고 여러 클래스에서 사용할 수 있으므로 코드 재사용성이 향상되고 중복이 줄어듭니다.
  2. 캡슐화 : 추상 클래스는 일련의 관련 메서드 및 속성을 캡슐화할 수 있습니다. 코드를 보다 체계적이고 이해하기 쉽게 만들 수 있습니다. 이것은 또한 중요한 데이터와 함수의 우발적인 수정을 방지하는 데 도움이 될 수 있습니다.
  3. 다형성: 추상 클래스는 하위 클래스에 의해 확장되도록 설계되어 추상 메서드의 자체 구현을 제공할 수 있습니다. 이것은 다형성을 허용하는데, 여기서 다른 클래스의 객체들은 마치 동일한 유형인 것처럼 취급될 수 있기 때문에 다양한 다른 객체들과 함께 작동하는 코드를 더 쉽게 작성할 수 있습니다.
  4. 유연성 : 추상 클래스는 코드 디자인에서 일정 수준의 유연성을 제공할 수 있으므로 해당 기능을 구현하는 방법을 지정하지 않고도 공통 기능 세트를 정의할 수 있습니다. 이는 공통 기능을 공유하지만 구현이 다른 여러 클래스를 만들어야 할 때 유용할 수 있습니다.
  5. 유형 안전성: 추상 클래스는 유형 안전성 수준을 제공하여 런타임이 아닌 컴파일 타임에 오류가 발생합니다. 추상 클래스는 모든 하위 클래스에서 모든 추상 메서드를 구현해야 하므로 실수로 메서드 구현을 놓치고 런타임 오류가 발생할 가능성이 줄어듭니다.

장점이 있다면 단점이 존재합니다. 추상 클래스의 단점입니다.

  1. 복잡성 : 추상 클래스는 복잡한 클래스 계층 구조로 이어질 수 있으므로 코드를 이해하고 유지하기가 더 어려워집니다.
  2. 긴밀한 결합: 추상 클래스는 클래스 간의 긴밀한 결합으로 이어져 향후 코드를 변경하거나 리팩터링 하기 어렵게 만듭니다.
  3. 취약한 기본 클래스 문제 : 추상 클래스를 변경하면 하위 클래스에 의도하지 않은 결과가 발생하여 버그 및 유지 관리 문제가 발생할 수 있습니다.
  4. 오버헤드 : 추상 클래스가 성능을 추가할 수 있습니다. 특히 구체적인 메서드에 대해 가상 메서드 디스패치를 ​​사용할 때 오버헤드가 발생합니다.
  5. 유연하지 않은 디자인 : 추상 클래스는 쉽게 수정하거나 확장할 수 없는 경직된 디자인으로 이어질 수 있습니다.

아래코드는 추상클래스의 예제입니다.

abstract class Shape {
    abstract fun getArea(): Double
}

class Rectangle(val width: Double, val height: Double) : Shape() {
    override fun getArea(): Double {
        return width * height
    }
}

class Circle(val radius: Double) : Shape() {
    override fun getArea(): Double {
        return Math.PI * radius * radius
    }
}
 
 

이 예제에는 getArea() 메서드를 정의하는 추상 클래스 Shape가 있습니다. 그러나 이에 대한 구현을 제공하지 않습니다. getArea() 메서드는 추상적이므로 Shape 클래스에서 상속하는 모든 클래스에 의해 재정의되어야 합니다.

 

그런 다음 두 가지를 정의합니다. Shape 클래스에서 상속되는 Rectangle 및 Circle 클래스. 이 두 클래스는 특정 모양에 따라 고유한 방식으로 getArea() 메서드를 구현합니다.

 

Rectangle 클래스는 width 및 height를 생성자 매개변수로 사용하고 면적을 width * height로 계산합니다. Circle 클래스는 원의 radius를 생성자 매개변수로 사용하고 면적을 pi * radius * radius로 계산합니다.

 

Shape 클래스는 추상적이기 때문에 인스턴스를 직접 만들 수 없습니다. 대신 Rectangle 및 Circle과 같은 구체적인 하위 클래스의 인스턴스를 만들어야 합니다.

 

 

감사합니다!

 
반응형

댓글