Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用具有不同方法名称的子类而不违反实体原则_Java_Oop_Design Patterns_Polymorphism_Mixins - Fatal编程技术网

Java 使用具有不同方法名称的子类而不违反实体原则

Java 使用具有不同方法名称的子类而不违反实体原则,java,oop,design-patterns,polymorphism,mixins,Java,Oop,Design Patterns,Polymorphism,Mixins,//接口 public interface Singer{ void sing(); } public interface SongWriter{ void writeSong(); } //实现 public class PureSinger implements Singer{ void sing(){} } public class SingerSongWriter implements Singer, SongWriter{ void sing(){}

//接口

public interface Singer{
    void sing();
}
public interface SongWriter{
    void writeSong();
}
//实现

public class PureSinger implements Singer{
    void sing(){}
}
public class SingerSongWriter implements Singer, SongWriter{
    void sing(){}
    void writeSong(){}
}
//客户端代码

void methodA(){
    Singer objPureSinger = new PureSinger();
    Singer objSingerSWer = new SingerSongWriter();

    doSomething(objPureSinger);
    doSomething(objSingerSWer);
}

public void doSomething(Singer obj){
    obj.sing();
    obj.writeSong();    //<--- this does not work.
}
void methodA(){
Singer objPureSinger=新的PureSinger();
Singer objSingerSWer=新歌手SongWriter();
doSomething(objPureSinger);
doSomething(objSingerSWer);
}
公共无效剂量测定(Singer obj){
obj.sing();

obj.writeSong();//您不应该假设在doSomething()中使用.writeSong(),因为您以Singer的身份传递参数,我们知道Singer只有一个名为.sing()的方法。下面是一些选项

<> LI>您应该考虑在业务逻辑意义上实际做什么(可能),也许我们可以去掉调用.WrreSeNe(),因为传入的参数并不总是可以向歌曲编写者浇铸。
  • 考虑使用基类(例如抽象类或具体类)实现Singer和SongWriter,将其作为参数数据类型传入
  • 如果您正在寻找一个快速修复程序来运行代码,请参阅下面的内容
  • 快速修复: 您首先需要查看obj是否是SongWriter的实例,因为传入的参数类型为Singer,而Singer没有名为.writeSong()的方法

    public void doSomething(Singer obj){
    obj.sing();
    
    //obj.writeSong();//要快速回答问题
    doSomething
    调用
    sing()
    writeSong()
    方法。只有您的
    SingerSongWriter
    类同时定义了这两种方法,并且是唯一可以同时执行这两种方法的类。
    objPureSinger
    没有定义什么是
    writeSong
    ,因此调用时不知道该做什么


    如果你想保持这种结构,你可以在两个类中都实现一个名为
    do
    的方法。在
    PureSinger
    类中,
    do
    只需调用
    sing()
    ,但在
    SingerSongWriter
    类中它同时调用
    sing()
    writeSong())
    。最后,在您的
    doSomething
    方法中,只需调用
    obj.do();

    您就可以根据业务需要设计类。而且,很明显,在

    public void doSomething(Singer obj){
        obj.sing();
        obj.writeSong();    //<--- compiler will complain here
    }
    
    因为只有歌手SongWriter才能同时执行这两项操作

    为了实现这类代码,我应该如何设计类结构

    首先定义一个名为
    Artist
    接口
    ,该接口有一个名为
    perform
    的方法。接下来,定义两个子类,即
    Singer
    SongWriter
    ,每个子类实现
    perform
    ,并包含分别用于唱歌和写歌的代码

    以下两种设计模式将非常好地支持您的用例:

  • 设计模式:在你的例子中,
    Artist
    是组件,
    Singer
    SongWriter
    是具体的组件,
    ArtistDecorator
    是你的抽象装饰类。使用
    ArtistDecorator
    歌手
    包装成
    歌曲作者
    doSomething
    方法od接受一个
    Artist
    参数,并传递最终装饰的
    Artist
    对象,该对象将
    歌手
    包装成
    歌曲作者
  • 设计模式:在您的案例中,
    Arist
    是组件。
    compositeratist
    是复合的,
    Singer
    SongWriter
    是叶子或具体的组件类。
    doSomething
    方法采用
    Artist
    参数。将
    compositeratist的实例传递给它ode>(它是一个
    Artist
    )和
    doSomething
    只是调用
    perform
    ,它在内部逐个迭代调用其
    perform
    方法的所有
    Artist
    实例

  • 目标是用一个基本接口/抽象类对象控制PureSinger和SingerSongWriter对象。根据您的设计,您应该使用
    SingerSongWriter
    作为
    doSomething()
    的参数,您希望
    doSomething(objPureSinger);
    做什么?这样,我就不能将objPureSinger传递给doSomething()@再次重申,OP不希望歌手写歌。相反,OP希望歌手唱歌,写歌人写歌。他还希望歌手写歌,写歌人可以唱歌和写歌。这项功能需要使用单一界面来支持,而不必真正担心
    doSomething
    传递给它的具体类型。我同意
    Singer
    接口名称令人困惑,可以将其重命名为
    Artist
    ,并且
    doSomething
    可以作为
    Artist
    的参考。希望这能澄清问题。(我已经在回答中介绍了解决方案)将来可能会添加新接口或新Singer的具体类,因此“if(obj instanceOf)…”违反实体的OCP。我需要一个实现OCP的设计。因此您有两个选项。第一个选项是创建一个基类来实现这两个方法,并将其作为参数数据类型传递。另一个选项是不调用.writeSong()在doSomething()方法中(重新访问您的业务需求)。我认为这违反了SOLID的LSP。纯歌手不写任何歌曲。如果你想让dosomething方法对两个人都有效,试试新的建议,它只是在两个类中都添加了一个名为相同的方法。@Federicoperaltachafner关于复合模式不适合这里的评论:在复合模式的情况下e
    CompositeAritst
    将在数组/列表中包含一个
    Singer
    实例和一个
    SongWriter
    实例。这将共同构成一个歌手-歌曲作者的合成。你能详细说明你所说的没有合成,只有单叶对象吗?嗯……我的意思是合成是我们的一种模式
    public void doSomething(Singer obj){
        obj.sing();
        obj.writeSong();    //<--- compiler will complain here
    }
    
    doSomething (SingerSongWriter obj)