(我不确定标题术语是否正确。)
假设我正在尝试为可读,可写和可读写的“属性”创建一些抽象。根据具体情况,我可能只想接受可读属性,只接受可写属性或两者(可读和可写)。但是,假设我希望两种类型的属性从相同的超类型派生它们的核心方法,但我也想保持类型安全(例如,如果我请求可读属性,我想要确保我将获得可读属性)。
以下是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();
}
...
}
注意没有添加新方法;所有改变的是现有方法有更严格的规范。这是针对所述情况的合适设计吗?
(注意:这种情况是虚构的。我更关注这个想法,而不是它的具体应用。)
为什么不简单地使用两个抽象类,每个只实现一个方法?
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();
}
}
实际上,您正在实现一个接口方法,而不是为接口中新引入的签名定义默认行为(这是引入默认修饰符的主要原因)
我将有一个抽象类Property,包含读和写之间的公共操作,一个扩展此抽象类并实现Read操作的ReadProperty和一个扩展此抽象类并实现Read操作的WriteProperty。
通过在界面中执行不受支持的操作,您违反了Liskov Substitution原则。重新审视SOLID原则。
您可以将此Abstract类作为参数传递给您的函数,并在处理时检查它是否实现了读或写接口。