2. Umumlashgan interfeyslar.
Umumlashgan sinflar va metodlardan tashqari, C# umumlashgan interfeyslardan ham foydalanish mumkin. Bunday interfeyslar umumlashgan sinflarga o'xshash tarzda yaratiladi. Quyida ISeries interfeysi 12 bobdagi misolning o'zgartirilgan ko`rinishi keltirilgan[1,612]. (Eslatib o'tamiz, ISeries butun sonlar ketma-ketni chiqaruvchi sinf uchun interfeys.) Ushbu interfeysi amal bajaruvchi ma'lumotlar tipi parametrlar tipi bilan belgilanadi.
// Umumiy interfeysdan foydalanishning ko`rinishi.
using System;
public interface ISeries {
T GetNext();// navbatdagi sonni qaytaradi
void Reset(); // amallar bajarilayotgan sonli ketma-ketlikning boshlanishiga o`tadi
void SetStart (T v); // boshlang'ich qiymatni belgilash
}
// ISeries interfeysidan amalda foydalanish,
class ByTwos : ISeries {
T start;
T val;
// очередного элемента в ряду последовательных значений.
//Ushbu delegate ketma-ketlikning navbatdagi elementni qiymatini olish uchun //ishlatiluvchi metodning shaklini belgilaydi.
public delegate T IncByTwo(T v);
// Ushbu delegatda ByTwos sinfining konstruktoriga o'tkaziladigan metodga //havola beriladi.
IncByTwo incr;
public ByTwos(IncByTwo incrMeth) {
start = default(T);
val = default(T);
incr = incrMeth;
}
public T GetNext() {
val = incr(val);
return val;
}
public void Reset() {
val = start;
}
public void SetStart(T v) {
start = v;
val = start;
}
}
class ThreeD {
public int х.д, у, z;
public ThreeD(int a, int b, int c) {
x = a;
у = b;
z = c;
}
}
class GenlntfDemo {
// int tipidagi har bir qiymatni ikkitaga oshiruvchi metod aniqlangan.
static int IntPlusTwo(int v) {
return v + 2;
}
// double tipidagi har bir qiymatni ikkitaga oshiruvchi metod aniqlangan.
static double DoublePlusTwo(double v) {
return v + 2.0;
}
// ThreeD tipidagi ob`ektning har bir koordinata qiymatni ikkitaga oshiruvchi //metod aniqlangan.
static ThreeD ThreeDPlusTwo(ThreeD v) {
if(v==null) return new ThreeD(0, 0, 0) ;
else return new ThreeD(v.x + 2, v.у + 2, v.z + 2);
}
static void Main() {
// int tipida ammallar bajarilayotgan ketma-ketlikning qiymatlarini chiqarish //keltirilgan.
ByTwos intBT = new ByTwos(IntPlusTwo);
for(int i=0; i < 5; i++)
Console.Write (intBT.GetNext() + " ") ;
Console.WriteLine();
// double tipida ammallar bajarilayotgan ketma-ketlikning qiymatlarini chiqarish //keltirilgan.
ByTwos dblBT = new ByTwos(DoublePlusTwo);
dblBT.SetStartA1.4);
for(int i=0; i < 5; i++)
Console. Write (dblBT.GetNext() + " ") ;
Console.WriteLine ();
// ThreeD tipida ammallar bajarilayotgan berilgan ob`ektning koordinata //qiymatlarini chiqarish keltirilgan.
ByTwos ThrDBT = new ByTwos(ThreeDPlusTwo);
ThreeD coord;
for(int i=0; i < 5; i++) {
coord = ThrDBT.GetNext();
Console.Write(coord.x + "," +
coord.у + "," +
coord.z + " ");
}
Console.WriteLine();
}
}
Ushbu kod quyidagi natijani beradi.
2 4 6 8 10
13.4 15.4 17.4 19.4 21.4
0,0,0 2,2,2 4,4,4 6,6,6 8,8,8
Ushbu misoldagi kodda bir qator qiziqarli joylar mavjud. Avvalo, kodning ISeries interfeysi e'lon qilingan qatorga e'tibor beraylik.
public interface ISeries {
Yuqorida aytib o'tilganidek, umumlashtgan interfeysni e'lon qilish uchun umumlashgan sinfni e'lon qilish bilan bir xil sintaksis ishlatiladi.
Endi ByTwos sinfining keyingi e'loniga e'tibor beraylik, u ISeries interfeysini amalga oshiradi.
class ByTwos : ISeries {
T-tipli parametr nafaqat ByTwos sinfini e'lon qilishda, balki u ISeries interfeysini e'lon qilishda ham foydalanilgan. Va bu juda muhim. Axir, umumlashgan interfeysni versiyasini amalga oshiradigan sinfning o`zi ham umumlashgan bo`lishi kerak. Pastda ko`rsatilgan e`lon qilish usuli noto`g`ri, chunki birorta ham parameter T tipida aniqlanmagan.
class ByTwos : ISeries { // Noto`g`ri!
ISeries interfeysida aniqlangan argument tipini ByTwos sinfiga o'tkazilishi kerak. Aks holda, interfeys hech qanday argument tipini topa olmaydi.
Keyingi o'zgaruvchilar, keyingi ketma-ket joriy qiymatini(val) va uning boshlang'ich qiymati(start) saqlashda , umumlashgan T tipining ob'ektlari sifatida e'lon qilinadi. Shundan so'ng IncByTwo delegati e'lon qilgan. Ushbu delegat T tipdagi ob'ektda saqlangan qiymatni ikkiga oshirish uchun ishlatiladigan metod shaklini belgilaydi. ByTwos sinfi har qanday tipdagi ma'lumotlarni qayta ishlash tartibi qanday aniqlangan bo`lishiga qaramasdan har bir ma'lumotning qiymatini ikkiga oshirish nazarda tutilgan. Buning uchun ByTwos sinfining konstruktorlari qiymatni ikki barobar ko'payadigan metodga havola qilingan. Ushbu havola incr delegati o`zgaruvchisining nusxasini saqlanadi. Ketma-ketlikning keying elementi gneratsiya qilish jarayoni boshlanganda bu metod incr delegati yordamida chaqiriladi.
Endi ThreeD sinfiga e'tibor beraylik. Ushbu sinfda uch o'lchovli fazo (X,Z,Y) koordinatalari qamrab olinadi. Uning vazifasi ByTwos sinfida sinf ma'lumotlarini qayta ishlashni namoyish qilishdir.
Bundan tashqari, GenlntfDemo sinfida int, double va ThreeD kabi ob'ektlar qiymatini ikkiga oshiruvchi uchta metod e'lon qilingan. Ushbu metodlarning barchasi tegishli tipdagi ob'ektlarni yaratishda ByTwos sinfining konstruktoriga murojaat qiladi. Quyidagi ThreeDPlusTwo() metodiga alohida e'tibor beraylik.
// Metodda ThreeD tipidagi keying har bir ob'ekt koordinatalari qiymatini ikkiga //oshirish aniqlang.
static ThreeD ThreeDPlusTwo(ThreeD v) {
if(v==null) return new ThreeD(0, 0, 0);
else return new ThreeD(v.x + 2, v.у + 2, v.z + 2);
}
Ushbu metodda birinchi navbatda v o'zgaruvchi namunasini bo'sh qiymat (null)ga tekshiradi. Agar u bu qiymatni o'z ichiga olgan bo'lsa, metod ThreeD tipdagi ob'ektni yangi barcha koordinatalari nolga teng qiymatlar bilan qaytaradi. Aslida, v o'zgaruvchiga standart tipda berilgan default(T)qiymat ByTwos sinfning konstruktorida tayinlangan. Ushbu qiymat qiymatli tiplar uchun standart holda nolga teng bo'lib va ob'ektlarga havola(kursatgich) tiplari uchun bo'sh bo'ladi. Shuning uchun, agar SetStart() metodi oldindan chaqirilmagan bo'lsa, o'zgaruvchining qiymatini ikkiga oshirishdan oldin v ob'ektga havola bo'sh qiymat ega bo`ladi. Bu shuni anglatadiki, birinchi marta qiymatni ikki barobar oshirish uchun yangi ob'ekt talab qilinadi.
Umumlashgan interfeysdagi parametr tipiga ham umumlashgan sinfda bo'lgani kabi cheklovlar qo'llanilishi mumkin. Quyidagi misolda ISeries interfeysini e'lon qilishning faqat ko`rsatgich tiplarini ishlatish uchun cheklovlar variant keltirilgan.
public interface ISeries where T : class {
Agar ISeries interfeysining bunday versiyasi amalga oshirilsa, uni amalga oshiruvchi sinfda quyida ko'rsatilganidek, T tipidagi parametrga bir xil cheklovni ko'rsatilishi kerak.
class ByTwos : ISeries where T : class {
Malumot tipi cheklanganligi sababli, ISeries interfeysining ushbu versiyasi qiymat tiplariga qo'llanilishi mumkin emas. Shuning uchun, agar siz uni bu yerda ko'rib chiqilayotgan dastur misolida amalga oshirsangiz, faqat ByTwos e`lonini qabul qiladi, lekin ByTwos va ByTwose`lonlarini qabul qilmaydi.
Foydalanildi:
1. Герберт Шилдт. С# 4.0: полное руководство. Пер. с англ. — М.: ООО "И.Д. Вильяме", 2011.
Do'stlaringiz bilan baham: |