接口与抽象类的区别和存在意义

接口 抽象类 的区别在面试中问的比较广泛,同时也是开发者必须要明白的基础性知识,下面就来捋一下:

1.从 特征上比较
(1)接口可被类实现(implement),也可以被接口扩展继承(extends),抽象类只能被子类继承(extends)。
(2)接口只能有方法声明不可变常量
    方法声明:会被自动设置为public abstract,接口中方法平时会省略掉public,但是实现方法必须显示声明public
    不可变常量:定义的变量只能是公共的静态的常量,域变量会被自动设置为public static final

/**
 * 菜单接口
 */
public interface MenuService {         //接口名 补全public

  int defaultTotal=33;                       //1.1:一般写法
  public static final int defaultTotal2=40;  //1.2:常量补全public static final,和上面类型相同

  Double getFoodTotal(String restaurantName);       //2.1:一般写法
  abstract Double getFoodPrice(String foodName);    //2.2:方法声明补全抽象方法关键词abstract
  public abstract int getFoodNum(String foodName);  //2.3:方法声明补全抽象方法关键词public abstract


  default String getBaseInfo(){        //3.1:java8 引入默认方法,必须实现
      //defaultTotal=defaultTotal+1;       //错误,长岭不能更改
        return "This is a menu";
    }
  static String getRestaurantName(){   //3.2:java8 引入静态方法,必须实现
        return "MFC";
    }
}

 抽象类可以有方法声明(即抽象方法)、具体的方法和属性(可以是静态常量和普通变量)。

/**
 * 菜单抽象类  //补充public,abstract可以省略,只要有抽象方法就是一个抽象类
 */
public  abstract class MenuAbstract {
    int defaultTotal=33;                       //1.1:变量
    public static final int defaultTotal2=40;  //1.2:常量,和上面的变量不同

    //Double getFoodTotal(String restaurantName);      //2.1:方法声明错误用法,abstract声明的类中抽象方法必须使用abstract
    abstract Double getFoodPrice(String foodName);    //2.2:方法声明一般写法
    public abstract int getFoodNum(String foodName);  //2.3:方法声明补全关键词public

    public String getBaseInfo(){  //2.4:具体方法,public可省略
        defaultTotal=defaultTotal+1;
        return "This is a menu";
    }
    static String getRestaurantName(){  //2.5
        return "MFC";
    }
//    default String getBaseInfo(){    //2:抽象方法不支持默认default方法
//        return "This is a menu";
//    }
}

(3)用instanceof可以检查一个对象是否属于某个特定类或是否实现了某个接口。可用来检测是否实现了目标接口或目标类。
(4)Java8新添加相关特性
       》》》接口可以含有静态方法,但必须实现该静态方法。
       值得注意的是:实现类实现多个接口时,可能会实现多个接口,各个接口可能含有同参同名的方法,使用该方法时,要使用“接口.接口静态方法”,而不是“实现类.接口静态方法”;如果接口要定义同名同参的静态方法,但是不能使用@Override重写接口中的方法,使用“实现类.实现类静态方法”的形式访问即可实现类中的静态方法。
        》》》接口中可以含有默认方法,但必须实现它。


2.从 设计上做比较
(1)接口和抽象类都是用来抽象具体对象的,两者均能体现多态性,但是接口的抽象级别最高,两者均不可直接实例化,若要实例化,必须先实现所有抽象方法。
(2)接口是设计的结果,即从无到有,大家制定契约和规则,签约类必须要完全遵守、实现该契约中的方法,即所有方法都是有意义且必须要实现的;侧重于行为约束,主要抽象功能
 抽象类是重构的结果,即从有到有 的设计,更侧重与内部优化与合理性,是为了继承扩展,实现代码的重用,主要抽象了事物(包含属性和方法)。

如何理解上面代码中的菜单的设计?
      当一家餐厅可能有多个门店,每个门店可能需要根据当地的实际消费,人数等情况自定义价格,折扣等操作,所以就出现了不同的需求。
      菜单接口:由专门人员去设计,3个开发者根据接口去开发,每个人负责一种门店菜单的开发,接口从无到有,要求所有门店菜单开发者(实现者)必须遵守这样的接口,实现每个方法,侧重于契约精神、规则精神。
      菜单抽象类:可以将所有门店的共同行为或属性抽取出来放在抽象类,派生的门店菜单实现类就不需要多次重写相同的行为代码了;并且,不同门店的个性化需求,可以通过实现抽象方法自定义;

为什么要设计接口和抽象类?
        接口设计不是必须的,如果一个系统较为复杂,需要多人合作,则可以使用接口,设计者制定接口后,就不再轻易改变接口(除非改动对接口有意义),其他人根据接口具体实现即可。如果系统较为简单,一个人即可实现,无需设计接口,否则就要牵一发动全身。不用为了以后的扩展怎么滴怎么滴的大费周章的去设计,真到那个时候再去重构设计也不迟。
       抽象类的设计也不是必须的,它的设计师为了更好的优化重构代码,实现代码的扩展、复用。
 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值