Bicara tentang kelas dan objek di Delphi
1. Tidak dapat memahami beberapa konsep tanpa dididik.
Berbicara tentang kelas dan objek, kita tidak bisa tidak menyebutkan konsep berikut: kelas, objek, dan instance. Menurut saya pribadi, tidak apa-apa
Pahami seperti ini: objek mengacu pada istilah umum, dan entitas apa pun di alam dapat dianggap sebagai objek, sedangkan kelas mengacu pada istilah tersebut
Serangkaian kategori yang terbagi atas ciri-ciri tertentu dari objek tersebut, suatu instance merujuk secara khusus pada suatu objek yang termasuk dalam kategori tertentu;
Oke, saya tidak perlu bicara lebih banyak lagi tentang prinsip-prinsip besar ini. Mengapa tidak mengambil pendekatan yang "berlawanan", mari gunakan Delphi
kode untuk menjelaskan beberapa konsep yang dikemukakan oleh orang asing ini yang sulit dipahami oleh kita orang Cina:
var
ABtn:Tombol;
Definisikan ABtn sebagai objek yang termasuk dalam kelas TButton, namun ABtn tidak dapat dikatakan sebagai instance karena belum
dibuat, jadi kita katakan bahwa suatu objek didefinisikan. Jika sebuah instance didefinisikan, lebih atau kurang
Beberapa tidak cukup tepat. :)
mulai
ABtn:=TButton.Create(Self);//Buat sebuah instance dari TButton
ABtn.Caption:='objek';
ABtn.Gratis;
akhir;
2. Objeknya adalah penunjuk keluar-keluar
Dari sudut pandang fisik, objek adalah ruang alamat, dan simbol dari ruang alamat inilah yang kita definisikan.
Kelas "Variabel". Jadi kita bisa menganggap suatu objek sebagai penunjuk ke suatu kelas. Seperti yang kita ketahui bersama, untuk mengakses sebuah pointer saja
Pointer harus diinisialisasi. Karena objeknya adalah pointer, maka harus diinisialisasi. Bagaimana cara menginisialisasinya?
Mari kita bicara tentang inisialisasi pointer. Ada dua cara untuk menginisialisasi pointer:
(1) Distribusi langsung
var
Pint:^Bilangan Bulat;
mulai
baru(Pint);
Pint^:=12;
Buang(Pint);
akhir;
(2) Variabel yang menunjuk ke ruang lain yang dialokasikan
var
Pint:^Bilangan Bulat;
saya: bilangan bulat;
mulai
saya:=12;
Pint:=@i;
akhir;
Menariknya, ada dua cara untuk menginisialisasi "pointer" seperti objek:
(1) Distribusi langsung
var
Bentuk:TForm;
mulai
AForm:=TForm.Create(Self);
AForm.ShowModal;
AForm.Gratis;
akhir;
(2) Tunjukkan contoh ruang lain yang dialokasikan
var
Bentuk:TForm;
mulai
AForm:=Diri;
AForm.Caption:='Tahukah anda? Mengapa ini terjadi';
akhir;
file://AForm ini dan instance Formulir yang ditunjuknya berbagi unit alamat yang sama, dan semua operasi di AForm akan merespons
file:// ke instance Formulir yang sesuai.
Omong-omong, kita dapat dengan mudah menjelaskan mengapa parameter objek dari prosedur (fungsi) diteruskan dalam format seperti ini:
(1)Prosedur SetEdit(var Edit:TEdit);
mulai
Sunting.Teks:='11';
akhir;
Dan
(2) prosedur SetEdit(Edit:TEdit);
mulai
Sunting.Teks:='11';
akhir;
Efeknya sama. (1) adalah meneruskan entitas TEdit sebagai referensi parameter, (2) adalah
Berikan "pointer" objek TEdit sebagai parameter.
3. Kelas dapat dipahami sebagai tipe data khusus
Kita tahu bahwa tipe data dapat dipaksa untuk mengetikkan konversi. Karena kelas dapat dipahami sebagai tipe data, maka
Maka ia juga harus dapat melakukan konversi tipe kelas. Misalnya, kode berikut adalah event klik pada sebuah tombol (Tombol1):
(satu)
prosedur TForm1.Button1Click(Pengirim: TObject);
var
Keterangan:String;
mulai
ACaption:=TButton(Sender).Caption;//Sender mengkonversi dari TObject ke TButton
ShowMessage(Format('Anda mengklik ''%s'' !',[ACaption]));
akhir;
Dalam kode ini, Pengirim adalah objek bertipe TObject, dan kami mentransmisikannya ke tipe TButton. seperti kamu
Jika Anda tidak dapat melihat dengan jelas, Anda dapat merujuk pada konversi tipe data yang biasa kami lakukan:
(dua)
prosedur TForm1.Button1Click(Pengirim: TObject);
var
S_Str:String;
P_Str:PChar;
mulai
S_Str:='Saya suka Tiongkok!';
P_Str:=PChar(S_Str);
S_Str:='';
S_Str:=String(P_Str);
Tampilkan Pesan (S_Str);
akhir;
Namun, dalam proses pemrograman berorientasi objek, penekanannya adalah pada keselamatan. Misalnya, konversi tipe paksa pada (1) memiliki banyak masalah.
Keamanan. Kode berikut masih menulis event Button1.OnClick:
(tiga)
prosedur TForm1.Button1Click(Pengirim: TObject);
mulai
TCanvas(Pengirim).Kuas.Warna:=clMerah;
akhir;
Jika Anda menjalankannya, kesalahan akan terjadi. Bukankah ini melanggar tujuan pemrograman berorientasi objek? Tidak, tentu saja
Jika berupa kelas, harus ada metode pemaksaan kelas khusus kelas. Cara mengubah (3) adalah sebagai berikut:
(Empat)
prosedur TForm1.Button1Click(Pengirim: TObject);
mulai
(Pengirim sebagai TCanvas).Brush.Color:=clRed;
end;//Gunakan as untuk mengonversi, karena dapat menangkap kesalahan dan tidak akan mempengaruhi pengoperasian normal program.
Omong-omong, izinkan saya menyebutkan VB. Jika Anda telah mempelajari VB, Anda mungkin merasa susunan kontrol di dalamnya lebih menyenangkan, terutama di
Saat menulis program seperti kalkulator. Tapi apa yang Delphi berikan kepada kita? Jawabannya Delphi juga bisa dibuka dengan cepat dan ringkas.
Keluarkan program seperti itu. Jika Anda melakukan ini: letakkan Edit dan sepuluh Tombol pada formulir, bagi Button.Caption menjadi
Jangan setel ke '0', '1', '2',...'9', lalu tulis event OnClick pada tombol sebagai berikut:
(lima)
prosedur TForm1.Button1Click(Pengirim: TObject);
mulai
Edit1.Teks:=Edit1.Teks+(Pengirim sebagai TButton).Caption;
akhir;
Kaitkan peristiwa OnClick dari Tombol lain ke Button1Click dan jalankan program. Tepuk tanganmu! Kalkulator ini
Prototipe program ini sekarang telah tersedia. Kami menggunakan konversi tipe kelas Delphi untuk mengembangkan fungsi array kontrol yang serupa dengan yang ada di VB.
Programnya juga bagus :)
4. Kelas abstrak dan instance-nya
Ada kelas di Delphi yang disebut kelas abstrak, dan Anda tidak dapat secara naif membuat turunannya secara langsung. Seperti: TStrings
baik. Kode berikut:
(satu)
var
StrLst:Tstring;
mulai
StrLst:=TStrings.Buat;
StrLst.Add('Saya suka Jepang!');
StrLst.Gratis;
akhir;
Ini tidak benar. Jadi bagaimana Anda membuat instance kelas abstrak seperti TStrings? Jawabannya adalah dengan menggunakan yang non-pompa
Subkelas gajah. Kita tahu bahwa TStrings memiliki subkelas TStringList yang non-abstrak. Kita bisa melakukan ini:
(dua)
var
StrLst:Tstring;
mulai
StrLst:=TStringList.Create;//Subkelas StrLst dengan bantuan konstruktor subkelasnya
StrLst.Add('Saya suka Cina!');
StrLst.Gratis;
akhir;
(tiga)
var
StrLst:TStringList;
mulai
StrLst:=TStringList.Buat;
file://Menyerah, jangan gunakan kelas abstrak lagi, gunakan saja "anaknya" untuk menjalankan bisnis Anda
StrLst.Add('Saya suka Cina!');
StrLst.Gratis;
akhir;
5. Kelas adalah mekanisme yang sangat merangkum data dan operasi.
(1) Enkapsulasi data
satuan Unit2;
antarmuka
jenis
Karyawan TE=kelas
pribadi
NamaF:String;
publik
Buat Konstruktor;
fungsi DapatkanNama:String;
prosedur SetName(AName:String);
akhir;
pelaksanaan
{ Karyawan }
konstruktor TEmployee.Create;
mulai
FName:='Api Berkobar';
akhir;
fungsi TEmployee.GetName: String;
mulai
Hasil:=NamaF;
akhir;
prosedur TEmployee.SetName(AName: String);
mulai
NamaF:=NamaA;
akhir;
akhir.
Seperti yang ditunjukkan pada kode di atas, kami menggunakan prosedur SetName dan fungsi GetName untuk menyetel sepenuhnya variabel pribadi FName.
Enkapsulasi. Ini yang perlu kita lakukan dengan FName:
kegunaan
satuan2;
prosedur TForm1.Button1Click(Pengirim: TObject);
var
AKaryawan:TEKaryawan;
mulai
AEmployee:=TEkaryawan.Buat;
AEmployee.SetName('Rose');//Gunakan SetName untuk menyetel FName
MessageBox(Handle,PCar(AEmployee.GetName),'Empoyee',0);
file://Gunakan GetName untuk mengakses FName
AKaryawan.Gratis;
akhir;
(2) Operasi enkapsulasi
satuan Unit2;
antarmuka
jenis
Divisi T=Kelas
publik
file://polymorphism membuat program Anda lebih "fleksibel"
fungsi GetDiv(Nomor1,Nomor2:Ganda):Ganda;kelebihan beban;
fungsi GetDiv(Nomor1,Nomor2:integer):integer;kelebihan beban;
akhir;
pelaksanaan
{ Divisi }
fungsi TDivision.GetDiv(Nomor1, Nomor2: Ganda): Ganda;
mulai
mencoba
Hasil:=Nomor1/Nomor2;
kecuali
Hasil:=0;//Menyediakan mekanisme pemrosesan poin untuk menangani situasi ketika pembaginya adalah 0
akhir;
akhir;
fungsi TDivision.GetDiv(Nomor1, Angka2: bilangan bulat): bilangan bulat;
mulai
mencoba
Hasil:=Nomor1 div Nomor2;
kecuali
Hasil:=0;//Menyediakan mekanisme pemrosesan poin untuk menangani situasi ketika pembaginya adalah 0
akhir;
akhir;
akhir.
Dalam kode di atas, kita menggunakan mekanisme polimorfisme kelas untuk memproses pembagian menjadi pembagian bilangan bulat dan pembagian non-bilangan bulat, dan menggunakan layar penanganan pengecualian.
Untuk menghilangkan case yang angkanya 0, untuk menjamin keamanan operasi, saat menelepon, kita bisa melakukannya seperti ini:
kegunaan
satuan2;
{$R *.dfm}
prosedur TForm1.Button1Click(Pengirim: TObject);
var
Divisi: Divisi T;
Nilai IV: bilangan bulat;
Nilai F: Ganda;
mulai
Divisi:=TDivision.Create;
IVvalue:=Divisi.GetDiv(1,2);
Nilai F:=Divisi.GetDiv(1.0,2);
IVvalue:=Divisi.GetDiv(1,0);
Nilai F:=Divisi.GetDiv(1.0,0);
Divisi.Gratis;
akhir;
6. Kelas adalah mekanisme penggunaan kembali kode
Misalnya, di 5, jika kita ingin menambahkan fungsi GetAdd ke kelas ini untuk melakukan operasi penambahan, kita bisa menggunakan pewarisan kelas. menyukai
Tulis saja:
(satu)
satuan Unit2;
antarmuka
jenis
Divisi T=Kelas
publik
fungsi GetDiv(Nomor1,Nomor2:Ganda):Ganda;kelebihan beban;
fungsi GetDiv(Nomor1,Nomor2:integer):integer;kelebihan beban;
akhir;
jenis
TOperasi=Kelas(Divisi T)
publik
fungsi GetAdd(Nomor1,Nomor2:Ganda):Ganda;
akhir;
pelaksanaan
{ Divisi }
fungsi TDivision.GetDiv(Nomor1, Nomor2: Ganda): Ganda;
mulai
mencoba
Hasil:=Nomor1/Nomor2;
kecuali
Hasil:=0;
akhir;
akhir;
fungsi TDivision.GetDiv(Nomor1, Angka2: bilangan bulat): bilangan bulat;
mulai
mencoba
Hasil:=Nomor1 div Nomor2;
kecuali
Hasil:=0;
akhir;
akhir;
{TOPperasi}
fungsi TOperation.GetAdd(Nomor1, Nomor2: Ganda): Ganda;
mulai
Hasil:=Bilangan1+Bilangan2;
akhir;
akhir.
Di sini kita mewarisi subkelas TOPerasi dari TDivision. TOperation dapat memiliki TDivsion
Metode publik GetDiv memiliki metode uniknya sendiri, GetAdd. Ini adalah kelas "makan kuemu dan makan juga" untuk kita.
Metode "Dapatkan".