상속과 조합 in Android

유진·2024년 11월 28일
0

Android

목록 보기
2/3

OOP에서 강조되는 상속과 조합을 OOP언어로 개발하는 안드로이드의 예시를 들어 설명해보겠다!

상속은 정말 익숙한 개념이다. 대학교 2학년 때부터니 벌써 2년 동안은 상속에 대해 지겹도록 봐온 것이다. 하지만 조합? 음.. 조합이 뭔데? 하는 나를 발견하여 이 글을 쓰게 되었다.

안드로이드 뿐만 아니라 개발을 하게 되면 클래스의 설계코드 재사용은 정말로 중요하다. 말로만 중요한 것이 아니라 even한 코드를 짜기 위해서는 정말 중요하다. 그래서 저 두가지를 잘하는 것이 정말 중요한데, 상속과 조합을 적재적소에 사용해서 해소할 수 있다.


1. 상속(Inheritance)

정의

상속은 클래스 간의 부모-자식 관계를 정의하며, 자식 클래스가 부모 클래스의 속성과 메서드를 물려받을 수 있도록 한다.

특징

  • extends 키워드를 사용해 구현.
  • 자식 클래스는 부모 클래스의 모든 public, protected 멤버를 물려받음.
  • 단일 상속만 가능 (다중 상속은 지원하지 않음).

장점

  • 코드 재사용성이 높음.
  • 공통 기능을 상위 클래스에 정의하여 관리할 수 있음.
  • 객체 지향적인 설계 방식과 잘 어울림.

단점

  • 부모-자식 클래스 간 결합도가 높아짐.
  • 부모 클래스의 변경이 자식 클래스에 영향을 미침.
  • "is-a" 관계를 강제하므로, 모든 상황에서 적합하지 않음.

안드로이드에서 사용 예시

  • Activity 상속:
    class MyActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
        }
    }
  • Custom View 상속:
    class CustomTextView(context: Context, attrs: AttributeSet) : TextView(context, attrs) {
        init {
            setTextColor(Color.BLUE)
        }
    }

2. 조합(Composition)

정의

조합은 객체가 다른 객체를 포함(참조)함으로써 기능을 확장하거나 재사용하는 방식이다.

특징

  • "has-a" 관계를 표현.
  • 한 클래스가 다른 클래스의 인스턴스를 필드로 포함.

장점

  • 결합도가 낮아 유지보수성이 높음.
  • 객체 간 유연한 관계를 설정 가능.
  • 다중 기능 조합이 가능.

단점

  • 초기 설계가 복잡할 수 있음.
  • 직접 메서드를 위임해야 하므로 코드가 약간 길어질 수 있음.

안드로이드에서 사용 예시

  • Custom Component 조합:

    class MyCustomComponent(context: Context) {
        private val textView = TextView(context)
        private val button = Button(context)
    
        fun setup() {
            textView.text = "Hello"
            button.text = "Click Me"
        }
    }
  • Delegation 사용:

    class MyLogger {
        fun log(message: String) {
            println(message)
        }
    }
    
    class MyComponent(private val logger: MyLogger) {
        fun performAction() {
            logger.log("Action performed")
        }
    }

3. 상속과 조합의 비교

특징상속조합
재사용성부모 클래스의 모든 기능을 재사용 가능필요한 기능만 선택적으로 사용 가능
결합도높음낮음
유연성부모 클래스 변경 시 자식 클래스 영향 큼독립적, 유연한 설계 가능
다중 기능 지원단일 상속만 가능여러 객체를 포함해 다중 기능 조합 가능
관계"is-a" 관계"has-a" 관계

4. 언제 사용해야 할까?

상속을 사용하는 경우

  • 부모 클래스의 대부분의 기능이 자식 클래스에 적합할 때.
  • 공통된 동작이 많은 유사한 클래스가 필요할 때.
  • 강력한 "is-a" 관계가 있을 때.
    • 예: 모든 Activity는 기본적으로 AppCompatActivity에서 시작.

조합을 사용하는 경우

  • 더 유연하고 독립적인 설계가 필요할 때.
  • 다중 기능을 조합해 사용할 때.
  • "has-a" 관계가 더 적합할 때.
    • 예: ViewModel에서 Repository를 포함해 데이터를 관리.

5. 안드로이드에서의 실제 사용 사례

상속 예제: BaseActivity

  • 공통 로직을 처리하기 위해 상속 사용.

    open class BaseActivity : AppCompatActivity() {
        fun setupToolbar() {
            // 공통 툴바 설정
        }
    }
    
    class MainActivity : BaseActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setupToolbar()
        }
    }

조합 예제: Repository와 ViewModel

  • 조합을 사용해 독립적인 역할을 유지.

    class UserRepository {
        fun getUser(): User {
            // 사용자 데이터 반환
        }
    }
    
    class UserViewModel(private val repository: UserRepository) : ViewModel() {
        fun getUser() = repository.getUser()
    }

6. 결론

  • 상속은 간단하고 강력하지만, 결합도가 높아질 수 있으므로 제한적으로 사용.
  • 조합은 유연하고 결합도가 낮아 유지보수가 용이하므로 일반적으로 더 권장되는 방법.
  • 안드로이드에서는 상속은 UI 클래스(View, Activity)에서, 조합은 데이터 및 비즈니스 로직(ViewModel, Repository 등)에서 주로 사용된다.

마사카!!! 난 이미 조합을 쓰고 있었던 것이다. 의존성으로 받는 행위가 다 !!!! 조합이었던 것이다~!!!

왜냐?? Viewmodel(repository)의 예시로 들면, 레포지토리의 메소드를 뷰모델 클래스 안에서 복붙해서 계속 만드는게 아니라, 레포지토리라는 클래스를 잘~ 만들어놓고, 필요한 곳에서 호출! 해서 쓰기 때문에 이것은 조합이다.

profile
안드로이드 학생 개발자 에디 / 유진입니다

0개의 댓글