Java8默认方法可读性

Java8默认方法可读性,java,default-method,Java,Default Method,Java8引入了默认方法的概念。使用默认方法考虑以下接口: public interface IDefaultMethod { public abstract void musImplementThisMethod(); public default void mayOrMayNotImplementThisMethod() { System.out.println(" This method is optional for classes that imple

Java8引入了默认方法的概念。使用默认方法考虑以下接口:

public interface IDefaultMethod {

    public abstract void musImplementThisMethod();
    public default void mayOrMayNotImplementThisMethod() {
        System.out.println(" This method is optional for classes that implement this interface ");
    }

}
以及实现此接口的类:

    public class DefaultMethodImpl implements IDefaultMethod {

        @Override
        public void musImplementThisMethod() {
                System.out.println("This method must be implementd ");
        }


        @Override
        public void mayOrMayNotImplementThisMethod() {
            // TODO Auto-generated method stub
            IDefaultMethod.super.mayOrMayNotImplementThisMethod();
        }

}
我对
mayOrMayNotImplementThisMethod
中以下调用的可读性有疑问:

IDefaultMethod.super.mayOrMayNotImplementThisMethod();

我理解在上面的调用中显式指定接口名的原因是为了避免在类实现的多个接口具有相同方法的情况下发生混淆。我不明白的是
super
关键字在此上下文中的含义。当我们说
IDefaultMethod.super
时,这里到底指的是什么?IDefaultMethod.mayOrMayNotImplementThisMethod()不是比IDefaultMethod.super.mayOrMayNotImplementThisMethod()更可读吗?删除super关键字使其更具可读性,但代价是区分静态或非静态方法调用。

这只是访问超类成员的常用方法的默认方法的扩展:

格式
T.super.Identifier
指的是与
T
对应的词汇封闭实例的名为
Identifier
的字段,但该实例被视为
T
超类的实例


本质上,当一个类有多个祖先时(无论是因为默认方法还是仅仅因为它在一个层次结构中有多个超类),引用哪个成员可能存在歧义。
super
关键字类似于
Outer。这是内部类中的
;这意味着你想得到“
这个
,但是我会在超类的主体中看到的东西,而不是这个子类中的成员。”

超级
指的是你从中继承的类或接口。这意味着您希望调用一个方法,而忽略该方法已被重写的事实


如果您使用
this
,您将引用该类(或子类),因此具有无限递归。

我将尝试按照我自己的理由对此进行讨论

使用类 首先,让我们看看这是如何与简单Java类一起工作的:

class Barney {
    void foo() { System.out.println("Barney says foo"); }
}

class Fred extends Barney {
    @Override void foo() { super.foo(); }
}
在这种情况下,如果我们在
Fred
实例中调用
foo
方法,它将要求在其超类中实现
foo
方法并执行该方法

显然,其他这些都不起作用:

@Override void foo() { foo(); } //means this.foo() so infinite recursion
@Override void foo() { Barney.foo(); } //means a static method
我们可以进行第三种配置:

class Barney {

    void foo() { System.out.println("Barney says foo"); }

    class Fred extends Barney {
        @Override void foo() { Barney.this.foo(); }
    }

}
在这种情况下,如果我们在
Fred
的实例中调用
foo
,因为这个实例将与其封闭实例有一个连接,这个调用将调用
Barney
封闭实例中的
foo
方法

比如说

new Barney().new Fred().foo();
因此,使用
Barney。这里的
用于在内部/外部关系的实例之间导航

使用接口 现在,让我们尝试对接口重复相同的想法

interface Barney {
    default void foo() { System.out.println("Barney says foo"); }
}


interface Fred extends Barney {
    @Override default void foo() { Barney.super.foo(); }
}
据我所知,这与类完全相同,只是在这种情况下,由于一个接口可以从多个接口继承,我们只需使用我们在本例中针对的接口的名称限定
super
关键字

意思是一样的,我们希望在显式命名的超级接口中调用
foo
方法的“实现”

与类一样,以下内容不起作用:

@Override default void foo() { super.foo(); } //can't be sure of which interface
@Override default void foo() { this.foo(); } //infinite recursion
@Override default void foo() { Barney.foo(); } //static method
@Override default void foo() { Barney.this.foo(); } //not an inner class relation
因此,这里的逻辑选择是
Interface.super.method()

这里的一个问题是,在使用接口时,我们是否曾经有过像
Interface.this.method
这样的用例

interface Barney {
    default void foo() { System.out.println("Barney says foo"); }
}


interface Fred extends Barney {
    @Override default void foo() { Barney.super.foo(); }
}
不完全是这样,因为接口代表一个静态上下文,所以在接口之间从来没有像内部类这样的概念。所以这是不可能的

interface Barney {
    default void foo() { System.out.println("Barney says foo"); }

    interface Fred extends Barney {
            @Override default void foo() { Barney.this.foo(); }
    }
}
基本上,这是不可能的,因为上面的代码并不意味着
Fred
的实例需要存在于
Barney
实例的上下文中。这只是一个静态的内部接口,它的实例可以独立于父接口的任何实例而存在

所以,这就是为什么这不是一个好的选择


因此,正如您所看到的,在所有这些之后,
super
的使用是有意义的,或者至少我希望我已经解释得足够好,能够传达这个想法。

Java8接口也有静态方法

如果你说, IDefaultMethod.mayOrMayNotImplementThisMethod();
然后,它是一种调用静态方法的方法,这似乎也是正确的,因为它类似于我们访问类的静态成员的方式。

对于默认方法,若并没有使用“super”,那个么他们可能已经使用了“this”,这并没有意义,因为“this”属于我们正在进行方法调用的类


我的意见是,您是对的,因为它不具有良好的可读性,但似乎符合语言设计。

很抱歉,我仍然无法理解IDefaultMethod.super调用。而Outer.this意味着让我得到与内部this对应的外部this,IDefaultMethod.super是什么意思?给我IDefaultMethod接口的super?super的一般用法是指父级。当我说超级什么的时候,我指的是父母什么的。阅读IDefaultMethod.super并以同样的方式思考是不直观的。@bot它的意思是“附加到
IDefaultMethod
的此方法的版本”,而不是“附加到
AbstractDefaultMethodImpl
的此方法的版本”。
super
是区分静态方法所必需的。在同一接口或类中,不能有同名的静态方法和非静态方法。当IDefaultMethod中没有静态MayorMayonNotImplementThisMethod()方法时,为什么需要super关键字来区分它与静态方法?我认为误解来自于您对super的定义。还是松松地说T.super