A preface.
Usually, we may be faced with a scenario where there are many methods on an interface of the system, and our business needs to implement the interface. What we really need are only a few methods of the interface, but we have to rewrite other useless methods to implement the interface, resulting in a large pile of useless code, such as:
public interface Way {
void solve2(a);
void solve1(a);
void solve3(a);
void solve4(a);
}
/** * The only method we really need for this interface is solve2, but the other three interfaces of the interface have to be rewritten * and given an empty implementation, resulting in useless code pile */
Way way = new Way() {
@Override
public void solve2(a) {
System.out.println("child solve2");
}
@Override
public void solve1(a) {}@Override
public void solve3(a) {}@Override
public void solve4(a) {}}Copy the code
This article focuses on how to solve this pain point from the perspective of Java and Kotlin respectively
Java optimization interface implementation
- Interfaces belong to system API or third-party library API definitions
Using the Way example above, if the interface is system-provided, we can use an abstract class approach as a bridge between the business code implementation and the system interface
Define an abstract class that implements all methods of the Way interface:
public abstract class WayAdapter implements Way {
@Override
public void solve2(a) {}@Override
public void solve1(a) {}@Override
public void solve3(a) {}@Override
public void solve4(a) {}}Copy the code
So if the business needs to use the system interface Way, we do not implement Way directly inherit the above class WayAdapter, selectively rewrite the method we need, without additional processing of other unnecessary methods
@Test
public void main(a) {
Way way = new WayAdapter() {
@Override
public void solve2(a) {}}; }Copy the code
Animation The listener class AnimatorListenerAdapter is based on this
- Interfaces belong to their own business layer definition
We use the Java8 default keyword directly to change the way the interface part of the method is defined: default in the interface to modify the method can be directly in the interface to give an empty implementation, subclasses do not need this method and do not need additional overwriting
public interface Way {
void solve2(a);
default void solve1(a) {}default void solve3(a) {}default void solve4(a) {}}Copy the code
If the Way interface forces the solve2 subclass to be overridden and the other methods optional, we simply give the optional method an empty implementation with the default modifier
@Test
public void main(a) {
Way way = new Way() {
@Override
public void solve2(a) {}}; }Copy the code
Lifecycle’s DefaultLifecycleObserve is based on this
Kotlin optimized interface implementation
- Interfaces belong to system API or third-party library API definitions
Kotlin has two solutions to this situation:
- As in Java above, it is solved by an intermediate abstract class
interface Color {
fun alpha(a)
fun result(a)
fun process(a)
}
abstract class ColorAdapter: Color {
override fun alpha(a){}override fun result(a){}override fun process(a){}}Copy the code
- Through the syntax features of the Kotlin DSL
// Get an object of interface type Color
fun obtainColor(block: ColorAdapter. () - >Unit): Color {
return ColorAdapter().apply(block)
}
class ColorAdapter : Color {
private var alpha: (() -> Unit)? = null
private var result: (() -> Unit)? = null
private var process: (() -> Unit)? = null
fun setAlpha(block: () -> Unit) {
alpha = block
}
fun setResult(block: () -> Unit) {
result = block
}
fun setProcess(block: () -> Unit) {
process = block
}
override fun alpha(a){ alpha? .invoke() }override fun result(a){ result? .invoke() }override fun process(a){ process? .invoke() } }Copy the code
Where the business needs it, it can be used as follows:
Call the required setResult or setResult() or setProcess() method as required by the business
val color: Color = obtainColor {
setResult {
// Todo implements specific code logic}}Copy the code
- Interfaces belong to their own business layer definition
This approach is basically the same as the Java approach, except that Kotlin does not add default
interface Color {
fun alpha(a){}fun result(a){}fun process(a)
}
Copy the code
Use:
val color2: Color = object : Color {
override fun process(a){}}Copy the code
Iv. Easter Eggs (Digression)
If Kotlin needs to define a functional interface (an interface that contains only one method), Kotlin has two options:
- If you want to implement the SAM transformation, the Kotlin interface definition needs to be preceded by a
fun
The keyword
fun interface Tree {
fun num(a)
}
Copy the code
- Use kotlin-specific function types directly without defining interfaces:
var listen: ((View) -> Unit)? = null