Since Kotlin does not want to invoke a specific method in only one of several implementation classes for an interface, we would like to prevent it from being used by making a compilation error.
Specifically, suppose you have the following interface and class definitions:
interfaceIHoge{
fun test()
}
class A —IHoge
class B —IHoge
class C —IHoge
Suppose you do not want to invoke C.test()
when and .In other words, if I write C.test()
under this situation, I would like to make it a compilation error. Is there such a way?
Set the method to
funtest(){
error()
}
It is easy to make runtime errors by doing something like that.However, is there any way to prevent C.test()
from being called during compilation?An example of java is acceptable.
Because you do not want to invoke C.test()
, C
should not implement IHoge
in the first place.I will try to answer if I can or can't implement IHoge
below.
In this case, I think it is appropriate to separate the interfaces.
interfaceIHoge{
fun test()
}
interface IFuga {
// Non-test() methods in the original IHoge
}
class A —IHoge, IFuga
class B —IHoge, IFuga
class C —IFuga
In this case, you may be asked to use the default implementation of the interface, so we define IPartial
with a method other than test()
and "merge" IHoge
and IPartial
in the new class D
.
In addition, C
does not inherit D
directly, but deligate to avoid becoming a subclass of IHoge
.
interfaceIHoge{
fun f() = println("f()")
fun test() = println("test()"
}
interface IPartial {
funf();
}
open class D:IHoge,IPartial {
override funf() = super<IHoge>.f();
}
class A —D()
class B —D()
class C(p:IPartial=D())—IPartial by p {
}
funmain(){
val1 = mutableListOf<IHoge>(A(),B())
// l1.add(C(A()))//<--- Compilation Error
l1.forEach {it.test()}
val2 = mutableListOf<IPartial>(A(), B(), C());
l2.forEach {it.f()}
}
test()
test()
f( )
f( )
f( )
It is different from the original usage, but Deprecated
annotation is available.
level
and DeprecationLevel.ERROR
can result in compilation errors.
One caveat is that if you call the test()
method via IHoge
, you will not be able to detect it even if the actual instance is C
.
interfaceIHoge{
fun test()
}
class A:IHoge {
override funtest(){}
}
class C:IHoge {
@Deprecated(message="unavailable method", level=DeprecationLevel.ERROR)
override funtest(){}
}
funmain(args:Array<String>){
valc = C()
c.test()// Compilation Error
vali —IHoge=C()
i.test()// No compilation errors
}
That's right.
However, as far as I can read the questionnaire, I feel that the design is wrong, just like other people's answers (so I think the design should be reviewed).
© 2024 OneMinuteCode. All rights reserved.