正确使用界面中的default关键字

Using default keyword in interface correctly

我有一个同事需要一种方法供两个 classes 使用。

他决定创建一个新接口,由 classes 实现。

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

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

我觉得这是对界面的错误使用,应该以不同的方式完成。即也许 class 具有允许其他 classes 通过使用该对象来使用它的方法。

请问有这方面经验的朋友有什么意见可以分享吗?

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

更新:

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

接口:

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);
        } 
    }
}
public class HDAccountActivity extends AbstractActivity implements LogInCookie {

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

}
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!
        }
    }

}

接口中的默认方法
*)可以有一个默认实现
*) 可以被实现 class

覆盖

是的,它是自 JAVA8 以来的正确用法。
我们可以在接口中有默认方法以及抽象方法

理想情况下,您可以将该方法 doThis() 放在两个 class 都扩展的抽象 class 中。但是,如果您需要实现多重继承,那么在这里使用接口就可以了。

带有静态方法 doThis() 并且可以静态调用的 class 也可以。

这完全取决于您组织项目的方式。

在 java8 中,引入了 default 关键字 in interface 以应对任何一组 api 具有长继承层次结构的情况,并且我们想引入一种应该在所有较低层中都可用的方法 classes.

所以对于前。在 Java 8 中,stream() 方法作为默认方法引入到 Collection 接口中,它最终在所有底层 classes 中可用。

就您所考虑的情况而言,如果我按照您的话行事,那么如果您的开发是新开发的,那么您应该使用接口 -> 抽象 class -> 实际实现 class。

只有当您的开发设置较旧并且您已经 classes 从接口实现时,这才是在您的接口中使用默认方法的理想方案。

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

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

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

    private SomeUtilClass() {} //no instances
}

并使用此方法在 class 中使用 import static packageof.SomeUtilClass.doThis;

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

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

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

    private SomeUtilClass() {} //no instances
}

使用 firstParameter 而不是 this,可以像 doThis(this, …).

一样调用