扩展接口以更改合同,但不扩展API

问题描述 投票:0回答:2

(我不确定标题术语是否正确。)

假设我正在尝试为可读,可写和可读写的“属性”创建一些抽象。根据具体情况,我可能只想接受可读属性,只接受可写属性或两者(可读和可写)。但是,假设我希望两种类型的属性从相同的超类型派生它们的核心方法,但我也想保持类型安全(例如,如果我请求可读属性,我想要确保我将获得可读属性)。

以下是Property超级界面的外观:

public interface Property {
    // Readable property core methods

    /**
     * Blah blah...
     * @throws UnsupportedOperationException if this property is not readable.
     */
    X readAsX();
    ...

    // Writable property core methods

    /**
     * Blah blah...
     * @throws UnsupportedOperationException if this property is not writable.
     */
    void writeX(X value);
    ...
}

需要注意的重要一点是,如果UnsupportedOperationException不可读/写,则指定适当地抛出Property

现在,以下是定义ReadableProperty的合适方法吗? (WritableProperty的定义也是类似的。)

public interface ReadableProperty extends Property {
    // Readable property core methods

    /**
     * Blah blah...
     * Not allowed to throw UnsupportedOperationException: must be readable!
     */
    X readAsX();
    ...

    // Writable property core methods

    /**
     * Always throws UnsupportedOperationException: this property is not writable.
     */
    default void writeX(X value) {
        throw new UnsupportedOperationException();
    }
    ...
}

注意没有添加新方法;所有改变的是现有方法有更严格的规范。这是针对所述情况的合适设计吗?

(注意:这种情况是虚构的。我更关注这个想法,而不是它的具体应用。)

java interface
2个回答
1
投票

为什么不简单地使用两个抽象类,每个只实现一个方法?

public abstract class ReadableProperty implements Property {
// Readable property core methods
// Writable property core methods

/**
 * Always throws UnsupportedOperationException: this property is not writable.
 */
@Override
final void writeX(X value) {
    throw new UnsupportedOperationException();
}

}

实际上,您正在实现一个接口方法,而不是为接口中新引入的签名定义默认行为(这是引入默认修饰符的主要原因)


1
投票

我将有一个抽象类Property,包含读和写之间的公共操作,一个扩展此抽象类并实现Read操作的ReadProperty和一个扩展此抽象类并实现Read操作的WriteProperty。

通过在界面中执行不受支持的操作,您违反了Liskov Substitution原则。重新审视SOLID原则。

您可以将此Abstract类作为参数传递给您的函数,并在处理时检查它是否实现了读或写接口。

© www.soinside.com 2019 - 2024. All rights reserved.