如何在覆盖实现中调用接口的方法的默认实现?
How to invoke an interface's default implementation of a method in an overriding implementation?
假设我有以下代码:
interface HumanoidForm {
default HumanoidForm reproduce() {
<appropriate code for humanoid form reproduction>
}
}
class Android extends Machine implements HumanoidForm {
public HumanoidForm reproduce() {
<appropriate code for android reproduction> // how to use HumanoidForm's default implementation here?
}
}
现在假设 "appropriate code for android reproduction" 最好用 "appropriate code for humanoid form reproduction" 作为子例程来描述。如何从 "appropriate code for android reproduction" 中访问 "appropriate code for humanoid form"?我可以想到三种方法,但其中 none 行得通:
- 只需调用 reproduce() 即可调用覆盖实现。
- 编写 ((HumanoidForm) this).reproduce() 仍然调用覆盖实现。
- 通过覆盖方法来模仿super类中方法实现的重用,可能会想到写super.reproduce()。但是,那指的是机器对重现的实现,它甚至可能不存在。
所以似乎没有办法重新使用默认方法中的代码进行覆盖。真的是这样吗?
HumanoidForm.super.reproduce();
看看这个:https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/
特别是说 "If we want to specifically invoke one of the sayHi() methods in either InterfaceA or InterfaceB, we can also do as follows:"
的部分
public class MyClass implements InterfaceA, InterfaceB {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
}
@Override
public void saySomething() {
System.out.println("Hello World");
}
@Override
public void sayHi() {
InterfaceA.super.sayHi();
}
}
interface InterfaceA {
public void saySomething();
default public void sayHi() {
System.out.println("Hi from InterfaceA");
}
}
interface InterfaceB {
default public void sayHi() {
System.out.println("Hi from InterfaceB");
}
}
So it seems there is no way to re-use the code in the default method for overriding. Is that really so?
不,您可以重复使用代码。您可以轻松地对其进行测试,您将看到以下代码有效:
public class Test implements HumanoidForm
{
public static void main(String[] args)
{
new Test().reproduce();
}
@Override
public void reproduce(){
HumanoidForm.super.reproduce(); //Invoking default method
System.out.println("From implementing class");
}
}
interface HumanoidForm {
default void reproduce() {
System.out.println("From default interface");
}
}
输出:
From default interface
From implementing class
实际上,您可以自由选择现有的实现。让我给你一个比你的稍微复杂的场景。更糟糕的是,所有 A
、B
和 C
都具有相同的方法签名。
interface A {
default void doWork() {
System.out.println("Default implementation From A");
}
}
interface B{
default void doWork() {
System.out.println("Default implementation From B");
}
}
class C{
void doWork(){
System.out.println("Default implementation From C");
}
}
现在,我创建一个 C 的子类来实现 A 和 B:
class Tester extends C implements A, B
{
@Override public void doWork(){
A.super.doWork(); //Invoke A's implementation
B.super.doWork(); //Invoke B's implementation
super.doWork(); //Invoke C's implementation
}
}
输出将是:
Default implementation From A
Default implementation From B
Default implementation From C
当你运行:
new Tester().doWork();
假设我有以下代码:
interface HumanoidForm {
default HumanoidForm reproduce() {
<appropriate code for humanoid form reproduction>
}
}
class Android extends Machine implements HumanoidForm {
public HumanoidForm reproduce() {
<appropriate code for android reproduction> // how to use HumanoidForm's default implementation here?
}
}
现在假设 "appropriate code for android reproduction" 最好用 "appropriate code for humanoid form reproduction" 作为子例程来描述。如何从 "appropriate code for android reproduction" 中访问 "appropriate code for humanoid form"?我可以想到三种方法,但其中 none 行得通:
- 只需调用 reproduce() 即可调用覆盖实现。
- 编写 ((HumanoidForm) this).reproduce() 仍然调用覆盖实现。
- 通过覆盖方法来模仿super类中方法实现的重用,可能会想到写super.reproduce()。但是,那指的是机器对重现的实现,它甚至可能不存在。
所以似乎没有办法重新使用默认方法中的代码进行覆盖。真的是这样吗?
HumanoidForm.super.reproduce();
看看这个:https://blog.idrsolutions.com/2015/01/java-8-default-methods-explained-5-minutes/
特别是说 "If we want to specifically invoke one of the sayHi() methods in either InterfaceA or InterfaceB, we can also do as follows:"
的部分public class MyClass implements InterfaceA, InterfaceB {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
}
@Override
public void saySomething() {
System.out.println("Hello World");
}
@Override
public void sayHi() {
InterfaceA.super.sayHi();
}
}
interface InterfaceA {
public void saySomething();
default public void sayHi() {
System.out.println("Hi from InterfaceA");
}
}
interface InterfaceB {
default public void sayHi() {
System.out.println("Hi from InterfaceB");
}
}
So it seems there is no way to re-use the code in the default method for overriding. Is that really so?
不,您可以重复使用代码。您可以轻松地对其进行测试,您将看到以下代码有效:
public class Test implements HumanoidForm
{
public static void main(String[] args)
{
new Test().reproduce();
}
@Override
public void reproduce(){
HumanoidForm.super.reproduce(); //Invoking default method
System.out.println("From implementing class");
}
}
interface HumanoidForm {
default void reproduce() {
System.out.println("From default interface");
}
}
输出:
From default interface
From implementing class
实际上,您可以自由选择现有的实现。让我给你一个比你的稍微复杂的场景。更糟糕的是,所有 A
、B
和 C
都具有相同的方法签名。
interface A {
default void doWork() {
System.out.println("Default implementation From A");
}
}
interface B{
default void doWork() {
System.out.println("Default implementation From B");
}
}
class C{
void doWork(){
System.out.println("Default implementation From C");
}
}
现在,我创建一个 C 的子类来实现 A 和 B:
class Tester extends C implements A, B
{
@Override public void doWork(){
A.super.doWork(); //Invoke A's implementation
B.super.doWork(); //Invoke B's implementation
super.doWork(); //Invoke C's implementation
}
}
输出将是:
Default implementation From A
Default implementation From B
Default implementation From C
当你运行:
new Tester().doWork();