我要告訴你:java接口中可以定義private私有方法

2021-01-08 紙鶴視界

在傳統的Java編程中,被廣為人知的一個知識點是:java Interface接口中不能定義private私有方法。只允許我們定義public訪問權限的方法、抽象方法或靜態方法。但是從Java 9 開始,Interface 接口中允許定義私有方法和私有靜態方法。下面我們就來為大家介紹其語法規則,和為什麼要有這樣的設計。

其實在Java 8之前,還有另一個被廣為人之的知識點:接口中所有的方法必須是abstract 抽象方法。但是,從java 8開始接口中可以包含非abstract 方法,如下文中的default方法。這個不是我們本文要為大家介紹的內容,如不熟悉,請自行補課。

一、Java 9接口定義私有方法

從Java 9開始,我們可以在Interface接口中添加private的私有方法和私有靜態方法。這些私有方法將改善接口內部的代碼可重用性。例如,如果需要兩個默認方法來共享代碼,則私有接口方法將允許它們共享代碼,但不將該私有方法暴露給它的實現類調用(後文中會給大家舉一個例子)。

在接口中使用私有方法有四個規則:

接口中private方法不能是abstract抽象方法。因為abstract抽象方法是公開的用於給接口實現類實現的方法,所以不能是private。接口中私有方法只能在接口內部的方法裡面被調用。接口中私有靜態方法可以在其他靜態和非靜態接口方法中使用。接口中私有非靜態方法不能在私有靜態方法內部使用。interface CustomInterface { public abstract void abstractMethod(); //抽象方法不能是私有的 public default void defaultMethod() { privateMethod(); //可以調用接口中的私有方法 privateStaticMethod(); //可以調用接口中的私有靜態方法 System.out.println("普通方法被調用"); } public static void staticMethod() { privateStaticMethod(); //public靜態方法可以調用private靜態方法 System.out.println("靜態方法被調用"); } private void privateMethod() { System.out.println("private私有方法被調用"); } private static void privateStaticMethod() { System.out.println("private私有靜態方法被調用"); }}按照上面四個規則,上面的代碼定義都是正確的

二、一個例子:分別計算奇數與偶數的和

接口定義如下,下文中add方法採用了java8 的Stream流操作,分別使用lambda表達式作為過濾條件,並求和。核心是:addEvenNumbers偶數求和函數和addOddNumbers奇數求和函數,都調用了add接口私有方法。

public interface CustomCalculator { default int addEvenNumbers(int... nums) { //非抽象,java8 開始可以定義default方法 return add(n -> n % 2 == 0, nums); //過濾偶數並求和,調用private私有方法 } default int addOddNumbers(int... nums) { //非抽象,java8 開始可以定義default方法 return add(n -> n % 2 != 0, nums); //過濾奇數並求和,調用private私有方法 } //按照過濾條件過濾奇數或偶數並sum求和:java9開始可以定義private私有方法 private int add(IntPredicate predicate, int... nums) { return IntStream.of(nums) //java8 Stream流 .filter(predicate) //java8 predicate及過濾器 .sum(); //sum求和 }}接口實現類MainCalculator 實現CustomCalculator接口

public class MainCalculator implements CustomCalculator { public static void main(String[] args) { CustomCalculator demo = new MainCalculator (); int sumOfEvens = demo.addEvenNumbers(1,2,3,4,5,6,7,8,9); System.out.println(sumOfEvens); //過濾所有偶數並求和,結果是20 int sumOfOdds = demo.addOddNumbers(1,2,3,4,5,6,7,8,9); System.out.println(sumOfOdds); //過濾所有奇數並求和,結果是25 } }歡迎關注我的博客,裡面有很多精品合集

本文轉載註明出處(必須帶連接,不能只轉文字):字母哥博客。覺得對您有幫助的話,幫我點讚、分享!您的支持是我不竭的創作動力! 。另外,筆者最近一段時間輸出了如下的精品內容,期待您的關注。

《手摸手教你學Spring Boot2.0》《Spring Security-JWT-OAuth2一本通》《實戰前後端分離RBAC權限管理系統》《實戰SpringCloud微服務從青銅到王者》《VUE深入淺出系列》

相關焦點

  • 從頭再來:Java中的接口(接口可以是private的嗎?)
    Java的接口Java中可以定義一個私有接口嗎?答案是肯定的。那為什麼會用到私有的接口?回答這個問題之前先看看Java中的接口Java的接口接口提供了一種接口和實現分離的方法,在Java中通過關鍵字interface定義,接口中的方法都是抽象的(沒有實現體)。接口在現實中使用的太多了,比如插座的接口,手機的充電接口,耳機接口。接口只定義了協議,實現者只要實現這個接口定義即可。
  • 看了這篇,我確定你已經徹底搞懂Java的繼承了
    遇到認真的讀者是作者的一種幸運,真的,上一篇接口推送後,有好幾個讀者留言說,「二哥,你有一處內容需要修正,應該是接口中不能有 private 和 protected 修飾的方法。」說實話,看到這樣的留言,我內心是非常欣慰的,因為你投出去的一塊石頭在水面上激起了一串美麗的漣漪。
  • Java 中的繼承和多態(深入版)
    所以可以簡單的理解,重寫就是子類對父類方法的核心進行重新定義。因為白切雞類中live()方法的參數列表和返回值與父類一樣,但方法體不一樣了。2. 重載重載,指的是在一個類中有若干個方法名相同,但參數列表不同的情況,返回值可以相同也可以不同的方法定義場景。也可以簡單理解成,同一行為(方法)的不同表現形式。
  • 面試官寫了個雙冒號:問我這是什麼語法?Java中有這玩意?
    一:簡潔方法引用分為三種,方法引用通過一對雙冒號:: 來表示,方法引用是一種函數式接口的另一種書寫方式靜態方法引用,通過類名::靜態方法名, 如 Integer::parseIntstatic int parseInt(String s) throws NumberFormatException {return parseInt(s,10);}}通過方法引用,可以將方法的引用賦值給一個變量,
  • java集合【6】——— Iterable接口
    iterable接口整個接口框架關係如下(來自百度百科):iterable接口其實是java集合大家庭的最頂級的接口之一了,實現這個接口,可以視為擁有了獲取迭代器的能力。內部定義的方法 java集合最源頭的接口,實現這個接口的作用主要是集合對象可以通過迭代器去遍歷每一個元素。
  • java中static, final, 內部類的具體運用
    class Yy {}final class Fue xtendsYy{} //可以繼承Yy 類class Zi extends Fu{}final修飾的方法不可以被覆蓋,但父類中沒有被final修飾方法,子類覆蓋後可以加final。
  • Java:如何更優雅地處理空值?
    對於以上描述的接口方法來看,大概可以推斷出可能它包含了以下兩個含義:listUser(): 查詢用戶列表get(Integer id): 查詢單個用戶在所有的開發中,XP推崇的TDD模式可以很好的引導我們對接口的定義
  • Java 9 中的 9 個新特性
    你是否就像我一樣在一直使用 Google 來查找正確的 Javadoc 頁面呢? 這不再需要了。Javadoc 現在支持在 API 文檔中的進行搜索。另外,Javadoc 的輸出現在符合兼容 HTML5 標準。此外,你會注意到,每個 Javadoc 頁面都包含有關 JDK 模塊類或接口來源的信息。
  • Java中抽象類和接口的介紹及二者間的區別
    在Java中,定一個接口的形式如下:接口中可以含有 變量和方法。但是要注意,接口中的變量會被隱式地指定為public static final變量(並且只能是public static final變量,用private修飾會報編譯錯誤),而方法會被隱式地指定為public abstract方法且只能是public abstract方法(用其他關鍵字,比如private、protected、static、 final等修飾會報編譯錯誤),並且接口中所有的方法不能有具體的實現
  • 對啊我就是認定你不知道ArrayList為什麼要實現RandomAccess接口
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫在我們的開發中,List接口是最常見不過,而且我們幾乎每天都在用ArrayList或者LinkedList,但是細心的同學有沒有發現,ArrayList中實現了RandomAccess接口,而LinkedList卻沒有實現RandomAccess
  • 如何優雅的設計 Java 異常
    如何選擇異常從筆者的開發經驗來看,如果在一個應用中,需要開發一個方法(如某個功能的service方法),這個方法如果中間可能出現異常,那麼你需要考慮這個異常出現之後是否調用者可以處理,並且你是否希望調用者進行處理,如果調用者可以處理,並且你也希望調用者進行處理,那麼就要拋出受檢異常,提醒調用者在使用你的方法時
  • 10道虐心的Java面試題,被面試官虐哭了,同事一題都沒答對
    有一天,小王告訴我,他去一家公司面試 Java 崗,結果被面試官虐哭了。整整 10 道 Java 面試題,小王一道也沒答正確。  他沮喪地給我說,「哥,說點我的情況,你願意聽嗎?我和一個女孩相處,女孩大我兩歲,我非科班。本來打算國慶換一家薪水高點的,好確認關係。
  • 「原創」為什麼java中一切都是對象,還要有static?
    並且由於這個特性,在靜態方法中不能訪問類的非靜態成員變量和非靜態成員方法,因為非靜態成員方法/變量都是必須依賴具體的對象才能夠被調用。但是要注意的是,雖然在靜態方法中不能訪問非靜態成員方法和非靜態成員變量,但是在非靜態成員方法中是可以訪問靜態成員方法/變量的。
  • 阿里內部學習指南《Effective Java中文 第3版》程式設計師進階必備
    通過閱讀貫穿全書的透徹的技術剖析與完整的示例代碼,認真理解並加以實踐,必定會從中受益匪淺。書中介紹的示例代碼清晰易懂,也可以作為日常工作的參考指南。本書分為12章共90個條目,涵蓋了Java 5.0/6.0/ 7.0/ 8.0/ 9.0的種種技術要點。
  • 一文解析Java常用關鍵字
    4.2.2.2 final變量構造函數中初始化(空白final) 因為被final修飾的變量一定要在使用前被初始化,所以如果沒在定義操作,一定在構造函數中初始化,這種情況稱為空白final。
  • Java基礎面試題簡單總結
    如果在子類中定義某方法與其父類有相同的名稱和參數,我們說該方法被重寫 (Overriding)。子類的對象使用這個方法時,將調用子類中的定義,對它而言,父類中的定義如同被"屏蔽"了。如果在一個類中定義了多個同名的方法,它們或有不同的參數個數或有不同的參數類型,則稱為方法的重載(Overloading)。
  • Java 訪問權限控制:你真的了解 protected 關鍵字嗎?
    Package 關於包的使用,只需注意一點:在一個項目中,不可以有相同的兩個包名,也就是說,包名不能和項目中其他的包名重複,這裡不但包括自定義包名也包括項目所引用的類庫的包名。在Java中,類成員的訪問權限修飾詞有四個:private,無(包訪問權限),protected 和 public,其權限控制如下表所示:     特別要注意的是,不同於類成員的訪問權限類別,對於非內部類而言,類的訪問權限修飾詞僅有public和包訪問權限兩種(內部類可以是private或protected的。
  • Java 枚舉(enum) 詳解7種常見的用法
    在java中如何更好的使用這些「數據集」呢?因此枚舉便派上了用場,以下代碼詳細介紹了枚舉的用法。JDK1.5引入了新的類型——枚舉。在 Java 中它雖然算個「小」功能,卻給我們的開發帶來了「大」方便。在JDK1.5 之前,我們定義常量都是: public static fianl.... 。
  • 2020 年,你還在使用 Java 中的 SimpleDateFormat 嗎?
    8之前 SimpleDateFormat 是一個比較常用的類,但是我還是在這裡要建議開發者不要用 SimpleDateForma。那麼很多人就會想,既然new 代價太大, 不如我們使用 static 將其設置為共享變量,這樣就可以減小頻繁創建對象帶來的內存開銷啦,真的是機智如我。
  • Java中ItemEvent的使用方法
    1:ItemEvent事件源:選擇框,下拉列表都可以觸發ItemEvent事件2:註冊監視器:ItemListener樓口作為監視器事件源addI temListener (ItemListener listen