【问题标题】:Abstract method vs Interface method抽象方法与接口方法
【发布时间】:2013-07-21 18:13:33
【问题描述】:

已经被问了 100 次,但他们都有不同的答案。所以我才敢再次提出这个问题。 为什么我们不能把所有的抽象方法都移到接口上?

我知道有模板模式可以使用抽象方法来实现,但是它也可以使用接口来完成,那么为什么要抽象方法呢。 今天我正在阅读有关此内容并试图找到答案。

提前致谢。

【问题讨论】:

    标签: oop inheritance abstraction ooad


    【解决方案1】:

    这是模板方法模式的一个例子。用抽象类制作的模板,带有一些 final 方法(你不想改变的逻辑)和抽象方法(被实现覆盖)

    public abstract class HtmlTemplate {
    
        /**
         * Get html code.
         * Its final, so nobody can override.
         * @return Html code.
         */
        public final String getHtml() {
            String html = "<html>"
                    + "<head>"
                    + getHead() // abstract method
                    + "</head>"
                    + "<body>"
                    + getBody() // abstract method
                    + "</body>"
                    + "</html>";
            return html;
    
        }
    
        /**
         * Get head implementation.
         * @return head code
         */
        protected abstract String getHead();
    
        /**
         * Get body implementation.
         * @return body code
         */
        protected abstract String getBody() ;
    }
    
    public class MyHtmlPageImpl extends HtmlTemplate {
    
        @Override
        protected String getHead() {
            return "<title>My page</title>";
        }
    
        @Override
        protected String getBody() {
            return "Hello world";
        }
    }
    

    【讨论】:

      【解决方案2】:

      我假设您已经知道这一点,但是接口要求实现者覆盖每个方法。抽象类没有。这很有用的原因是因为您可能希望为扩展该抽象类的所有类提供一个方法实现。

      一个简单的例子可能是一个 Person 类

      abstract class Person{
      
      public void pumpBlood(){
      //do blood pumping stuff 
      }
      
      public void talk(); 
      public void getDressed(Clothes someClothes); 
      }
      

      所有人都应该(理论上)以相同的方式抽血,但并非所有人都应该以同样的方式穿衣或说话。抽象类适用于这种可以提供具体方法的情况。

      【讨论】:

      • 谢谢布拉德,我的问题更多是关于抽象的“方法”。它没有在抽象类中实现,所以为什么不将它移到接口中。也被称为接口程序。将所有抽象“方法”移动到接口并将通用逻辑保留在基类或抽象类中似乎不正确。
      • 当时误会你了。
      【解决方案3】:

      接口定义了一个对象的public契约。在使用模板模式时,我经常使用受保护的(在 Java 中)抽象方法,因为我不希望外部调用者能够调用该方法。

      在某些情况下,您可能不需要接口。如果你有类似的东西怎么办

      abstract class MyClass {
           someConreteMethod() { ... }
           abstract someAbstractMethod();
      }
      

      也许您只希望 MyClass 的实现来扩展抽象 MyClass

      一般来说,我不经常使用 public 抽象方法,但使用非公共方法更为常见。

      【讨论】:

      • 感谢模板示例,这很有意义。但是在第二个示例中,我可以只为公共逻辑 someconcretemethod() 提供一个基类,并为 someabstractmethod 编写一个接口(如果它是公共的)。那么公共抽象方法应该去接口吗?似乎大多数时候基类应该是抽象的。
      • 一个接口有一个意义——你希望能够通过那个接口引用一个对象。如果您不想拥有多个不扩展MyClass 的实现,那么接口就没有意义。有时这只是一个判断电话。
      猜你喜欢
      • 2013-01-19
      • 2011-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多