mixin_application_concrete_super_invoked_member_type 진단: super로 호출한 멤버의 타입이 실제 구현과 달라요
mixin_application_concrete_super_invoked_member_type 진단: super로 호출한 멤버의 타입이 실제 구현과 달라요
분석기가 내보내는 진단에는 이름이 있어요. mixin_application_concrete_super_invoked_member_type은 super를 통해 호출하는 멤버의 시그니처가, mixin이 선언한 on 타입에 정의된 시그니처와 다른 클래스에서 mixin이 사용될 때 Dart 분석기가 알려주는 컴파일 타임 진단이에요. 이 경우 mixin 안의 호출이 실제로 실행될 메서드와는 맞지 않는 방식으로 호출될 수 있기 때문에 오류가 되는 거예요.
본문
설명
분석기는 super를 사용해 메서드를 호출하는 mixin이, 그 메서드의 실제 구현(concrete implementation)이 mixin의 on 타입에 정의된 시그니처와 다른 시그니처를 가진 클래스에 적용될 때 이 진단을 만들어요. 오류인 이유는 mixin 안의 호출이 실제로 실행될 메서드와 호환되지 않는 방식으로 그 메서드를 호출할 수 있기 때문이에요.
예시
다음 코드는 클래스 C가 mixin M을 사용하고, mixin M이 super로 foo를 호출하는데, I(mixin의 on 타입)에 선언된 추상 버전의 foo가 A에 선언된 실제 버전의 foo와 시그니처가 같지 않아서 이 진단이 나와요.
class I {
void foo([int? p]) {}
}
class A {
void foo(int p) {}
}
abstract class B extends A implements I {
@override
void foo([int? p]);
}
mixin M on I {
void bar() {
super.foo(42);
}
}
abstract class C extends B with M {}
흔한 해결 방법
클래스가 mixin을 쓸 필요가 없다면, with 절에서 mixin을 빼 버려요.
class I {
void foo([int? p]) {}
}
class A {
void foo(int? p) {}
}
abstract class B extends A implements I {
@override
void foo([int? p]);
}
mixin M on I {
void bar() {
super.foo(42);
}
}
abstract class C extends B {}
클래스가 mixin을 꼭 써야 한다면, mixin이 기대하는 시그니처에 맞는 실제 구현을 가진 메서드가 있도록 만들어 줘요.
class I {
void foo([int? p]) {}
}
class A {
void foo(int? p) {}
}
abstract class B extends A implements I {
@override
void foo([int? p]) {
super.foo(p);
}
}
mixin M on I {
void bar() {
super.foo(42);
}
}
abstract class C extends B with M {}