Java 8种默认方法可读性
Java 8 default method readability
Java 8介绍了默认方法的概念。考虑以下带有默认方法的接口:
public interface IDefaultMethod {
public abstract void musImplementThisMethod();
public default void mayOrMayNotImplementThisMethod() {
System.out.println(" This method is optional for classes that implement this interface ");
}
}
还有一个实现这个接口的 class :
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();
我理解在上述调用中显式指定接口名称的原因是为了避免在 class 实现的多个接口具有相同方法的情况下混淆。我不明白的是 super
关键字在这种情况下的含义。当我们说 IDefaultMethod.super
时,我们指的到底是什么? IDefaultMethod.mayOrMayNotImplementThisMethod() 不会比 IDefaultMethod.super.mayOrMayNotImplementThisMethod() 更具可读性吗?删除 super 关键字使其更具可读性,但以区分静态或非静态方法调用为代价。
这只是对访问 superclasses (JLS 15.11):
成员的常用方法的默认方法的扩展
The form T.super.Identifier
refers to the field named Identifier
of the lexically enclosing instance corresponding to T
, but with that instance viewed as an instance of the superclass of T
.
本质上,当 class 有多个祖先时(无论是因为默认方法还是仅仅因为它有多个 superclasses 在层次结构)。 super
关键字是内部 class 中 Outer.this
的类比;这意味着你想得到“this
,但我会在那个超级class的主体内看到的东西,而不是这个子class内的成员”。
super
指的是 class 或您继承的接口。这意味着您想调用一个方法而忽略它已被覆盖的事实。
如果您使用 this
,您将引用此 class(或子 class),因此具有无限递归。
我会根据自己的推理来为讨论做出贡献。
使用类
首先,让我们看看它如何使用简单的 Java classes:
class Barney {
void foo() { System.out.println("Barney says foo"); }
}
class Fred extends Barney {
@Override void foo() { super.foo(); }
}
在这种情况下,如果我们在 Fred
实例中调用方法 foo
,它将要求 实现 foo
方法 在它的 super class 中执行那个。
显然,none 这些其他人可以工作:
@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
,因为此实例与其封闭实例有一个键,此调用将调用 foo
中的方法Barney
.
的封闭实例
例如
new Barney().new Fred().foo();
因此,此处使用 Barney.this
用于在 inner/outer 关系中的实例之间导航。
使用界面
现在让我们尝试对接口重复相同的想法。
interface Barney {
default void foo() { System.out.println("Barney says foo"); }
}
interface Fred extends Barney {
@Override default void foo() { Barney.super.foo(); }
}
据我所知,这与 classes 完全相同,只是在这种情况下,因为一个接口可以继承自多个接口,我们只需限定 super
关键字与我们在这种情况下定位的接口的名称。
意思是一样的,我们要在显式命名的super接口中调用foo
方法的"implementation"
与 classes 一样,以下内容不起作用:
@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
这样的用例。
不完全是,因为接口代表静态上下文,因此接口之间从来没有像内部 classes 那样的概念。所以这是不可能的。
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();
那么就是调用静态方法的方式,貌似也是正确的,和我们访问class的静态成员类似。
对于默认方法,如果未使用 'super' 那么他们可能会使用 'this',这没有意义,因为 'this' 属于我们所在的 class进行方法调用。
我的意见是,你是对的,因为它没有提供良好的可读性,但似乎符合语言设计。
Java 8介绍了默认方法的概念。考虑以下带有默认方法的接口:
public interface IDefaultMethod {
public abstract void musImplementThisMethod();
public default void mayOrMayNotImplementThisMethod() {
System.out.println(" This method is optional for classes that implement this interface ");
}
}
还有一个实现这个接口的 class :
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();
我理解在上述调用中显式指定接口名称的原因是为了避免在 class 实现的多个接口具有相同方法的情况下混淆。我不明白的是 super
关键字在这种情况下的含义。当我们说 IDefaultMethod.super
时,我们指的到底是什么? IDefaultMethod.mayOrMayNotImplementThisMethod() 不会比 IDefaultMethod.super.mayOrMayNotImplementThisMethod() 更具可读性吗?删除 super 关键字使其更具可读性,但以区分静态或非静态方法调用为代价。
这只是对访问 superclasses (JLS 15.11):
成员的常用方法的默认方法的扩展The form
T.super.Identifier
refers to the field namedIdentifier
of the lexically enclosing instance corresponding toT
, but with that instance viewed as an instance of the superclass ofT
.
本质上,当 class 有多个祖先时(无论是因为默认方法还是仅仅因为它有多个 superclasses 在层次结构)。 super
关键字是内部 class 中 Outer.this
的类比;这意味着你想得到“this
,但我会在那个超级class的主体内看到的东西,而不是这个子class内的成员”。
super
指的是 class 或您继承的接口。这意味着您想调用一个方法而忽略它已被覆盖的事实。
如果您使用 this
,您将引用此 class(或子 class),因此具有无限递归。
我会根据自己的推理来为讨论做出贡献。
使用类
首先,让我们看看它如何使用简单的 Java classes:
class Barney {
void foo() { System.out.println("Barney says foo"); }
}
class Fred extends Barney {
@Override void foo() { super.foo(); }
}
在这种情况下,如果我们在 Fred
实例中调用方法 foo
,它将要求 实现 foo
方法 在它的 super class 中执行那个。
显然,none 这些其他人可以工作:
@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
,因为此实例与其封闭实例有一个键,此调用将调用 foo
中的方法Barney
.
例如
new Barney().new Fred().foo();
因此,此处使用 Barney.this
用于在 inner/outer 关系中的实例之间导航。
使用界面
现在让我们尝试对接口重复相同的想法。
interface Barney {
default void foo() { System.out.println("Barney says foo"); }
}
interface Fred extends Barney {
@Override default void foo() { Barney.super.foo(); }
}
据我所知,这与 classes 完全相同,只是在这种情况下,因为一个接口可以继承自多个接口,我们只需限定 super
关键字与我们在这种情况下定位的接口的名称。
意思是一样的,我们要在显式命名的super接口中调用foo
方法的"implementation"
与 classes 一样,以下内容不起作用:
@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
这样的用例。
不完全是,因为接口代表静态上下文,因此接口之间从来没有像内部 classes 那样的概念。所以这是不可能的。
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();
那么就是调用静态方法的方式,貌似也是正确的,和我们访问class的静态成员类似。
对于默认方法,如果未使用 'super' 那么他们可能会使用 'this',这没有意义,因为 'this' 属于我们所在的 class进行方法调用。
我的意见是,你是对的,因为它没有提供良好的可读性,但似乎符合语言设计。