成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java8 default methods 默認方法的概念與代碼解析

開發 后端
Java 8引入default method,或者叫virtual extension method,目的是為了讓接口可以事后添加新方法而無需強迫所有實現該接口的類都提供新方法的實現。也就是說它的主要使用場景可能會涉及代碼演進。

一、基本概念  

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.

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

什么是默認方法(default methods)

即接口可以有實現方法,而且不需要實現類去實現其方法。只需在方法名前面加個default關鍵字即可,這些方法默認是

為什么要有默認方法

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

二、 java 8抽象類與接口的區別

相同點:

1.都是抽象類型;

2.都可以有實現方法(java8才可以)

3.都可以不需要實現類或者繼承者去實現所有方法

不同點

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

2.抽象類和接口所反映出的設計理念不同。其實抽象類表示的是"is-a"關系,接口表示的是"like-a"關系;

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

三、多重繼承的沖突說明

由于同一個方法可以從不同接口引入,自然而然的會有沖突的現象,默認方法判斷沖突的規則如下:

1.一個聲明在類里面的方法優先于任何默認方法(classes always win)

2.否則,則會優先選取***體的實現,比如下面的例子 B重寫了A的hello方法。

四、如何擴展或實現帶有默認方法的接口?

當前擴展一個默認方法的接口時,你可以采用以下三種方式:

1:讓擴展類繼承默認方法,根據不管是否存在默認方法

2:重新聲明默認方法,使其變為一個抽象方法(注意,擴展類的實現類必須實現此方法)

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

五、默認方法樣例代碼

  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.         // 顯示當前日期時間  
  47.         System.out.println(client.toString());  
  48.         // 設置日期  
  49.         client.setTime(111222);  
  50.         System.out.println(client);  
  51.         // 設置時間  
  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. }  

六、整合默認方法、靜態方法到已經存在的接口

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

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

下面的代碼是有關撲克牌游戲中的洗牌,針對牌排序,打散,發牌的部分源代碼

  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. //先根據rank,再根據suit進行比較  
  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. //撲克牌實現類  
  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.     //實現比較接口  
  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. //牌桌實現類  
  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.         //根據玩家的個數,每個玩家分到的撲克牌數進行分牌  
  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

責任編輯:林師授 來源: oschina
相關推薦

2021-03-04 08:14:37

Java8開發接口

2015-05-25 09:45:16

Java多繼承深入解析

2015-06-25 10:00:30

Java 8代碼

2022-01-06 07:39:17

Java Default關鍵字 Java 基礎

2014-03-28 11:08:16

Java 8多重繼承

2023-12-29 08:33:17

2025-06-26 08:10:00

Java8函數

2014-04-11 12:49:00

Java8Java8教程

2017-01-13 10:51:13

RPC模型解析

2020-07-24 08:11:04

Java8ava5語言

2009-08-28 12:31:06

C#靜態方法

2021-08-13 12:53:42

StringBuildStringJoineJava

2023-07-26 07:13:55

函數接口Java 8

2020-12-08 06:24:08

Java 代碼工具

2010-08-02 16:41:15

2017-10-31 20:45:07

JavaJava8Optional

2023-03-15 17:37:26

Java8ListMap

2010-06-29 16:53:08

2025-01-02 15:40:23

2022-04-14 15:12:40

Java8Stream列表
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩在线视频一区 | 一区二区三区四区在线 | 欧美日韩久久 | 久久精品国产一区 | 国产色网| 国产成人精品免费视频大全最热 | 亚洲丝袜天堂 | 在线欧美亚洲 | 午夜影院视频 | 亚洲 自拍 另类 欧美 丝袜 | 午夜99 | 国产一区二区自拍 | 蜜桃av一区二区三区 | 日韩在线视频一区 | 久久网一区二区三区 | 亚洲欧美一区二区在线观看 | 精品国产欧美一区二区三区成人 | 亚洲深夜福利 | 天天操网 | 精品一区二区三区视频在线观看 | 久久久精品网 | 日韩视频专区 | 色接久久 | 久久精品无码一区二区三区 | 日本亚洲一区二区 | 黄网站在线观看 | 国产精品久久久久久久久久久久久 | 一区二区三区四区国产 | 91传媒在线观看 | 亚洲精品乱码8久久久久久日本 | 午夜影视在线观看 | 特一级毛片 | 中文字幕av网站 | 婷婷91| 精品欧美激情精品一区 | 国产在线中文字幕 | 久久久久国产 | 国产精品一区二区日韩 | 欧美精品一区二区在线观看 | 久在线| 五月综合久久 |