[Dart] mixin이란?

티라노·2025년 1월 13일
0

Today I Learned

목록 보기
34/38

mixin 키워드에 대해 알아보자.

들어가기

Dart 시스템에서 클래스를 상속받을 때는 보통 아래의 포맷을 따른다.

class MyName extends Name
  {
 	...
  }

그런데 가끔 아래처럼 상속하는 경우가 있었다.

class MyName extends Name with Age
  {
	 ...
  }

지나가며 검색해보니 Mixin 기능과 관련이 있는 것 같았는데 정확히 무엇인지는 모르고 넘어갔었다. 이번 기회에 Mixin 이란 무엇인지, 기존에 사용하던 extendsimplements 와는 무엇이 다른지 알아보자.


추상 클래스와 인터페이스

먼저 상속을 대표하는 두 가지 종류의 클래스에 대해 가볍게 알아보고 넘어가자.

추상 클래스

abstract class AbstractClass {
  int number = 3;
  
  int getNumber(){ return number; }
  
  void setNumber();
  
}

추상 클래스는 멤버 변수, 정의된 메서드, 정의되지 않은 메서드를 모두 포함할 수 있다.

인터페이스

abstract interface class InterfaceClass {
  late int number;
  
  int getNumber();
  
  void setNumber();
  
}

인터페이스는 정의되지 않은 요소만 멤버로 가진다. 변수나 메서드는 자식 클래스에서 오버라이딩하여 정의해야 한다.

extends와 implements

두 키워드 모두 클래스를 상속받는 키워드이지만 쓰임새가 조금 다르다.

extends ( + 추상 클래스 )

extends 는 변수와 메서드가 존재하는 클래스를 상속받는 키워드이다.
상속 받는 즉시 부모 클래스의 메서드를 사용할 수 있지만 다중 상속은 불가능하다.

implements ( + 인터페이스 )

implements 는 인터페이스를 상속받는 키워드이다. extends 와 달리 대상이 인터페이스라서 메서드만 정의되어있고 기능은 구현되어있지 않다. 따라서 자식 클래스에서 오버라이딩을 해야 한다.
그래서 상속이 아닌 구현이라는 뜻으로 implements 라는 키워드를 사용한다. 다중 상속이 가능하다.

추상 클래스와 인터페이스의 차이

mixin과 with

클래스에 mixin 키워드를 붙여 선언하면, 자식 클래스를 선언할 때 with 키워드를 활용해서 상속받을 수 있다.
with 는 위의 두 키워드를 적절히 섞어 놓은 것이라고 생각하면 된다. 추상 클래스를 상속받으면서도 다중 상속이 가능하게끔 돕는다. 예시를 통해 알아보자.

mixin Bread {
  void addBread(){ print("bread"); }
}

mixin Tomato {
  void addTomato(){ print("tomato"); }
}

mixin Meat {
  void addMeat(){ print("Meat"); }
}

세 가지 클래스를 상속받는 자식 클래스를 만들어보자.

class Sandwich with Meat, Bread, Tomato{
}

void main(){
  Sandwich mySandwich = Sandwich();
  
  mySandwich.addBread();
  mySandwich.addTomato();
  mySandwich.addMeat();
}

이런 식으로 상속받은 세 가지 클래스의 메서드를 모두 사용할 수 있다.

오버라이딩도 가능하다.


블로그 검색하면서 생긴 궁금한 점

1. 키워드가 class여도 with에 붙일 수 있다?

mixin 키워드를 넣지 않아도 with 뒤에 올 수 있을까 궁금해서 바로 해봤는데...안 된다.

2. 동일한 메서드가 있을 때


mixin Tomato {
  void addTomato() {
    print("tomato");
  }

  void addMeat() {
    print("Tomato Meat");
  }
}

Meat 클래스에 이미 존재하는 addMeat() 함수를 Tomato 클래스에도 같은 이름으로 정의하고 자식 클래스에서 사용이 되나 테스트해보았다.

Meat를 먼저 상속했을 때

Tomato를 먼저 상속했을 때

with에서 뒤에 상속받은 클래스의 메서드가 더 우선시된다는 점을 알았다.
그러면 mixin과 class에 같은 이름의 메서드가 동시에 있으면 어떻게 될까?

클래스 Bread에 addTomato() 함수를 추가했는데 Tomato의 함수가 출력된다. class인지 mixin인지에 상관없이 마지막으로 상속받은 클래스의 메서드를 선택하는 것 같다.


요약

mixin이 무엇인지?

이미 정의된 멤버를 가지면서도 다중 상속이 가능한 객체를 만들 때 사용하는 키워드이다. mixin으로 선언한 객체는 with를 통해 상속받을 수 있으며 여러 객체를 나열하고 콤마(,)로 구분한다. 같은 이름의 멤버가 여러 mixin에 존재할 경우 나중에 상속받은 쪽의 멤버가 우선시된다.

mixin과 추상 클래스의 차이점은?

둘 다 정의된 멤버를 가질 수 있기 때문에 비슷하게 보이지만, mixin은 다중 상속이 가능하고 추상 클래스는 그렇지 못하다.

0개의 댓글

관련 채용 정보