接口和抽象有什么区别?

简介: 接口和抽象有什么区别?

接口和抽象有什么区别?



接口和抽象是 Java 面向对象设计的两个基础机制。

接口是对行为的抽象,它是抽象方法的集合,利用接口可以达到API 定义和实现分离的目的

  • 接口不能实例化,
  • 接口不能包含任何非常量成员,任何 field 隐含 public field final的意义
  • 非静态方式实现,要么是抽象方法,要么是静态方法。

抽象类不能实例化,用 abstract 关键字修饰 class, 其主要目的是代码重用

  • 抽象类和普通 Java 类在形式上没有太大区别。可以有一个或者多个抽象方法,- 抽象类大多用于抽取 Java 类共用方法实现或者共同成员变量。然后通过继承的方式到达代码复用的目的。


接口和抽象区别


  • 接口 Java 类实现 interface 使用 implements 关键词
  • 继承 抽象类是使用 extends 关键词
  1. 支持多重继承:接口支持;抽象类不支持;类不支持;
  2. 支持抽象函数:接口语义上支持;抽象类支持;类不支持;
  3. 允许函数实现:接口不允许;抽象类支持;类允许;
  4. 允许实例化:接口不允许;抽象类不允许;类允许;
  5. 允许部分函数实现:接口不允许;抽象类允许;类不允许。
  6. 定义的内容:接口中只能包括public函数以及public static final常量;抽象类与类均无任何限制。
  7. 使用时机:当想要支持多重继承,或是为了定义一种类型请使用接口;

当打算提供带有部分实现的“模板”类,而将一些功能需要延迟实现请使用抽象类;当你打算提供完整的具体实现请使用类。


public class ArrayLis<E> extends AbsractLis<E> implements Lis<E>, RandomAccess, Cloneable, java.io.Serializable
{
      //...
}

抽象的极限性


Java 不支持多继承。Java 类可以实现多个接口,因为接口是抽象方法的集合,采用声明抽象方法的方式,但是并不能通过扩展多个抽象类来重用逻辑。

还有一些场景,需要抽象与具体实例化无关的通用逻辑,比如 Utils 类,但是如果采用抽象类,这样就存在单继承的问题。


面向对象设计


面向对象的基本要素:封装,继承,多态。

  • 封装的目的是隐藏事务内部的实现细节,以便提高安全性和简化编程。封装提供了合理边界,避免外部调用者接触内部细节。比如,多线程编程是,暴露内部状态,冗余导致并发修改的问题。
  • 继承是代码复用的基础机制,继承是一种紧耦合的关系,父类代码修改,子类行为会跟着变动。如果过度滥用,会起到不好的效果。
  • 多态,说到多态,会立即想到重写(override) 和重载 (overload),向上转型。
  1. 重写是父子类中相同名字和参数的方法,不同的实现。
  2. 重载是相同名字方法,但是不同的参数。

要注意的是 方法名称和参数一致,但是返回值不同,这样不是重载,编译会报错!!


public int doSomething() {
    return 0;
}
// 输入参数不同,意味着方法签名不同,重载的体现
public int doSomething(Lis<String> srs) {
  return 0;
}
// return类型不一样,编译不能通过
public short doSomething() {
   return 0;
}


面向对象设计原则


  • 单一职责原则 , 类或者对象最好是单一职责,如果发现某个类中承担着多种义务,可以考虑拆分重构。
  • 开闭原则,对扩展是开放的,但是对修改是关闭的。程序设计应保证平滑的扩展性,尽量避免因为新增同类功能而修改已实现。这样可以减少回归问题。(回归测试)。
  • 里式转换原则, 进程继承抽象时,凡是可以用父类或者基类的地方,都可以用子类转换。简单的说,子类对象可以赋给父类对象,但父类对象不能赋值给子类对象。
  • 接口分离原则,在进行类和接口设计时,如果在一个接口中定义了太多方法,子类可能只需要实现其中部分方法,这样就破坏了程序的内聚性,可采用接口分离方式,进行解耦。这样实现了高内聚,低耦合。
  • 依赖反转,实体应该依赖于抽象而不是实现。也就是说,高层次模块,不应该依赖低层次模块。而是基于抽象接口。抽象接口不应该依赖具体,而具体要依赖于抽象。


interface Coder {
        void wearSweater(Sweater sweater);
  }
  class XiaoMing implements Coder{
      @Override
      public void wearSweater(Sweater sweater) {
      }
  }
  interface Sweater {
  }
  class TneckSweater implements Sweater {
  }
Coder xiaoming = new XiaoMing();
Sweater tneckSweater = new TneckSweater();
xiaoming.wearSweater(tneckSweater);


640.png


开闭原则改造如下代码:


public class VIPCenter {
    void serviceVIP(T extend User user>) {
        if (user insanceof SlumDogVIP) {
            // 穷X VIP,活动抢的那种
            // do somthing
         } else if(user insanceof RealVIP) {
           // do somthing
        }
        // ...
}

修改关闭,扩展开放的原则:


public class VIPCenter {
    private Map<User.TYPE, ServiceProvider> providers;
       void serviceVIP(T extend User user) {
          providers.get(user.getType()).service(user);
       }
}
interface ServiceProvider{
       void service(T extend User user) ;
}
class SlumDogVIPServiceProvider implements ServiceProvider{
        void service(T extend User user){
              // do somthing
        }
}
class RealVIPServiceProvider implements ServiceProvider{
        void service(T extend User user) {
             // do something
         }
}


相关文章
|
1月前
抽象和封装
抽象和封装
14 0
|
7月前
|
7月前
|
设计模式 数据安全/隐私保护
面向对象编程基础:封装、继承、多态与抽象的全面解析
面向对象编程基础:封装、继承、多态与抽象的全面解析
30 0
|
9月前
|
索引
接口和类有什么异同
接口和类有什么异同
|
9月前
|
C# 索引
C#中接口和类有什么异同
C#中接口和类有什么异同
|
11月前
|
Java
10 抽象与封装
10 抽象与封装
55 0
普通类,抽象类和接口之间的区别
普通类,抽象类和接口之间的区别
接口vs抽象类、继承vs组合,他们之间有啥关系
接口vs抽象类、继承vs组合,他们之间有啥关系
|
Java
抽象类和接口的区别(通俗易理解)
抽象类和接口的区别(通俗易理解)
476 0
系统认知Java接口、接口与继承、接口与多态
在面向对象的基础之上,接口的出现是类性质的一种完善,是继承机制的一种补充,是体现多态性的一种形式。从生活实际出发,接口把它之下一系列复杂的逻辑,功能等通过“实现接口”的方式封装简化出来,只通过连接一个小小的口子就轻而易举地实现了背后实则很复杂的功能。我想这就是接口存在的意义所在吧。
150 0
系统认知Java接口、接口与继承、接口与多态