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

Java8 default methods 默認(rèn)方法的概念與代碼解析

開發(fā) 后端
Java 8引入default method,或者叫virtual extension method,目的是為了讓接口可以事后添加新方法而無需強(qiáng)迫所有實(shí)現(xiàn)該接口的類都提供新方法的實(shí)現(xiàn)。也就是說它的主要使用場(chǎng)景可能會(huì)涉及代碼演進(jìn)。

一、基本概念  

Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.

默認(rèn)方法使您能夠添加新的功能到你現(xiàn)有庫的接口中,并確保與采用老版本接口編寫的代碼的二進(jìn)制兼容性。

什么是默認(rèn)方法(default methods)

即接口可以有實(shí)現(xiàn)方法,而且不需要實(shí)現(xiàn)類去實(shí)現(xiàn)其方法。只需在方法名前面加個(gè)default關(guān)鍵字即可,這些方法默認(rèn)是

為什么要有默認(rèn)方法

為什么要有這個(gè)特性?首先,之前的接口是個(gè)雙刃劍,好處是面向抽象而不是面向具體編程,缺陷是,當(dāng)需要修改接口時(shí)候,需要修改全部實(shí)現(xiàn)該接口的類,目前的java 8之前的集合框架沒有foreach方法,通常能想到的解決辦法是在JDK里給相關(guān)的接口添加新的方法及實(shí)現(xiàn)。然而,對(duì)于已經(jīng)發(fā)布的版本,是沒法在給接口添加新方法的同時(shí)不影響已有的實(shí)現(xiàn)。所以引進(jìn)的默認(rèn)方法。他們的目的是為了解決接口的修改與現(xiàn)有的實(shí)現(xiàn)不兼容的問題

二、 java 8抽象類與接口的區(qū)別

相同點(diǎn):

1.都是抽象類型;

2.都可以有實(shí)現(xiàn)方法(java8才可以)

3.都可以不需要實(shí)現(xiàn)類或者繼承者去實(shí)現(xiàn)所有方法

不同點(diǎn)

1.抽象類不可以多重繼承,接口可以(無論是多重類型繼承還是多重行為繼承);

2.抽象類和接口所反映出的設(shè)計(jì)理念不同。其實(shí)抽象類表示的是"is-a"關(guān)系,接口表示的是"like-a"關(guān)系;

3.接口中定義的變量默認(rèn)是public static final 型,且必須給其初值,所以實(shí)現(xiàn)類中不能重新定義,也不能改變其值;抽象類中的變量默認(rèn)是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。

三、多重繼承的沖突說明

由于同一個(gè)方法可以從不同接口引入,自然而然的會(huì)有沖突的現(xiàn)象,默認(rèn)方法判斷沖突的規(guī)則如下:

1.一個(gè)聲明在類里面的方法優(yōu)先于任何默認(rèn)方法(classes always win)

2.否則,則會(huì)優(yōu)先選取***體的實(shí)現(xiàn),比如下面的例子 B重寫了A的hello方法。

四、如何擴(kuò)展或?qū)崿F(xiàn)帶有默認(rèn)方法的接口?

當(dāng)前擴(kuò)展一個(gè)默認(rèn)方法的接口時(shí),你可以采用以下三種方式:

1:讓擴(kuò)展類繼承默認(rèn)方法,根據(jù)不管是否存在默認(rèn)方法

2:重新聲明默認(rèn)方法,使其變?yōu)橐粋€(gè)抽象方法(注意,擴(kuò)展類的實(shí)現(xiàn)類必須實(shí)現(xiàn)此方法)

3:重新定義默認(rèn)方法,覆蓋(override)父類的默認(rèn)方法

五、默認(rèn)方法樣例代碼

  1. import java.time.DateTimeException;  
  2. import java.time.LocalDateTime;  
  3. import java.time.ZoneId;  
  4. import java.time.ZonedDateTime;  
  5.  
  6. public interface TimeClient {  
  7.     void setTime(int hour, int minute, int second);  
  8.  
  9.     void setDate(int day, int month, int year);  
  10.  
  11.     void setDateAndTime(int day, int month, int year, int hour, int minute,  
  12.             int second);  
  13.  
  14.     LocalDateTime getLocalDateTime();  
  15.  
  16.     static ZoneId getZoneId(String zoneString) {  
  17.         try {  
  18.             return ZoneId.of(zoneString);  
  19.         } catch (DateTimeException e) {  
  20.             System.err.println("Invalid time zone: " + zoneString  
  21.                     + "; using default time zone instead.");  
  22.             return ZoneId.systemDefault();  
  23.         }  
  24.     }  
  25.  
  26.     default ZonedDateTime getZonedDateTime(String zoneString) {  
  27.         return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));  
  28.     }  
  29. }  
  1. import java.time.LocalDate;  
  2. import java.time.LocalDateTime;  
  3. import java.time.LocalTime;  
  4. import java.util.ArrayList;  
  5. import java.util.Collections;  
  6. import java.util.Comparator;  
  7. import java.util.List;  
  8.  
  9. public class SimpleTimeClient implements TimeClient {  
  10.  
  11.     private LocalDateTime dateAndTime;  
  12.  
  13.     public SimpleTimeClient() {  
  14.         dateAndTime = LocalDateTime.now();  
  15.     }  
  16.  
  17.     public void setTime(int hour, int minute, int second) {  
  18.         LocalDate currentDate = LocalDate.from(dateAndTime);  
  19.         LocalTime timeToSet = LocalTime.of(hour, minute, second);  
  20.         dateAndTime = LocalDateTime.of(currentDate, timeToSet);  
  21.     }  
  22.  
  23.     public void setDate(int year, int month, int day) {  
  24.         LocalDate dateToSet = LocalDate.of(year, month, day);  
  25.         LocalTime currentTime = LocalTime.from(dateAndTime);  
  26.         dateAndTime = LocalDateTime.of(dateToSet, currentTime);  
  27.     }  
  28.  
  29.     public void setDateAndTime(int year, int month, int day, int hour,  
  30.             int minute, int second) {  
  31.         LocalDate dateToSet = LocalDate.of(year, month, day);  
  32.         LocalTime timeToSet = LocalTime.of(hour, minute, second);  
  33.         dateAndTime = LocalDateTime.of(dateToSet, timeToSet);  
  34.     }  
  35.  
  36.     public LocalDateTime getLocalDateTime() {  
  37.         return dateAndTime;  
  38.     }  
  39.  
  40.     public String toString() {  
  41.         return dateAndTime.toString();  
  42.     }  
  43.  
  44.     public static void main(String... args) {  
  45.         TimeClient client = new SimpleTimeClient();  
  46.         // 顯示當(dāng)前日期時(shí)間  
  47.         System.out.println(client.toString());  
  48.         // 設(shè)置日期  
  49.         client.setTime(111222);  
  50.         System.out.println(client);  
  51.         // 設(shè)置時(shí)間  
  52.         client.setDate(20121112);  
  53.         System.out.println(client);  
  54.  
  55.         System.out.println("Time in Asia/Shanghai: " 
  56.                 + client.getZonedDateTime("Asia/Shanghai").toString());  
  57.     }  
  58. }  

六、整合默認(rèn)方法、靜態(tài)方法到已經(jīng)存在的接口

默認(rèn)方法使您能夠添加新的功能到已經(jīng)存在的接口,確保與采用老版本這些接口編寫的代碼的二進(jìn)制兼容性。特別是,默認(rèn)的方法使您能夠在已經(jīng)存在的接口中添加使用lambda表達(dá)式作為參數(shù)的方法。下面的樣例代碼說明通過默認(rèn)方法和靜態(tài)方法,Comparator 接口是如何提供豐富的功能的。

在java8中,Compartor接口提供了豐富的功能,提供了差不多近20個(gè)默認(rèn)或靜態(tài)方法,在以前的版本中僅僅提供了compare(T o1, T o2)一個(gè)比較接口方法

下面的代碼是有關(guān)撲克牌游戲中的洗牌,針對(duì)牌排序,打散,發(fā)牌的部分源代碼

  1. package defaultmethods;  
  2.  
  3. //撲克牌接口類  
  4. public interface Card extends Comparable<Card> {  
  5.       
  6.     public enum Suit {   
  7.         DIAMONDS (1"Diamonds"),   
  8.         CLUBS    (2"Clubs"   ),   
  9.         HEARTS   (3"Hearts"  ),   
  10.         SPADES   (4"Spades"  );  
  11.           
  12.         private final int value;  
  13.         private final String text;  
  14.         Suit(int value, String text) {  
  15.             this.value = value;  
  16.             this.text = text;  
  17.         }  
  18.         public int value() {return value;}  
  19.         public String text() {return text;}  
  20.     }  
  21.       
  22.     public enum Rank {   
  23.         DEUCE  (2 , "Two"  ),  
  24.         THREE  (3 , "Three"),   
  25.         FOUR   (4 , "Four" ),   
  26.         FIVE   (5 , "Five" ),   
  27.         SIX    (6 , "Six"  ),   
  28.         SEVEN  (7 , "Seven"),  
  29.         EIGHT  (8 , "Eight"),   
  30.         NINE   (9 , "Nine" ),   
  31.         TEN    (10"Ten"  ),   
  32.         JACK   (11"Jack" ),  
  33.         QUEEN  (12"Queen"),   
  34.         KING   (13"King" ),  
  35.         ACE    (14"Ace"  );  
  36.         private final int value;  
  37.         private final String text;  
  38.         Rank(int value, String text) {  
  39.             this.value = value;  
  40.             this.text = text;  
  41.         }  
  42.         public int value() {return value;}  
  43.         public String text() {return text;}  
  44.     }  
  45.       
  46.     public Card.Suit getSuit();  
  47.     public Card.Rank getRank();  
  48. }  
  1. package defaultmethods;  
  2.  
  3. import java.util.Comparator;  
  4. import java.util.List;  
  5. import java.util.Map;  
  6.  
  7. //牌桌接口類  
  8. public interface Deck {  
  9.       
  10.     List<Card> getCards();  
  11.     Deck deckFactory();  
  12.     int size();  
  13.     void addCard(Card card);  
  14.     void addCards(List<Card> cards);  
  15.     void addDeck(Deck deck);  
  16.     void shuffle();  
  17.     void sort();  
  18.     void sort(Comparator<Card> c);  
  19.     String deckToString();  
  20.  
  21.     Map<Integer, Deck> deal(int players, int numberOfCards)  
  22.         throws IllegalArgumentException;  
  23.  
  24. }  
  25.  
  1. package defaultmethods;  
  2.  
  3. import java.util.Comparator;  
  4.  
  5. //先根據(jù)rank,再根據(jù)suit進(jìn)行比較  
  6. public class SortByRankThenSuit implements Comparator<Card> {  
  7.     public int compare(Card firstCard, Card secondCard) {  
  8.         int compVal = firstCard.getRank().value()  
  9.                 - secondCard.getRank().value();  
  10.         if (compVal != 0)  
  11.             return compVal;  
  12.         else 
  13.             return firstCard.getSuit().value() - secondCard.getSuit().value();  
  14.     }  
  15. }  
  1. package defaultmethods;  
  2.  
  3. //撲克牌實(shí)現(xiàn)類  
  4. public class PlayingCard implements Card {  
  5.  
  6.     private Card.Rank rank;  
  7.     private Card.Suit suit;  
  8.  
  9.     public PlayingCard(Card.Rank rank, Card.Suit suit) {  
  10.         this.rank = rank;  
  11.         this.suit = suit;  
  12.     }  
  13.  
  14.     public Card.Suit getSuit() {  
  15.         return suit;  
  16.     }  
  17.  
  18.     public Card.Rank getRank() {  
  19.         return rank;  
  20.     }  
  21.  
  22.     public boolean equals(Object obj) {  
  23.         if (obj instanceof Card) {  
  24.             if (((Card) obj).getRank() == this.rank  
  25.                     && ((Card) obj).getSuit() == this.suit) {  
  26.                 return true;  
  27.             } else {  
  28.                 return false;  
  29.             }  
  30.         } else {  
  31.             return false;  
  32.         }  
  33.     }  
  34.  
  35.     public int hashCode() {  
  36.         return ((suit.value() - 1) * 13) + rank.value();  
  37.     }  
  38.  
  39.     //實(shí)現(xiàn)比較接口  
  40.     public int compareTo(Card o) {  
  41.         return this.hashCode() - o.hashCode();  
  42.     }  
  43.  
  44.     //重載toString  
  45.     public String toString() {  
  46.         return this.rank.text() + " of " + this.suit.text();  
  47.     }  
  48.  
  49.     public static void main(String... args) {  
  50.         new PlayingCard(Rank.ACE, Suit.DIAMONDS);  
  51.         new PlayingCard(Rank.KING, Suit.SPADES);  
  52.     }  
  53. }  
  1. package defaultmethods;  
  2.  
  3. import java.util.ArrayList;  
  4. import java.util.Collections;  
  5. import java.util.Comparator;  
  6. import java.util.HashMap;  
  7. import java.util.List;  
  8. import java.util.Map;  
  9. import java.util.stream.Collectors;  
  10.  
  11. //牌桌實(shí)現(xiàn)類  
  12. public class StandardDeck implements Deck {  
  13.  
  14.     //撲克牌列表  
  15.     private List<Card> entireDeck;  
  16.  
  17.     public StandardDeck(List<Card> existingList) {  
  18.         this.entireDeck = existingList;  
  19.     }  
  20.  
  21.     public StandardDeck() {  
  22.         this.entireDeck = new ArrayList<>();  
  23.         for (Card.Suit s : Card.Suit.values()) {  
  24.             for (Card.Rank r : Card.Rank.values()) {  
  25.                 this.entireDeck.add(new PlayingCard(r, s));  
  26.             }  
  27.         }  
  28.     }  
  29.  
  30.     public Deck deckFactory() {  
  31.         return new StandardDeck(new ArrayList<Card>());  
  32.     }  
  33.  
  34.     public int size() {  
  35.         return entireDeck.size();  
  36.     }  
  37.  
  38.     public List<Card> getCards() {  
  39.         return entireDeck;  
  40.     }  
  41.  
  42.     public void addCard(Card card) {  
  43.         entireDeck.add(card);  
  44.     }  
  45.  
  46.     public void addCards(List<Card> cards) {  
  47.         entireDeck.addAll(cards);  
  48.     }  
  49.  
  50.     public void addDeck(Deck deck) {  
  51.         List<Card> listToAdd = deck.getCards();  
  52.         entireDeck.addAll(listToAdd);  
  53.     }  
  54.  
  55.     public void sort() {  
  56.         Collections.sort(entireDeck);  
  57.     }  
  58.  
  59.     public void sort(Comparator<Card> c) {  
  60.         Collections.sort(entireDeck, c);  
  61.     }  
  62.  
  63.     public void shuffle() {  
  64.         Collections.shuffle(entireDeck);  
  65.     }  
  66.  
  67.     //為每位玩家分牌  
  68.     public Map<Integer, Deck> deal(int players, int numberOfCards)  
  69.             throws IllegalArgumentException {  
  70.         int cardsDealt = players * numberOfCards;  
  71.         int sizeOfDeck = entireDeck.size();  
  72.           
  73.         if (cardsDealt > sizeOfDeck) {  
  74.             throw new IllegalArgumentException("Number of players (" + players  
  75.                     + ") times number of cards to be dealt (" + numberOfCards  
  76.                     + ") is greater than the number of cards in the deck (" 
  77.                     + sizeOfDeck + ").");  
  78.         }  
  79.         //把牌分成幾份  
  80.         int slices=players+1;  
  81.         if(cardsDealt == sizeOfDeck)  
  82.             slices=players;  
  83.  
  84.         //根據(jù)玩家的個(gè)數(shù),每個(gè)玩家分到的撲克牌數(shù)進(jìn)行分牌  
  85.         Map<Integer, List<Card>> dealtDeck = entireDeck.stream().collect(  
  86.                 Collectors.groupingBy(card -> {  
  87.                     int cardIndex = entireDeck.indexOf(card);  
  88.                     if (cardIndex >= cardsDealt)  
  89.                         return (players + 1);  
  90.                     else 
  91.                         return (cardIndex % players) + 1;  
  92.                 }));  
  93.         System.out.println(dealtDeck);  
  94.         // Convert Map<Integer, List<Card>> to Map<Integer, Deck>  
  95.         Map<Integer, Deck> mapToReturn = new HashMap<>();  
  96.  
  97.         for (int i = 1; i < (slices + 1); i++) {  
  98.             Deck currentDeck = deckFactory();  
  99.             currentDeck.addCards(dealtDeck.get(i));  
  100.             mapToReturn.put(i, currentDeck);  
  101.         }  
  102.         return mapToReturn;  
  103.     }  
  104.  
  105.     public String deckToString() {  
  106.         return this.entireDeck.stream().map(Card::toString)  
  107.                 .collect(Collectors.joining("\n"));  
  108.     }  
  109.       
  110.     public String toString(){  
  111.         return deckToString();  
  112.     }  
  113.  
  114.     public static void main(String... args) {  
  115.         System.out.println("Creating deck:");  
  116.         StandardDeck myDeck = new StandardDeck();  
  117.           
  118.         myDeck.sort();  
  119.         System.out.println("Sorted deck");  
  120.         System.out.println(myDeck.deckToString());  
  121.           
  122.         myDeck.shuffle();  
  123.         myDeck.sort(new SortByRankThenSuit());  
  124.         System.out.println("Sorted by rank, then by suit");  
  125.         System.out.println(myDeck.deckToString());  
  126.           
  127.         myDeck.shuffle();  
  128.         myDeck.sort(Comparator.comparing(Card::getRank).thenComparing(  
  129.                 Comparator.comparing(Card::getSuit)));  
  130.         System.out.println("Sorted by rank, then by suit " 
  131.                 + "with static and default methods");  
  132.         System.out.println(myDeck.deckToString());  
  133.  
  134.         myDeck.sort(Comparator.comparing(Card::getRank).reversed()  
  135.                 .thenComparing(Comparator.comparing(Card::getSuit).reversed()));  
  136.         System.out.println("Sorted by rank reversed, then by suit " 
  137.                 + "with static and default methods");  
  138.         System.out.println(myDeck.deckToString());  
  139.           
  140.         myDeck.shuffle();  
  141.         myDeck.sort(  
  142.             (firstCard, secondCard) ->  
  143.                 firstCard.getRank().value() - secondCard.getRank().value()  
  144.         );   
  145.         System.out.println(myDeck.deckToString());  
  146.           
  147.         myDeck.shuffle();  
  148.         myDeck.sort(Comparator.comparing(Card::getRank));  
  149.         System.out.println(myDeck.deckToString());  
  150.           
  151.         Map<Integer, Deck> map=myDeck.deal(411);  
  152.         for(Map.Entry<Integer, Deck> item:map.entrySet()){  
  153.             System.out.println(item.getKey());  
  154.             System.out.println(item.getValue());  
  155.             System.out.println("-------------------------------");  
  156.         }  
  157.     }  
  158. }  

七、參考

http://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html

http://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html

http://docs.oracle.com/javase/tutorial/java/TOC.html

原文鏈接:http://www.oschina.net/search?scope=all&q=java8

責(zé)任編輯:林師授 來源: oschina
相關(guān)推薦

2021-03-04 08:14:37

Java8開發(fā)接口

2015-05-25 09:45:16

Java多繼承深入解析

2015-06-25 10:00:30

Java 8代碼

2022-01-06 07:39:17

Java Default關(guān)鍵字 Java 基礎(chǔ)

2014-03-28 11:08:16

Java 8多重繼承

2023-12-29 08:33:17

2014-04-11 12:49:00

Java8Java8教程

2020-07-24 08:11:04

Java8ava5語言

2017-01-13 10:51:13

RPC模型解析

2009-08-28 12:31:06

C#靜態(tài)方法

2021-08-13 12:53:42

StringBuildStringJoineJava

2023-07-26 07:13:55

函數(shù)接口Java 8

2020-12-08 06:24:08

Java 代碼工具

2017-10-31 20:45:07

JavaJava8Optional

2023-03-15 17:37:26

Java8ListMap

2022-04-14 15:12:40

Java8Stream列表

2010-06-29 16:53:08

2010-08-02 16:41:15

2025-01-02 15:40:23

2020-05-25 16:25:17

Java8Stream函數(shù)式接口
點(diǎn)贊
收藏

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