它已经讨论过堆栈溢出,我们应该更喜欢属性标记接口(接口没有任何成员).MSDN上的接口设计文章也断言了这个建议:
避免使用标记接口(没有成员的接口).
自定义属性提供了标记类型的方法.有关自定义属性的更多信息,请参阅编写自定义属性.如果可以在执行代码之前推迟检查属性,则首选自定义属性.如果您的方案需要编译时检查,则无法遵守此准则.
甚至还有一个FxCop规则来强制执行此建议:
避免空接口
接口定义提供行为或使用合同的成员.无论类型在继承层次结构中出现何种位置,接口描述的功能都可以采用任何类型.类型通过为接口的成员提供实现来实现接口.空接口不定义任何成员,因此,不定义可以实现的合同.
如果您的设计包含期望实现类型的空接口,则可能使用接口作为标记,或者标识一组类型的方法.如果此标识将在运行时发生,则完成此操作的正确方法是使用自定义属性.使用属性的存在或不存在或属性的属性来标识目标类型.如果标识必须在编译时进行,则可以使用空接口.
本文仅说明了您可能忽略警告的一个原因:何时需要对类型进行编译时识别.(这与界面设计文章一致).
如果在编译时使用接口标识一组类型,则可以安全地从此规则中排除警告.
实际问题是:Microsoft在框架类库的设计中(至少在几种情况下)不符合他们自己的建议:IRequiresSessionState接口和IReadOnlySessionState接口.ASP.NET框架使用这些接口来检查它是否应该为特定处理程序启用会话状态.显然,它不用于类型的编译时识别.他们为什么不这样做?我可以想到两个潜在的原因:
微优化:检查对象是否实现接口(obj is IReadOnlySessionState)比使用反射检查属性(type.IsDefined(typeof(SessionStateAttribute), true))更快.大多数时候差异可以忽略不计,但它实际上可能对ASP.NET运行时中的性能关键代码路径很重要.但是,他们可以使用的解决方法就像为每个处理程序类型缓存结果一样.有趣的是,ASMX Web服务(具有类似性能特征)实际上使用EnableSession属性的WebMethod属性来实现此目的.
与使用第三方.NET语言的属性装饰类型相比,可能更有可能支持实现接口.由于ASP.NET被设计为与语言无关,并且ASP.NET 根据指令的属性为类型(可能在CodeDom的帮助下以第三方语言生成)生成代码,因此可能会生成更多感觉使用接口而不是属性.EnableSessionState<%@ Page %>
使用标记接口而不是属性的有说服力的原因是什么?
这只是一个(过早?)优化还是框架设计中的一个小错误?(他们认为反射是"红眼睛的大怪物"吗?)思想?
在Java中实现多重继承我们使用接口.它是接口的唯一用途吗?如果是,Java中接口的主要用途是什么?为什么我们需要Java中的接口?
Java中是否有类似于Callable接口的接口,它可以接受其调用方法的参数?
像这样:
public interface MyCallable<V> {
V call(String s) throws Exception;
}
Run Code Online (Sandbox Code Playgroud)
如果已经存在我可以使用的东西,我宁愿避免创建新类型.或者是否有更好的策略让多个客户端实现并插入可调用的例程?
我有以下实现,给出了编译器错误:
public enum FusionStat implements MonsterStatBuilderHelper {
ATTACK {
@Override
public MonsterCard.MonsterCardBuilder safeCreateBuilder(final MonsterCard baseMonsterCard, final MonsterCard fusedMonsterCard, final FusionCard fusionCard) {
Objects.requireNonNull(baseMonsterCard);
Objects.requireNonNull(fusedMonsterCard);
Objects.requireNonNull(fusionCard);
if (baseMonsterCard.equals(fusedMonsterCard)) {
throw new IllegalArgumentException("baseMonsterCard and fusedMonsterCard need to be different");
}
return new MonsterCard.MonsterCardBuilder(baseMonsterCard)
.attack(baseMonsterCard.getAttack() + (fusionCard.getFusionPower() * fusedMonsterCard.getAttack()));
}
},
HITPOINTS {
@Override
public MonsterCard.MonsterCardBuilder safeCreateBuilder(final MonsterCard baseMonsterCard, final MonsterCard fusedMonsterCard, final FusionCard fusionCard) {
Objects.requireNonNull(baseMonsterCard);
Objects.requireNonNull(fusedMonsterCard);
Objects.requireNonNull(fusionCard);
if (baseMonsterCard.equals(fusedMonsterCard)) {
throw new IllegalArgumentException("baseMonsterCard and fusedMonsterCard need to be different");
}
return …Run Code Online (Sandbox Code Playgroud) 随着 Kotlin1.5的推出sealed interface,. 即使我知道类和接口之间的区别,我也不清楚使用sealed interfaceover的最佳实践和好处是什么sealed class
interface即使是简单的情况,我是否应该始终使用now ?还是将视具体情况而定?
谢谢
Obs:没有发现类似的问题,只是关于sealed classes
假设我想定义一个代表远程服务调用的接口.现在,对远程服务的调用通常会返回一些内容,但也可能包含输入参数.假设实现类通常只实现一种服务方法.鉴于以上信息,以下是一个糟糕的设计(它感觉不太正确):
public interface IExecutesService<A,B>
{
public A executeService();
public A executeService(B inputParameter);
}
Run Code Online (Sandbox Code Playgroud)
现在,假设我使用一个使用输入参数执行远程服务的类来实现此接口:
public class ServiceA implements IExecutesService<String,String>
{
public String executeService()
{
//This service call should not be executed by this class
throw new IllegalStateException("This method should not be called for this class...blabla");
}
public String executeService(String inputParameter)
{
//execute some service
}
Run Code Online (Sandbox Code Playgroud)
关于上述问题我有两个问题:
IExecutesService<A,B>在您想要提供需要不同输入参数和接口方法的返回类型的子类的情况下,是否使用通用接口()?IExecutesService)下将我的服务执行者分组; 但是,实现类通常只实现其中一个方法,并且使用IllegalStateException感觉非常难看.此外,对于在IExecutesService<A,B>没有任何输入参数的情况下调用服务的实现类,B类型参数将是多余的.对于两个不同的服务调用来说,创建两个独立的接口似乎也是过度的.首先......对不起这篇文章.我知道stackoverflow上有很多帖子正在讨论多重继承.但我已经知道Java不支持多重继承,我知道使用接口应该是另一种选择.但我不明白并看到我的困境:
我必须对用Java编写的非常大且复杂的工具进行更改.在此工具中,有一个数据结构,它由许多不同的类对象构建,并具有链接的成员层次结构.无论如何...
Tagged具有多个方法的类,并根据对象的类返回一个对象标记.它需要成员和静态变量.XMLElement允许链接对象,最后生成一个XML文件.我还需要成员和静态变量.XMLElement,其中一些Tagged.好的,这不会起作用,因为它只能扩展一个类.我经常读到Java的所有内容都没问题,也没有必要进行多重继承.我相信,但我不知道接口应如何取代继承.
我真的不明白所以请有人解释我如何处理这个问题?
我正在从Java库中读取一些源代码,我在这里很困惑;
此代码来自jaxb库中的Document.java,而ContentVisitor是同一个包中的Interface,我们如何使用new关键字创建Interface实例?这不是非法的吗?
public final class Document {
.
.
private final ContentVisitor visitor = new ContentVisitor() {
public void onStartDocument() {
throw new IllegalStateException();
}
public void onEndDocument() {
out.endDocument();
}
public void onEndTag() {
out.endTag();
inscopeNamespace.popContext();
activeNamespaces = null;
}
}
Run Code Online (Sandbox Code Playgroud) 我倾向于支持显式接口实现而非隐式接口实现,因为我认为针对接口而不是针对实现进行编程通常是可取的,而且在处理Web服务时通常是必需的.
也就是说,我想知道为什么以下是非法的显式接口声明和合法的隐式接口:
interface IConnection
{
string ConnectionString { get; }
}
class Connection1 : IConnection
{
// private set is illegal, won't compile
string IConnection.ConnectionString { get; private set; }
}
class Connection2 : IConnection
{
// private set is legal now, it is not part of the interface
string ConnectionString { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)
我知道如何解决这个问题,因为同时拥有一个显式和隐式接口是合法的,而且我可以使隐式接口实现完全私有.
然而,我想知道这背后的原因.因为从技术上讲,内部编译的私有方法set_IConnection_ConnectionString不需要是接口的一部分,对吧?它可以被视为辅助setter,而不是接口的一部分,因为它处于隐式实现情况中.
更新:作为奖励,看似令人困惑,在我看来不太正确的编译错误,您收到的是以下内容:
访问者的可访问性修饰符必须比属性Connection1.ConnectionString更具限制性
请问,更严格的比private,怎么......什么?
我有片段ListView,比方说MyListFragment和自定义CursorAdapter.我onClickListener在此适配器中设置列表行中的按钮.
public class MyListAdapter extends CursorAdapter {
public interface AdapterInterface {
public void buttonPressed();
}
...
@Override
public void bindView(final View view, final Context context, final Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
...
holder.button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// some action
// need to notify MyListFragment
}
});
}
}
public MyListFragment extends Fragment implements AdapterInterface {
@Override
public void buttonPressed() {
// some action
} …Run Code Online (Sandbox Code Playgroud) interface ×10
java ×7
inheritance ×2
.net ×1
android ×1
asp.net ×1
attributes ×1
c# ×1
enums ×1
kotlin ×1
sealed-class ×1