Dalam teori bahasa pemrograman, suatu tipe adalah sekumpulan nilai. Misalnya jenis "int" adalah himpunan semua nilai integer.
Dalam bahasa OOP, kelas adalah tipe, bukan?
Ketika suatu kelas didefinisikan dengan lebih dari satu anggota, mis
class myclass{
int a;
double b;
}
Ketika kita berbicara tentang kelas, maksud kita
- "Di
(a,b)
manaa
int danb
dobel", atau - "{
(x,y)
|x
apakah ada int,y
apakah ada dobel}"?
Apa arti dari instance myclass
?
- "Di
(a,b)
manaa
int danb
dobel", atau - sebuah objek yang menempati ruang memori dan yang dapat (tidak harus, yaitu bisa kosong) disimpan
(x,y)
, di manax
ada int dany
ada yang ganda?
a
danb
anggota dari jenis itu, seperti yang disebutkan Killian Forth. Myclass isomorfis untuk catatan dengan bidanga
danb
jenisint
dandouble
- Anda dapat mengambil catatan seperti itu dan mengubahnya menjadi turunan darimyclass
Jawaban:
Tidak juga.
Saya kira Anda bertanya apakah memiliki jenis bidang yang sama sudah cukup untuk diklasifikasikan sebagai kelas yang sama, atau apakah mereka harus dinamai secara identik juga. Jawabannya adalah: "Bahkan tidak memiliki tipe yang sama dan nama yang sama sudah cukup!" Kelas yang secara struktural setara tidak harus kompatibel dengan tipe.
Misalnya, jika Anda memiliki kelas
CartesianCoordinates
dan aPolarCordinates
, mereka mungkin memiliki dua angka sebagai bidang mereka, dan mereka mungkin bahkan memilikiNumber
tipe dan nama yang sama, tetapi mereka masih tidak kompatibel, dan sebuah instance dariPolarCoordinates
tidak akan menjadi contoh dariCartesianCoordinates
. Kemampuan untuk memisahkan jenis dengan tujuan yang dimaksudkan dan bukan implementasi mereka saat ini adalah bagian yang sangat berguna dari penulisan kode yang lebih aman, lebih dapat dikelola.sumber
interface
di Java dan C # jika Anda ingin melakukan pengujian unit. Anda akhirnya menulis satu ton boilerplate hanya agar Anda dapat mengubah kelas tertentu yang akan digunakan program Anda meskipun Anda tidak memiliki niat untuk mengubahnya saat runtime.Jenis tidak disetel.
Anda lihat, teori himpunan memiliki sejumlah fitur yang tidak berlaku untuk jenis, dan sebaliknya . Sebagai contoh, suatu objek memiliki tipe kanonik tunggal. Ini mungkin merupakan instance dari beberapa tipe yang berbeda, tetapi hanya salah satu dari tipe tersebut yang digunakan untuk instantiate. Teori himpunan tidak memiliki gagasan tentang perangkat "kanonik".
Teori himpunan memungkinkan Anda membuat himpunan bagian dengan cepat , jika Anda memiliki aturan yang menjelaskan apa yang menjadi bagian dari himpunan bagian. Teori tipe umumnya tidak mengizinkan ini. Sementara sebagian besar bahasa memiliki
Number
jenis atau sesuatu yang serupa, mereka tidak memilikiEvenNumber
jenis, juga tidak mudah untuk membuatnya. Maksud saya, cukup mudah untuk mendefinisikan tipe itu sendiri, tetapi setiapNumber
s yang ada bahkan tidak akan secara ajaib diubah menjadiEvenNumber
s.Sebenarnya, mengatakan bahwa Anda dapat "membuat" himpunan bagian agak tidak jujur, karena himpunan adalah jenis hewan yang berbeda sama sekali. Dalam teori himpunan, himpunan bagian itu sudah ada , dalam semua cara tak terbatas Anda dapat mendefinisikannya. Dalam teori tipe, kita biasanya berharap berhadapan dengan sejumlah tipe yang terbatas (jika besar) pada waktu tertentu. Satu-satunya tipe yang dikatakan ada adalah yang sudah kita tentukan, tidak setiap jenis yang bisa kita definisikan.
Perangkat tidak diizinkan untuk memuat diri mereka secara langsung atau tidak langsung . Beberapa bahasa, seperti Python, menyediakan tipe-tipe dengan struktur yang kurang teratur (dalam Python,
type
tipe kanoniknya adalahtype
, danobject
dianggap sebagai turunan dariobject
). Di sisi lain, sebagian besar bahasa tidak mengizinkan tipe yang ditentukan pengguna untuk terlibat dalam tipu daya semacam ini.Set biasanya diizinkan untuk tumpang tindih tanpa terkandung satu sama lain. Ini tidak biasa dalam teori tipe, meskipun beberapa bahasa mendukungnya dalam bentuk pewarisan berganda. Bahasa lain, seperti Java, hanya mengizinkan bentuk terbatas ini atau melarangnya sama sekali.
Tipe kosong ada (ini disebut tipe bawah ), tetapi sebagian besar bahasa tidak mendukungnya, atau tidak menganggapnya sebagai tipe kelas satu. "Tipe yang berisi semua tipe lain" juga ada (ini disebut tipe teratas ) dan didukung secara luas, tidak seperti teori himpunan.
NB : Seperti yang ditunjukkan beberapa komentator sebelumnya (sebelum utas dipindahkan ke obrolan), dimungkinkan untuk memodelkan tipe dengan teori himpunan dan konstruksi matematika standar lainnya. Misalnya, Anda bisa memodelkan tipe keanggotaan sebagai relasi daripada memodelkan tipe sebagai set. Namun dalam praktiknya, ini jauh lebih sederhana jika Anda menggunakan teori kategori daripada teori himpunan. Ini adalah contoh bagaimana Haskell memodelkan teori tipenya.
Gagasan "subtyping" benar-benar sangat berbeda dari gagasan "subset." Jika
X
ini adalah subtipe dariY
, itu berarti kita dapat mengganti instanceY
untuk instanceX
dan program akan tetap "berfungsi" dalam beberapa hal. Ini lebih bersifat perilaku daripada struktural, meskipun beberapa bahasa (misalnya Go, Rust, bisa dibilang C) telah memilih yang terakhir karena alasan kenyamanan, baik untuk programmer atau implementasi bahasa.sumber
Tipe data aljabar adalah cara untuk membahas hal ini.
Ada tiga cara mendasar yang bisa Anda gabungkan jenis:
Produk. Pada dasarnya itulah yang Anda pikirkan:
adalah jenis produk; nilainya semua kombinasi yang mungkin (yaitu tupel) dari satu
int
dan satudouble
. Jika Anda mempertimbangkan tipe angka sebagai set, maka kardinalitas dari tipe produk sebenarnya adalah produk dari kardinalitas field.Jumlah. Dalam bahasa prosedural, ini agak canggung untuk diekspresikan secara langsung (klasiknya dilakukan dengan serikat yang ditandai ), jadi untuk pemahaman yang lebih baik, berikut adalah jenis jumlah di Haskell:
nilai-nilai dari tipe ini memiliki bentuk
AnInt 345
, atauADouble 4.23
, tetapi selalu ada hanya satu angka yang terlibat (tidak seperti untuk jenis produk, di mana setiap nilai memiliki dua angka). Jadi kardinalitas: pertama-tama Anda menghitung semuaInt
nilai, masing-masing harus digabungkan denganAnInt
konstruktor. Plus , semuaDouble
nilai, masing-masing digabungkan denganADouble
. Oleh karena itu tipe penjumlahan .Eksponensial 1 . Saya tidak akan membahasnya secara rinci di sini karena tidak memiliki korespondensi OO yang jelas sama sekali.
Jadi bagaimana dengan kelas? Saya sengaja menggunakan kata kunci
struct
alih-alihclass
untukIntXDouble
. Masalahnya, kelas sebagai tipe tidak benar-benar ditandai oleh bidangnya, itu hanyalah detail implementasi. Faktor krusialnya adalah, nilai apa yang dapat dibedakan oleh kelas.Apa yang relevan adalah, nilai suatu kelas dapat menjadi nilai dari semua subkelasnya ! Jadi suatu kelas sebenarnya adalah tipe penjumlahan dari pada tipe produk: jika
A
danB
keduanya berasalmyClass
, makamyClass
dasarnya adalah jumlah dariA
danB
. Terlepas dari implementasi yang sebenarnya.1 Ini fungsi (dalam arti matematika! ); tipe fungsi
Int -> Double
diwakili oleh eksponensialDouble
Int
. Buruk jika bahasa Anda tidak memiliki fungsi yang tepat ...sumber
static
metode, kecuali mereka masih bukan nilai kelas satu. Hal tentang kebanyakan bahasa OO adalah bahwa mereka mengambil objek sebagai blok bangunan terkecil, jadi jika Anda ingin sesuatu yang lebih kecil Anda harus memalsukannya dengan objek, dan Anda masih harus menyeret banyak fungsi semantik yang seharusnya tidak dimiliki. Misalnya tidak masuk akal untuk membandingkan fungsi untuk kesetaraan, tetapi Anda masih dapat membandingkan dua objek fungsi palsu.Maaf tapi saya tidak tahu tentang teori "mentah". Saya hanya bisa memberikan pendekatan praktis. Saya harap ini dapat diterima di programer.SE; Saya tidak terbiasa dengan etiket di sini.
Tema sentral OOP adalah menyembunyikan informasi . Apa data anggota suatu kelas, tepatnya, seharusnya tidak menarik bagi kliennya. Seorang klien mengirim pesan ke (memanggil metode / fungsi anggota) sebuah instance, yang mungkin atau mungkin tidak mengubah keadaan internal. Idenya adalah bahwa internal kelas mungkin berubah, tanpa klien terpengaruh olehnya.
Yang perlu diperhatikan adalah bahwa kelas bertanggung jawab untuk memastikan bahwa perwakilan internalnya tetap "valid". Mari kita asumsikan kelas yang menyimpan nomor telepon (disederhanakan) dalam dua bilangan bulat:
Ini adalah data anggota kelas. Namun, kelas mungkin akan lebih dari sekedar anggota datanya, dan tentu saja tidak dapat didefinisikan sebagai "set semua nilai yang mungkin dari int x int". Anda seharusnya tidak memiliki akses langsung ke anggota data.
Konstruksi sebuah instance dapat menolak angka negatif apa pun. Mungkin konstruksi juga akan menormalkan areacode dengan cara tertentu, atau bahkan memverifikasi seluruh nomor. Dengan demikian Anda akan berakhir lebih dekat dengan Anda
"(a,b) where a is an int and b is a double"
, karena tentu saja tidak ada dua int yang disimpan di kelas itu.Tapi itu tidak terlalu penting sejauh menyangkut kelas. Bukan tipe anggota data, atau rentang nilai yang mungkin yang mendefinisikan kelas, melainkan metode yang ditentukan untuknya.
Selama metode tersebut tetap sama, implementor dapat mengubah tipe data menjadi floating point, BIGNUMs, string, apa pun, dan untuk semua tujuan praktis, itu masih akan menjadi kelas yang sama .
Ada desain patters untuk memastikan bahwa perubahan representasi internal tersebut dapat dilakukan tanpa klien bahkan menyadarinya (misalnya idiom jerawat di C ++, yang menyembunyikan setiap anggota data di belakang pointer buram ).
sumber
It is neither the type of the data members, nor the range of their possible values that defines the class, it's the methods that are defined for it.
Anggota data tidak mendefinisikan kelas hanya ketika Anda menyembunyikannya. Itu mungkin kasus yang paling umum, tetapi tentu saja tidak dapat dikatakan bahwa itu berlaku untuk semua kelas. Jika bahkan satu bidang bersifat publik, itu sama pentingnya dengan metodenya.class
es. (Menandai merekafinal
membantu mendapatkan titik, tapi tetap). Anda masih memiliki masalah denganprotected
anggota, yang dapat diwarisi dan dengan demikian membentuk bagian dari API kedua untuk pelaksana subkelas.protected
mungkin dalam praktik. ;-))class
adalah konstruksi yang bergantung pada bahasa. Sejauh yang saya tahu tidak ada yang namanyaclass
teori tipe.Sebuah jenis adalah deskripsi dari kategori / berkisar dari nilai-nilai, struktur senyawa, atau apa pun. Jika demikian, ini mirip dengan "antarmuka". (Dalam pengertian bahasa-agnostik. Bahasa-spesifik, tidak begitu banyak. Di Jawa, misalnya,
int
adalah tipe , tetapi tidak ada hubungannya denganinterface
. Spesifikasi bidang publik / dilindungi, juga, bukan bagian dariinterface
, tetapi merupakan bagian dari "antarmuka" atau tipe .)Poin utamanya adalah, ini lebih merupakan definisi semantik dari pada yang konkret. Struktur hanya faktor karena bidang / perilaku yang terungkap dan tujuan yang ditetapkannya selaras. Jika Anda tidak memiliki keduanya, Anda tidak memiliki kompatibilitas tipe.
Sebuah kelas adalah realisasi dari tipe. Ini adalah template yang benar-benar mendefinisikan struktur internal, perilaku terlampir, dll.
sumber