前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >接口和抽象有什么区别?

接口和抽象有什么区别?

作者头像
王小明_HIT
发布2020-06-23 14:40:49
3570
发布2020-06-23 14:40:49
举报
文章被收录于专栏:程序员奇点程序员奇点

接口和抽象有什么区别?

接口和抽象是 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. 使用时机:当想要支持多重继承,或是为了定义一种类型请使用接口;

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

代码语言:javascript
复制
public class ArrayLis<E> extends AbsractLis<E> implements Lis<E>, RandomAccess, Cloneable, java.io.Serializable
{
      //...
}

抽象的极限性

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

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

面向对象设计

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

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

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

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

面向对象设计原则

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

依赖反转

开闭原则改造如下代码:

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

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

代码语言:javascript
复制
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
         }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接口和抽象有什么区别?
    • 接口和抽象区别
      • 抽象的极限性
        • 面向对象设计
          • 面向对象设计原则
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档