我可以将实现类的引用用于java接口中声明的方法吗
我见过一些类的设计方式,其中接口具有方法声明,该方法具有其子类类型(实现类)的参数,如下所示: 接口A定义为具有方法setData,该方法具有AAbstract类型的参数,该参数是实现接口A的具体类AImpl的子类:我可以将实现类的引用用于java接口中声明的方法吗,java,interface,Java,Interface,我见过一些类的设计方式,其中接口具有方法声明,该方法具有其子类类型(实现类)的参数,如下所示: 接口A定义为具有方法setData,该方法具有AAbstract类型的参数,该参数是实现接口A的具体类AImpl的子类: public interface A{ void setData(AAbstract ref); } 我们有实现类AImpl: public class AImpl implements A { private AAbstract in
public interface A{
void setData(AAbstract ref);
}
我们有实现类AImpl:
public class AImpl implements A {
private AAbstract instance;
public void setData(AAbstract ref) {
this.instance= ref;
}
}
还有抽象的实现,比如:
public abstract class AAbstract extends AImpl {
public abstract void dummy(String msg);
}
就我个人而言,我不认为这是正确的设计,我想从设计角度了解专家的意见 这种模式的最大问题是耦合-类
AImpl
和抽象类AAbstract
是紧密耦合和循环依赖的。继承层次结构中的每个级别都知道其他级别,因此其中一个级别的更改影响其他级别的可能性非常大。通常,您会尝试设计不依赖或不了解孩子的类。也有例外,一个类的实现数量是预先知道的,并且通常不会改变,但很少。在这种情况下,AAbstract
和AImpl
之间的循环依赖关系表明,它们也可以组合成一个类
老实说,我不知道这种模式会带来什么价值
AImpl
包含AAbstract
的一个实例,它扩展了AImpl
,因此也包含AAbstract
的一个实例。。。那么它是不是一直在下降?我的猜测是,在某种程度上有一个null,没有人喜欢null。答案就是使用更具描述性的实现名称
AImpl
和AAbstract
表明您正在为单个实现创建接口。在这种情况下,YAGNI适用,不需要抽象。抽象允许控制反转,允许您指定不同类型的A
。如果只有一个实现,那么抽象就毫无用处了。当然,这在理论上很简单,因为人们创建抽象以便于在测试中模仿
抽象允许不同的实现。如果您使用AImpl
,您会如何命名其他实现
您可以改为使用ADefault
,这表明它是一个默认实现(如果其他实现不适合,请使用默认实现),但这仍然是您指定的问题,只是稍微淡化了一点
问问自己:“如果我有多个实现,它们之间的区别是什么?为什么我需要多个实现?”。这将帮助您为每个实现找到更具描述性的名称,允许您命名抽象a
,然后根据存在的原因定义不同类型的a
举一个使用
A
的例子,我相信我可以很容易地为实现找到更好的名称。例如,Graphics
是一种抽象,OpenGL
和DirectX
是实现。这两种实现都有不同的用途,并以它们的名称进行了描述。AAbstract没有任何问题。您还没有说明为什么它可能是一个糟糕的设计选择。总的来说,我认为它没有什么问题。@markspace我可以看到一个问题Animal
是一个抽象概念,但似乎不需要说AbstractAnimal
。因此,“我们什么时候应该使用匈牙利符号?”这个问题突然出现,描述了一个一致性问题。许多专业人士确实使用了它,但许多专业人士在意识到这是一个“十亿美元的错误”之前使用了null
。糟糕的设计选择是不一致的。它允许你这样做,这实际上鼓励了脱钩。它类似于Graphics
类作为接口的方式。一些人建议使用IGraphics
,但另一些人建议使用更具描述性的名称implementations@VinceEmigh这里与Graphics
类有一个显著的区别-接口a
取决于它的实现者AAbstract
,它本身就是一个具体类的扩展。这不完全是教科书的合同设计。因此,您将拥有一个仅依赖于其他接口的接口。Graphics
的接口纯粹是根据原语和其他高级抽象来描述的。接口是抽象:您将所需的行为抽象到接口中。抽象是接口(契约),但允许您提供impl之间的公共属性,从而减少干冲突。正如您所说,AAbstract
是impl的一个扩展(它抽象了impl的细节),但是它抽象了哪些具体细节<代码>A摘要未对其进行描述。它表明只有一个抽象的实现,表明实际的接口只是为了便于模拟和强制设计。(在下一篇评论中继续举例)想象一下DirectX
和OpenGL
版本控制。它们都需要抽象不同的属性,可以定义为抽象类DirextX
,其中DirectX14
是实际的implAAbstract
没有为我们提供足够的关于impl被抽象的信息,这使得它成为一个糟糕的命名选择。这不是教科书上的博士,但想法非常相似。创建这些设计是为了帮助解决问题,如果它们是被迫的(没有实际问题需要解决),它们会产生更多的问题,例如命名。这只是基于我的经验,所以如果我错了,请纠正我。这不是好的合同设计。命名是一个问题的原因是对象设计不完美——这与我关于耦合的观点基本相同。如果我有什么事