基于Java面向对象编程(OOP)的程序流程

4
我正在学习基础Java知识,从《Head First Java》中阅读基本概念(多态性、抽象类/方法、覆盖等)。现在我正在做一个非常简单的例子,在其中使用遥控器来控制电视、家庭影院和CD播放器。一个遥控器必须完美地适用于所有3个设备。现在我所做的是...
  • Remote是这三个类(电视、家庭影院、CD播放器)的超类。
  • 基本功能如开关、音量+/-、频道+/-等都在超类中被覆盖。
  • 那些不常见的方法被实现在接口中,例如插入、弹出CD播放器,电视和家庭影院的显示设置等。

    所以这种方法可以吗?

将一个类作为超类,然后在接口中实现其余代码。

另外一个问题是,如果在电视和家庭影院中有一个共同的方法(例如显示设置),我应该实现接口还是更改我的类层次结构?

请不要介意这个愚蠢的问题,并指导我这些面向对象设计技术,谢谢。


这是关于编程的内容,请将其翻译成中文。请仅返回已翻译的文本:这只是一个演示,不是原始遥控器...只需尝试理解,我将使用布尔值输入开/关状态,使用+、-调节音量等,从BufferedReader等获取输入...不要认为我正在为某个原始遥控器编写代码,它必须在控制台上显示输入和输出...就这样。 - Sikander
3
遥控器怎么成为电视的超类?电视是遥控器的一种特殊类型吗?:P - Patashu
1
哦,我明白了,把现实生活抽象化,太棒了。 - argentum47
1
我认为我说/打得很好。 - argentum47
是的,刚刚看到了.. :) - Siddharth
显示剩余2条评论
5个回答

7
在实现继承(父类-子类逻辑)之前,请始终进行“Is-A”测试。例如,“电视机是遥控器吗?”,显然不是,因此你的方法是错误的。在我看来,这应该使用接口。电视机必须实现而不是扩展遥控器。这并不意味着每当有公共代码时,都要使用继承来避免重复。
基本功能,如打开、关闭、音量+-、频道+-等必须在遥控器接口中,所有其他类,如电视机等,必须实现它们。
public Class TV implements Remote

如果您想使用继承,可以创建一个名为ElectronicGadget的父类。您所有的电视、家庭影院和CD播放器都是电子设备。您可以有共同的方法,例如

public boolean turnOn()
public boolean turnOff()

在IT领域。


还有一件事,我可以在远程接口中实现所有通用的方法,对于那些不通用的方法,我应该在这些类中定义这些方法还是定义单独的接口?谢谢。 - Sikander
1
它不是那样工作的。它还必须有意义。例如,如果您想要维护您订阅的频道,则像addChannel()或removeChannel()这样的函数在Remote接口中将没有意义...您需要定义一个新接口,比如CableConnection。现在,即使您想在计算机上观看频道,您只需说计算机实现CableConnection即可。 - Aniket Thakur
我会说“implements RemoteControllable”或类似的东西,而不是“implements Remote”,但这个想法是正确的。 - Patashu

3

电视、家庭影院和CD播放机显然不是遥控器的一种。它们确实可以被遥控。这提示我们应该有一个名为Remotable的接口,并由设备来实现。

interface Remotable {
    void turnOff();
    void turnOn();
    void volumeUp();
    void volumeDown();
    void selftDestruct();
}

然后我们使所有设备实现这个接口。

class Television implements Remotable {

    @Override
    void turnOff() {
        System.out.println("Television is turned off");
    }

    //implements the rest.
}

class HomeTheater implements Remotable {
    // implements likes Television
}

class CDPlayer implements Remotable {
}

然后创建了一个 Remote 类来处理可远程控制的设备。

class Remote  {
    private Remotable target;

    public Remote(Remotable target) {
        this.target = target;
    }

    public void turnOn() {
        target.turnOn();
    }
}

并将所有东西组合在一起,我们会得到类似这样的内容:
Television tv = new Television();
Remote remote = new Remote(tv);
remote.turnOn();

请解释一下 Remote {} 这个类。谢谢。 - Sikander
2
Remote 类只是一个远程控制器。它只知道如何与 Remotable 对象一起工作,不关心这个对象是 TelevisionHomeTheater 还是 CDPlayer - Genzer
那澄清了这个想法。 - Sikander
所以我读了三遍,这是完美的答案。 - Sikander

2

除了已经说过的内容,你可能会有一个名为RemoteControl的抽象类。在这个类中,您实现常见的方法。如果您想要一个电视遥控器,您可以实现一个名为TvRemoteControl的类,它扩展自RemoteControl。这样,您就是在说TvRemoteControl Is-A RemoteControl。

在此基础上,您可以将RemoteControl添加到TV对象中。

这样做有意义吗?


是的,你可以给一个TV对象添加一个RemoteControl控制器。这句话的意思是什么? - Sikander
1
我的意思是,如果你有一个名为TV的类,你可以给它添加一个RemoteControl属性。public class TV implement Remotable {private RemoteControl remote = new TvRemoteControl();} - docDevil
这正是我所想的。它很干净。 - argentum47

1
根据我的理解,当您提到 Remote 是超类时,它适用于所有远程类型(如电视、CD 播放器等)。
遥控器的行为因设备而异。因此,RemoteControl 可能是一个接口,具有一组方法。所有实现类都会有自己的风格。
注意:建议添加更有意义的类/接口名称。我不喜欢 Remote,因为它也可能意味着 JDK 的 java.rmi.Remote。
还有一件事:如果您认为代码可重用于所有子类或者当它们执行 super 时,请将代码添加到超类中。
class Super
{
   public void method1()
   {
   }
}

class Sub extends Super
{
   public void method1()
   {
      super.method1();
      //Add more behavior specific to Sub
   }
}

您的解决方案是“真正的解决方案”,在此方案中,远程和电视都连接到本地网络,但他只是在学习Java基础知识,所以我认为这仅仅是一个面向对象的示例。 - Khaled.K

1
坦白地说,你没有理解重点。重点在于变革,而不是正确使用面向对象编程。你认为将来会增加更多的设备吗?或者某个特定设备的功能会发生变化吗?
如果你正在为所有设备构建一个独特的遥控器,那么你将需要为这些设备制作不同类型的遥控器。而且每个设备可能/可能没有超过1个遥控器。因此,你不能继承遥控器属性,而是需要实现该设备基本所需的遥控器属性。遥控器本身将具有树形结构,相互继承。遥控器将继承诸如频道点击器、基本声音、高级声音、专业声音、视频儿童等功能。
现在,如果你正在构建通用遥控器,那么设备将会改变,你需要控制其他设备中的代码更改,同时添加新设备。因此,在遥控器运行时,你需要抽象出设备类型。对于不同的设备,遥控器的行为将不同。对于一些设备,遥控器将显示“不支持”。而对于一些设备,音量将每次上按键增加5db,而对于另一些设备,则是每次上按键增加50db。对于每个设备,遥控器参数都将不同。分贝单位,亮度单位。
你需要以不同的思维方式进行设计,考虑到未来的变化。随着未来代码的更改,你不需要重新测试所有设备和遥控器,因为更改将仅针对该设备进行本地化。你可以为每个设备拥有不同的小型库,这样即使你重新构建并运行测试,也不需要运行任何旧测试,因为你没有更改任何代码。
设计模式需要让你的思维面向未来的最小代码更改。
编辑: 还有,你问了一个好问题。我建议你再次阅读前三章,并多喝水。你已经非常接近了。不要放弃,不要更改你的示例,除非你理解了它。相信我,你离成功很近。

谢谢您,我一定会先读前三章,因为我非常决心完成它 :) - Sikander
反复阅读前三章,如果你掌握了前三章,那么后面的内容将轻而易举,相信我,你能够理解它。不要放弃。 - Siddharth
当然,我有实体副本,我现在就会阅读它们。 - Sikander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接