Java中的抽象类与接口

Java中的抽象类与接口,java,design-patterns,interface,abstract-class,Java,Design Patterns,Interface,Abstract Class,有人问我一个问题,我想在这里复习一下我的答案 Q:在哪种情况下,扩展抽象类比实现接口更合适 A:如果我们使用的是模板方法设计模式 我说得对吗 如果我不能把问题说清楚,我很抱歉。 我知道抽象类和接口之间的基本区别 1) 当我们需要为特定操作(实现方法)在每个子类中实现相同的功能,而为其他操作(仅方法签名)在每个子类中实现不同的功能时,请使用抽象类 2) 如果您需要将签名设置为相同(并且实现不同),则使用接口,这样您就可以遵守接口实现 3) 我们可以扩展最多一个抽象类,但可以实现多个接口 重申这个问

有人问我一个问题,我想在这里复习一下我的答案

Q:在哪种情况下,扩展抽象类比实现接口更合适

A:如果我们使用的是模板方法设计模式

我说得对吗

如果我不能把问题说清楚,我很抱歉。
我知道抽象类和接口之间的基本区别

1) 当我们需要为特定操作(实现方法)在每个子类中实现相同的功能,而为其他操作(仅方法签名)在每个子类中实现不同的功能时,请使用抽象类

2) 如果您需要将签名设置为相同(并且实现不同),则使用接口,这样您就可以遵守接口实现

3) 我们可以扩展最多一个抽象类,但可以实现多个接口

重申这个问题:除了上面提到的场景之外,还有其他场景需要使用抽象类吗(一个是请参见模板方法设计模式仅在概念上基于此)

接口与抽象类

在这两者之间做出选择实际上取决于你想做什么,但幸运的是,埃里希·伽马可以帮我们一点忙

正如总是有一个折衷办法一样,一个接口给了你关于基类的自由,一个抽象类给了你以后添加新方法的自由埃里希·伽马

如果不需要更改代码中的许多其他内容,就无法更改接口,因此避免这种情况的唯一方法是创建一个全新的接口,这可能并不总是一件好事


抽象类
应主要用于密切相关的对象<代码>接口更适合为不相关的类提供公共功能。

你说得不对。有很多种情况。不可能将其简化为一个8字规则。

当所有类都具有相同的结构但功能完全不同时,将使用接口

当所有类都具有相同的结构,但某些功能相同或不同时,将使用抽象类


看看这篇文章:

什么时候使用界面

接口允许某人从头开始实现您的接口,或使用其他代码实现您的接口,这些代码的原始或主要用途与您的接口完全不同。对他们来说,您的接口只是附带的,必须添加到他们的代码中才能使用您的包。缺点是接口中的每个方法都必须是公共的。你可能不想暴露一切

何时使用抽象类

相反,抽象类提供了更多的结构。它通常定义一些默认实现,并提供一些对完整实现有用的工具。问题是,使用它的代码必须使用您的类作为基。如果希望使用您的包的其他程序员已经独立开发了自己的类层次结构,那么这可能会非常不方便。在Java中,一个类只能从一个基类继承

何时同时使用两者


您可以提供两个方面的最佳选择,一个接口和一个抽象类。如果实现者愿意,他们可以忽略抽象类。这样做的唯一缺点是通过接口名调用方法比通过抽象类名调用方法要慢一些

最短的答案是,扩展抽象类,当uou seek的某些功能已经在其中实现时

如果实现接口,则必须实现所有方法。但对于抽象类,需要实现的方法数量可能会更少


在这种情况下,必须定义一种行为。此行为依赖于其他抽象方法。通过创建子类并定义这些方法,您实际上定义了主要行为。底层行为不能在接口中,因为接口没有定义任何东西,它只是声明。因此,模板设计模式总是附带一个抽象类。如果要保持行为流的完整性,必须扩展抽象类,但不要覆盖主行为。

抽象类在两个重要方面不同于接口

  • 它们为所选方法提供了默认实现(您的答案中包括了这一点)
  • 抽象类可以有状态(实例变量)——所以这是您希望使用它们代替接口的又一种情况

当您想要扩展一些常见行为时,应该扩展抽象类。抽象超类将具有公共行为,并将定义子类应实现的抽象方法/特定行为

接口允许您随时更改实现,使接口保持完整

重申问题:除此之外还有其他情况吗 上面提到,我们特别需要使用抽象类 (一个是请参见模板方法设计模式在概念上基于 (仅此)

是的,如果您使用JAXB。它不喜欢接口。您应该使用抽象类,或者使用泛型解决此限制

从个人博客:

界面:

  • 一个类可以实现多个接口
  • 接口根本不能提供任何代码
  • 接口只能定义公共静态最终常量
  • 接口不能定义实例变量
  • 添加新方法会对实现类产生连锁反应(设计维护)
  • JAXB无法处理interfa
    1) Trading system places orders
    2) Trading system receives acknowledgements
    
    public interface ITradeSystem{
    
         public void placeOrder(IOrder order);
         public void ackOrder(IOrder order);
    
    }
    
    public class StockTradeSystem implements ITradeSystem{    
    
        @Override 
        public void placeOrder(IOrder order);
             getMarket().place(order);
    
        @Override 
        public void ackOrder(IOrder order);
             System.out.println("Order received" + order);    
    
        private void connectToMarket();
           SocketChannel sock = Socket.open();
           sock.bind(marketAddress); 
           <LOTS MORE MESSY CODE>
        }
    
        public void findGoodDeals();
           deals = <apply magic wizardry>
           System.out.println("The best stocks to buy are: " + deals);
        }
    
    public abstract class ABCTradeSystem implements ITradeSystem{    
    
        public abstract void findGoodDeals();
    
        @Override 
        public void placeOrder(IOrder order);
             getMarket().place(order);
    
        @Override 
        public void ackOrder(IOrder order);
             System.out.println("Order received" + order);    
    
        private void connectToMarket();
           SocketChannel sock = Socket.open();
           sock.bind(marketAddress); 
           <LOTS MORE MESSY CODE>
        }
    
    public class StockTradeSystem extends ABCTradeSystem{    
    
        public void findGoodDeals();
           deals = <apply magic wizardry>
           System.out.println("The best stocks to buy are: " + deals);
        }
    
    public class CurrencyTradeSystem extends ABCTradeSystem{    
    
        public void findGoodDeals();
           ccys = <Genius stuff to find undervalued currencies>
           System.out.println("The best FX spot rates are: " + ccys);
        }