接口和抽象是Java 面向對象設計的兩個基礎機制。面試
接口是對行爲的抽象,它是抽象方法的集合,利用接口能夠達到API 和實現分離的目的。它不包含任何很是量的變量,同時沒有方法實現。JDK1.8 後引入的default 後能夠。用關鍵字implements 實現。設計模式
抽象類是不能實例化的類,用關鍵字abstract 修飾,其主要目的是代碼重用。除了不能實例化,形式上和通常的 Java 類並無太大區別,能夠有一個或者多個抽象方法,也能夠沒有抽象方法。抽象類大多用於抽取相關 Java 類的共用方法實現或者是共同成員變量,而後經過繼承的方式達到代碼複用的目的。bash
一個類能夠單繼承多實現。多線程
如下爲網上摘取的不一樣點:函數
接口和抽象的區別是面試中常常問到的考點。雖然很簡單,可是往深了想其實仍是有不少值得咱們在乎的地方。主要是設計方面的問題。spa
咱們都知道C++ 能夠實現多繼承。可是多繼承會出現菱形繼承的問題:A 類實現了一個方法,B、C類分別繼承與A 並重寫了這個方法,D 類繼承B、C 可是不知到該調用誰的方法。雖然C++ 提供瞭解決辦法(好像是虛繼承),可是仍是不方便。Java 所以摒棄了多繼承。線程
爲何能夠多實現呢?首先接口不可能出現菱形繼承關係:A 接口被B、C 類實現,D 由於單繼承只能選擇一個來進行繼承。其次,就算實現的兩個接口擁有相同的方法名,在實現裏面也不會出現歧義。設計
不管是A 仍是B 來回調函數,均可以找到實現。只是這樣設計不太好。3d
這種問題其實在不少地方均可以問到,好比多線程既然Thread 能夠直接start,何須要設計一個Runnable 接口,畫蛇添足?code
new Thread().start();
new Thread(new Runnable()).start; //僞代碼
複製代碼
其實回答這些問題無非兩個關注點:
接口更關注在於API 和實現分離,而繼承更關注與方法和屬性重用;同時接口更簡潔,抽象須要額外繼承不少父類的東西。
JDK1.8 引入default 關鍵字讓接口能夠實現具體方法,之因此這樣設計的緣由是延展性考慮。相似於各類集合接口,它的實現類有不少,若是這種接口想要增長新方法,好比1.8 增長stream 流的操做,意味着因此實現類必須一樣增長實現?哪也太不便於維護和更新了,估計Java 底層設計師看到這個需求能夠直接申請辭職了。
咱們在設計抽象和接口的時候須要考慮設計模式,經常使用的設計模式也就是所謂的 S.O.L.I.D 原則。 這裏後面會補充