קונסטרוקטורים גנריים בג'אווה

1. סקירה כללית

דנו בעבר ביסודות Java Generics. במדריך זה נסתכל על בנאים גנריים בג'אווה.

קונסטרוקטור כללי הוא קונסטרוקטור שיש לו לפחות פרמטר אחד מסוג כללי.

נראה שנבנים גנריים לא חייבים להיות בכיתה גנרית, ולא כל הבונים בכיתה גנרית חייבים להיות גנריים.

2. מעמד לא גנרי

ראשית, יש לנו שיעור פשוט כְּנִיסָה, שאינו מעמד גנרי:

כניסה ציבורית {פרטי מחרוזת פרטית; דירוג אינטי פרטי; }

בשיעור זה נוסיף שני קונסטרוקטורים: קונסטרוקטור בסיסי עם שני פרמטרים, ובנאי כללי.

2.1. קונסטרוקטור בסיסי

הראשון כְּנִיסָה קונסטרוקטור הוא בנאי פשוט עם שני פרמטרים:

כניסה ציבורית (נתוני מחרוזת, דירוג int) {this.data = data; this.rank = דרגה; }

עכשיו, בואו נשתמש בבנאי בסיסי זה כדי ליצור כְּנִיסָה לְהִתְנַגֵד:

@Test הציבור בטל givenNonGenericConstructor_whenCreateNonGenericEntry_thenOK () {ערך כניסה = כניסה חדשה ("מדגם", 1); assertEquals ("מדגם", entry.getData ()); assertEquals (1, entry.getRank ()); }

2.2. קונסטרוקטור גנרי

לאחר מכן, הבנאי השני שלנו הוא בנאי גנרי:

כניסה ציבורית (אלמנט E) {this.data = element.toString (); this.rank = element.getRank (); }

למרות ש כְּנִיסָה class אינו כללי, יש לו קונסטרוקטור גנרי, שכן יש לו פרמטר אֵלֵמֶנט מהסוג ה.

הסוג הגנרי ה מוגבל וצריך ליישם את שניהם ניתן לדירוג ו ניתן לבצע סדרתי ממשקים.

עכשיו, בואו נסתכל על ה- ניתן לדירוג ממשק, שיש לו שיטה אחת:

ממשק ציבורי דירוג {public int getRank (); }

ונניח שיש לנו שיעור מוצר שמיישם את ניתן לדירוג מִמְשָׁק:

מחלקה ציבורית מכשירי מוצר ניתנים לדירוג, לסידור {שם מחרוזת פרטי; מחיר כפול פרטי; מכירות פרטיים; מוצר ציבורי (שם מחרוזת, מחיר כפול) {this.name = שם; מחיר זה = מחיר; } @Override public int getRank () {מכירות חוזרות; }}

לאחר מכן נוכל ליצור את הבנאי הגנרי כְּנִיסָה אובייקטים המשתמשים ב- מוצר:

@Test public void givenGenericConstructor_whenCreateNonGenericEntry_thenOK () {מוצר מוצר = מוצר חדש ("חלב", 2.5); product.setSales (30); כניסה כניסה = כניסה חדשה (מוצר); assertEquals (product.toString (), entry.getData ()); assertEquals (30, entry.getRank ()); }

3. מחלקה גנרית

לאחר מכן, נסתכל על שיעור גנרי שנקרא GenericEntry:

מחלקה ציבורית GenericEntry {נתוני T פרטיים; דירוג אינטי פרטי; }

נוסיף את אותם שני סוגי קונסטרוקטורים כמו החלק הקודם בכיתה זו.

3.1. קונסטרוקטור בסיסי

ראשית, בוא נכתוב קונסטרוקטור פשוט ולא גנרי עבורנו GenericEntry מעמד:

Public GenericEntry (int int) {this.rank = rank; }

למרות ש GenericEntry הוא מחלקה כללית, זהו קונסטרוקטור פשוט שאין לו פרמטר מסוג כללי.

כעת נוכל להשתמש בבנאי זה כדי ליצור GenericEntry:

@ מבחן הריק ציבורי givenNonGenericConstructor_whenCreateGenericEntry_thenOK () {GenericEntry entry = GenericEntry new (1); assertNull (entry.getData ()); assertEquals (1, entry.getRank ()); }

3.2. קונסטרוקטור גנרי

לאחר מכן, בואו נוסיף את הבנאי השני לכיתה שלנו:

Public GenericEntry (נתוני T, דירוג int) {this.data = data; this.rank = דרגה; }

זהו קונסטרוקטור גנרי, שכן יש לו נתונים פרמטר מהסוג הגנרי ט. שים לב שאנחנו לא צריכים להוסיף בהצהרת הקונסטרוקטור, כיוון שהיא נמצאת שם במשתמע.

עכשיו, בואו נבדוק את הבנאי הגנרי שלנו:

@Test public void givenGenericConstructor_whenCreateGenericEntry_thenOK () {GenericEntry entry = GenericEntry new ("sample", 1); assertEquals ("מדגם", entry.getData ()); assertEquals (1, entry.getRank ()); }

4. קונסטרוקטור גנרי מסוג אחר

בשיעור הגנרי שלנו, אנו יכולים גם לקבל קונסטרוקטור עם סוג גנרי השונה מהסוג הגנרי של הכיתה:

ציבורי GenericEntry (אלמנט E) {this.data = (T) אלמנט; this.rank = element.getRank (); }

זֶה GenericEntry לבנאי יש פרמטר אֵלֵמֶנט עם סוג ה, שהוא שונה מה- ט סוּג. בואו נראה את זה בפעולה:

@Test public void givenGenericConstructorWithDifferentType_whenCreateGenericEntry_thenOK () {מוצר מוצר = מוצר חדש ("חלב", 2.5); product.setSales (30); ערך GenericEntry = GenericEntry חדש (מוצר); assertEquals (product, entry.getData ()); assertEquals (30, entry.getRank ()); }

ציין זאת:

  • בדוגמה שלנו, השתמשנו מוצר (ה) ליצור GenericEntry מהסוג ניתן לבצע סדרתי (ט)
  • אנו יכולים להשתמש בבנאי זה רק כאשר הפרמטר מסוג ה ניתן ללהק ל ט

5. סוגי גנריות מרובים

לאחר מכן, יש לנו את המעמד הגנרי MapEntry עם שני סוגים גנריים:

MapEntry {class K מפתח פרטי; ערך V פרטי; MapEntry ציבורי (מקש K, ערך V) {this.key = מפתח; this.value = ערך; }}

MapEntry יש בנאי גנרי אחד עם שני פרמטרים, כל אחד מסוג אחר. בואו נשתמש בזה במבחן יחידה פשוט:

@Test public void givenGenericConstructor_whenCreateGenericEntryWithTwoTypes_thenOK () {MapEntry entry = MapEntry new ("sample", 1); assertEquals ("sample", entry.getKey ()); assertEquals (1, entry.getValue (). intValue ()); }

6. כרטיסי בר

לבסוף, אנו יכולים להשתמש בתווים כלליים בבנאי גנרי:

public GenericEntry (אופציונלי אופציונלי) {if (optional.isPresent ()) {this.data = (T) optional.get (); this.rank = optional.get (). getRank (); }}

הנה, השתמשנו בכרטי בר GenericEntry בונה לאגד את אופציונאלי סוּג:

@Test public void givenGenericConstructorWithWildCard_whenCreateGenericEntry_thenOK () {מוצר מוצר = מוצר חדש ("חלב", 2.5); product.setSales (30); אופציונלי אופציונלי = Optional.of (מוצר); ערך GenericEntry = GenericEntry חדש (אופציונלי); assertEquals (product, entry.getData ()); assertEquals (30, entry.getRank ()); }

שים לב שאנחנו צריכים להיות מסוגלים להטיל את סוג הפרמטר האופציונלי (במקרה שלנו, מוצר) אל ה GenericEntry סוג (במקרה שלנו, ניתן לבצע סדרתי).

7. מסקנה

במאמר זה למדנו כיצד להגדיר ולהשתמש בבנאים גנריים בשיעורים גנריים ולא גנריים.

קוד המקור המלא ניתן למצוא באתר GitHub.


$config[zx-auto] not found$config[zx-overlay] not found