正确使用界面中的默认关键字

ahs*_*dev 3 java default interface java-8

我有一个同事需要一种方法可以用于两个类。

他决定创建一个由这些类实现的新接口。

接口有一个方法 default doThis(String parameter)

它没有任何其他接口方法,没有迹象表明会向该接口添加其他方法。

我觉得这是对界面的不正确使用,应该以不同的方式完成。即可能是一个具有允许其他类通过使用对象来使用它的方法的类。

有没有这方面经验的人有什么意见可以分享?

我可以根据您的评论更新更多说明。

更新:

这是代码,问题仍然存在:这是对默认方法的有效使用,还是应该以另一种方式完成此通用逻辑,例如将保存到首选项的 Utilities 类?

界面:

public interface LogInCookie {

    default void mapCookiesToPreferences(String cookie) {
        if (cookie.contains(MiscConstants.HEADER_KEY_REFRESH)) {
            String refreshToken = cookie.replace(MiscConstants.HEADER_KEY_REFRESH, StringUtils.EMPTY);
            SharedPrefUtils.addPreference(SharedPrefConstants.REFRESH_TOKEN, refreshToken);
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)
public class HDAccountActivity extends AbstractActivity implements LogInCookie {

    private void mapCookies(List<String> mValue) {
       LogInCookie.super.mapCookiesToPreferences(mValue); //ekh!
    }

}
Run Code Online (Sandbox Code Playgroud)
public class BaseSplashPage extends AppCompatActivity implements DialogClickedCallBack, LogInCookie {

//method which uses this
private void mapCookiesToPreferences(List<String> headers) {
        int firstItemInHeader = 0;
        for (String header : headers) {
            String  mValue =  header.substring(firstItemInHeader,header.indexOf(MiscConstants.SEMICOLON));
            LogInCookie.super.mapCookiesToPreferences(mValue);  //ekh!
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 5

default接口中的方法没有定义其他方法,不能对实现类的实例做很多有用的事情。它只能使用从 继承的方法java.lang.Object,这些方法不太可能携带与接口相关的语义。

如果代码根本不使用实例方法this,换句话说,完全独立于this实例,你应该让它static,将包含的类更改为不可实例化的class类型,即

final class SomeUtilClass {
    static void doThis(String parameter) {
    // ...
    }

    private SomeUtilClass() {} //no instances
}
Run Code Online (Sandbox Code Playgroud)

import static packageof.SomeUtilClass.doThis;在使用此方法的类中使用。

这样,所有这些类都可以像doThis(…)没有限定类型名称一样调用方法,不需要误导性的类型层次结构。

当方法实际使用this实例时,如上所述,实例只能是从 继承的方法java.lang.Object,类型继承可能是合理的。由于这是不太可能的,您可能仍然认为类型层次结构具有误导性并将代码重写为

final class SomeUtilClass {
    static void doThis(Object firstParameter, String parameter) {
    // ...
    }

    private SomeUtilClass() {} //no instances
}
Run Code Online (Sandbox Code Playgroud)

使用firstParameter代替this,可以像 那样调用doThis(this, …)

  • 当您想要测试一个方法时,您应该使用准备好的输入来调用它,并验证它是否产生预期的输出。这就是单元测试的工作原理。大多数时候,我们使用的是模拟工具,但它的使用方式是错误的。您很少需要模拟工具来进行测试。在这方面,“默认”方法和“静态”方法之间没有根本区别。您的同事使用它的方式,在任何一种情况下,您都无法在不进行模拟的情况下拦截调用(但如上所述,您通常很少需要它来进行单元测试)。 (2认同)