【问题标题】:Java: Interface vs Abstract Class (regarding fields)Java:接口与抽象类(关于字段)
【发布时间】:2010-10-02 12:13:38
【问题描述】:

根据我收集到的信息,我想强制一个类使用特定的私有字段(和方法)我需要一个抽象类,因为接口只声明公共/静态/最终字段和方法。对吗??

我刚开始我的第一个大型 java 项目,想确保以后不会伤害自己 :)

【问题讨论】:

  • 接口中的最终字段/方法除外,这是正确的。

标签: java interface accessibility abstract-class field


【解决方案1】:

这是正确的。但这不一定是一个非此即彼的决定,您可以通过提供一个骨架实现以及您的接口来结合接口和抽象类的优点。您可以在 Effective Java, 2nd Ed. 第 18 条(“Prefer interfaces to abstract classes”)中找到对这种方法的非常有趣的描述。

【讨论】:

    【解决方案2】:

    子类不能使用私有字段和方法(除非它们也是内部类)。但是,您可以让它们受到保护。

    【讨论】:

      【解决方案3】:

      没错。接口供公众使用。私有实现需要在抽象(或具体)类中。

      【讨论】:

        【解决方案4】:

        如果您发现自己在猜测该选择哪一个,我建议您在接口方面犯错 - 最好有一个应该是抽象类的接口,而不是相反。

        【讨论】:

          【解决方案5】:

          您不想强制使用某些私有字段或方法。一般来说,你不关心实现,你关心的是接口。所以在几个接口中定义几个方法(取决于你需要多少)并定义实现它们的类。将来这可能对您的伤害最小。

          【讨论】:

          • +1 我很惊讶这个问题有这么多字面上的答案,而你是唯一一个解决问题背后的错误假设的人。
          【解决方案6】:

          接口仅定义了这一点 - 与实现类之外的世界的接口(合同)。 (抽象与否)超类的公共方法也是如此。您不应该尝试要求子类具有某些私有成员 - 您正在尝试指定实现,而这正是 OOP 所要避免的。

          当您想在超类中定义一些共享行为时,您可以使用抽象类 - 但该类不能独立存在(它需要被子类化)。可能是共享行为需要自己的某种状态 - 在这种情况下,它可以定义私有字段,并且它也可能具有只有它才能使用的私有方法。

          即使您从抽象类继承,也无法访问其私有字段/方法。

          【讨论】:

            【解决方案7】:

            接口为行为定义了一个契约。这就是他们需要关注的内容,而不是属性。

            【讨论】:

              【解决方案8】:

              如果你想让子类定义特定的方法,使用接口就可以了。正如其他人所说,与其说是如何子类做到这一点,不如说是它做到这一点。

              【讨论】:

                【解决方案9】:

                两者都提供是很常见的,因此您最终会得到:

                public interface Sendable {
                    public void sendMe();
                }
                

                public abstract class AbstractSender implements Sendable {
                    public abstract void send();
                
                    public void sendMe() {
                        send(this.toString());
                    }
                }
                

                这样,任何对抽象类中的默认实现感到满意的人都可以快速对其进行子类化,而无需重写大量代码,但任何需要做更复杂事情的人(或者需要从不同的基类继承)仍然可以实现接口,即插即用。

                【讨论】:

                • 你不希望 AbstractSender 实现可发送。
                • 是的。已更正。真的,我想要一个不那么做作的例子,但没有立即想到。
                • docs.oracle.com/javase/tutorial/java/IandI/abstract.html -- “如果一个类包含抽象方法,则该类本身必须声明为抽象。”你的代码真的可以编译吗?
                【解决方案10】:
                我想强制一个类使用特定的私有字段(和方法)

                你的这部分问题是有问题的:你认为你为什么要这样做?

                私有成员对子类不可见,而接口定义了公共接口,因此您唯一的选择是使用抽象类...但我想不出任何人想要这样做的任何理由

                【讨论】:

                  【解决方案11】:

                  如果您希望一个类使用另一个类的某些字段或方法,您可以将它们声明为受保护。

                      public abstract class A {
                  
                        protected Object thing;
                      }
                  

                  可以被同一个包中的另一个类访问(可以是A类,也可以不是)

                  A a = new A();
                  a.thing.toString();
                  

                  这并不是真的“强迫”另一个类使用它,更像是“启用”。

                  【讨论】:

                    猜你喜欢
                    • 2015-06-27
                    • 1970-01-01
                    • 2017-02-19
                    • 2016-03-24
                    • 2010-12-01
                    • 1970-01-01
                    • 2020-08-01
                    • 2021-12-11
                    相关资源
                    最近更新 更多