自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Java類(接口)的新類型-密封類

開(kāi)發(fā) 后端
在以往的Java類繼承中,Java類的繼承控制非常有限,僅能通過(guò)final關(guān)鍵字和訪問(wèn)控制符來(lái)控制類的繼承。例如final類無(wú)法被集成;包私有類僅僅只能在該包下進(jìn)行繼承。

[[432662]]

密封類是Java 17正式支持的一個(gè)新特性,它讓Java中類的繼承可以更加細(xì)粒度的進(jìn)行控制。今天就來(lái)認(rèn)識(shí)一下這個(gè)新的功能。

密封類

在以往的Java類繼承中,Java類的繼承控制非常有限,僅能通過(guò)final關(guān)鍵字和訪問(wèn)控制符來(lái)控制類的繼承。例如final類無(wú)法被集成;包私有類僅僅只能在該包下進(jìn)行繼承。

這顯然是不夠的。如果一個(gè)功能只允許出現(xiàn)在Phone和Pad上,不允許出現(xiàn)在Computer上。如果不對(duì)該功能的繼承實(shí)現(xiàn)進(jìn)行限制,開(kāi)發(fā)人員將很容易濫用該功能的實(shí)現(xiàn)類,錯(cuò)誤地重用一些代碼。這就是密封類產(chǎn)生的原因。

密封類的聲明

密封類不僅僅可以是類,也可以是接口。文章中的密封類為統(tǒng)稱

密封類(接口)可以明確哪些類和接口可以對(duì)其擴(kuò)展或?qū)崿F(xiàn)。你可以通過(guò)sealed修飾符來(lái)表明某個(gè)類是密封類。但是下面是一個(gè)錯(cuò)誤的密封類聲明:

  1. /** 
  2.  * 這是一個(gè)錯(cuò)誤的示范 
  3.  */ 
  4. public sealed interface SealedService { 
  5.     
  6.     void doSomething(); 

密封類(接口)在聲明的時(shí)候必須明確可繼承(實(shí)現(xiàn))的范圍,所以上面的寫法是錯(cuò)誤的。必須用permits子句指定允許擴(kuò)展密封類的類,而且permits關(guān)鍵字位于extends或者implements之后。

簡(jiǎn)而言之,密封類明確了哪些其他類(或接口)可以擴(kuò)展它們。

下面是正確的寫法:

  1. /** 
  2.  * 這是一個(gè)正確的示范,明確了可繼承的子類為{@link SealedServiceImpl} 
  3.  * 該密封類接口同時(shí)實(shí)現(xiàn)了{(lán)@link SuperService} 
  4.  */ 
  5. public sealed interface SealedService extends SuperService permits SealedServiceImpl { 
  6.     void doSomething(); 
  7.  
  8. /** 
  9.  * 密封類子類 
  10.  */ 
  11. public final class SealedServiceImpl implements SealedService { 
  12.     @Override 
  13.     public void doSomething() { 
  14.         System.out.println("這是一個(gè)密封類子類"); 
  15.     } 

密封類子類的類型

在上面示例中,密封類(接口)的實(shí)現(xiàn)類用了final關(guān)鍵字標(biāo)記,當(dāng)然密封類的實(shí)現(xiàn)類還可以是密封類:

  1. /** 
  2.  * 密封類子類 
  3.  */ 
  4. public sealed class SealedServiceImpl implements SealedService permits SonService { 
  5.     @Override 
  6.     public void doSomething() { 
  7.         System.out.println("這是一個(gè)密封類子類"); 
  8.     } 
  9.  
  10.  
  11. public final class SonService extends SealedServiceImpl { 

那么難道密封類(接口)的子類只能是final類或者密封類,就不能再擴(kuò)展了?答案是否定的,只需要使用關(guān)鍵字non-sealed顯式聲明密封類的繼承實(shí)現(xiàn)為非密封類就可以繼續(xù)擴(kuò)展了。

  1. public non-sealed class SealedServiceImpl implements SealedService { 
  2.     @Override 
  3.     public void doSomething() { 
  4.  
  5.     } 
  6.  
  7.     /** 
  8.      * 用{@code non-sealed}聲明非密封類,就可以繼續(xù)擴(kuò)展了 
  9.      */ 
  10.     static class NonSealedExtend extends SealedServiceImpl { 
  11.  
  12.     } 
  13.  

總結(jié)一下,密封類的子類要么是final Class;要么是sealed Class;要么是non-sealed Class。

permits 聲明的類必須是直接子類

密封類permits關(guān)鍵字聲明的子類必須是直接實(shí)現(xiàn)類,為了證明這一點(diǎn)我們這樣寫:

  1. /** 
  2.  * 錯(cuò)誤的示范 
  3.  */ 
  4. public sealed interface SealedService extends SuperService permits SealedServiceImpl, SonService { 
  5.     void doSomething(); 
  6.  
  7. public sealed class SealedServiceImpl implements SealedService permits SonService { 
  8.     @Override 
  9.     public void doSomething() { 
  10.         System.out.println("這是一個(gè)密封類子類"); 
  11.     } 
  12.  
  13. public final class SonService extends SealedServiceImpl { 

我使用SonService間接實(shí)現(xiàn)了SealedService,結(jié)果報(bào)錯(cuò),報(bào)錯(cuò)信息要求必須是直接的繼承關(guān)系。

錯(cuò)誤的密封類繼承實(shí)現(xiàn)

從上圖可以看出SonService并非直接實(shí)現(xiàn)SealedService,這樣會(huì)打破密封類的規(guī)則,所以無(wú)法編譯通過(guò)。

密封類中permits關(guān)鍵字聲明的子類必須是直接子類,不可間接實(shí)現(xiàn)。

密封類不支持匿名類和函數(shù)式接口

由于密封類必須明確繼承實(shí)現(xiàn)關(guān)系,所以它不支持匿名類。

  1. /** 
  2.  * 密封類無(wú)法使用匿名類 
  3.  * 
  4.  * @return the sealed service 
  5.  */ 
  6. public SealedService sealedService(){ 
  7.     // 提示 Anonymous classes must not extend sealed classes 
  8.     return new SealedService() { 
  9.         @Override 
  10.         public void doSomething() { 
  11.              
  12.         } 
  13.     }; 

同樣也不支持函數(shù)式接口:

  1. /** 
  2.  * 錯(cuò)誤的示范 
  3.  */ 
  4. @FunctionalInterface 
  5. public sealed interface SealedService permits SealedServiceImpl { 
  6.     void doSomething(); 

總結(jié)

 

密封類已經(jīng)在Java 17中正式轉(zhuǎn)正,這也是Java 17的非常重要的特性之一。對(duì)于需要細(xì)粒度控制繼承關(guān)系的場(chǎng)景來(lái)說(shuō)是非常有用的。

 

責(zé)任編輯:武曉燕 來(lái)源: 碼農(nóng)小胖哥
相關(guān)推薦

2022-03-29 07:20:04

密封類.NET性能

2012-02-29 09:32:01

Java

2020-06-29 07:52:17

Java工具類開(kāi)發(fā)

2011-07-10 14:07:59

JAVA

2011-07-12 15:58:48

java抽象類接口

2009-04-30 15:15:01

Java抽象類接口

2020-06-27 09:01:53

Java包裝類編程語(yǔ)言

2010-03-04 09:40:04

Java接口抽象類

2011-03-07 13:59:00

2009-06-12 13:48:13

數(shù)據(jù)類型string類Java教程

2013-12-10 16:44:30

2011-05-19 18:01:56

JAVA

2022-11-15 09:57:51

Java接口

2009-06-16 11:30:00

Java抽象類Java接口

2009-06-14 21:31:29

Java抽象類Java接口

2011-12-22 10:48:21

Java

2015-03-23 09:33:43

Java抽象類Java接口Java

2021-04-08 10:10:46

JavaSimpleDateFList接口

2020-07-08 07:56:08

Java工具類包裝類

2009-07-22 09:31:59

Scala類類層級(jí)Java類
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)