setValidity dan validObject
Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan R di Coddy. Pelajaran 30 dari 57.
setValidity("Class", function(object) ...) menambahkan aturan validitas setelah class dideklarasikan, sehingga pemanggilan setClass() yang panjang tetap singkat. Seperti setGeneric(), fungsi ini mengembalikan nilai yang dicetak di tingkat teratas, jadi bungkus dengan invisible():
setClass("Account", slots = c(owner = "character", balance = "numeric"))
invisible(setValidity("Account", function(object) {
if (object@balance < 0) return("balance must not be negative")
TRUE
}))
msg <- tryCatch(new("Account", owner = "Ada", balance = -1), error = function(e) conditionMessage(e))
cat(msg)Output:
invalid class “Account” object: balance must not be negativePerubahan harus dilakukan melalui method yang memeriksa hasilnya. Method withdraw() mengubah slot, memanggil validObject(), dan mengembalikan object hanya jika masih valid:
setClass("Account", slots = c(balance = "numeric"))
invisible(setValidity("Account", function(object) {
if (object@balance < 0) "balance must not be negative" else TRUE
}))
invisible(setGeneric("withdraw", function(acc, amount) standardGeneric("withdraw")))
setMethod("withdraw", "Account", function(acc, amount) {
acc@balance <- acc@balance - amount
validObject(acc)
acc
})
a <- new("Account", balance = 50)
a <- withdraw(a, 20)
msg <- tryCatch({ a <- withdraw(a, 100); "done" }, error = function(e) "refused")
cat(msg, a@balance)Output:
refused 30Sepasang accessor dapat dibuat dari generic: balance(x) membaca dan generic pengganti "balance<-" menulis. Method-nya memeriksa object, jadi balance(a) <- -5 ditolak seperti perubahan buruk lainnya:
setClass("Account", slots = c(balance = "numeric"),
validity = function(object) if (object@balance < 0) "balance must not be negative" else TRUE)
invisible(setGeneric("balance", function(x) standardGeneric("balance")))
invisible(setGeneric("balance<-", function(x, value) standardGeneric("balance<-")))
setMethod("balance", "Account", function(x) x@balance)
setMethod("balance<-", "Account", function(x, value) {
x@balance <- value
validObject(x)
x
})
a <- new("Account", balance = 10)
balance(a) <- 25
msg <- tryCatch({ balance(a) <- -5; "changed" }, error = function(e) "refused")
cat(balance(a), msg)Output:
25 refusedvalidObject(x, test = TRUE) tidak berhenti. Fungsi ini mengembalikan TRUE untuk object yang valid, atau teks masalahnya, yang berguna untuk laporan:
setClass("Box", slots = c(w = "numeric"),
validity = function(object) if (object@w <= 0) "w must be positive" else TRUE)
b <- new("Box", w = 2)
print(validObject(b, test = TRUE))
b@w <- 0
print(validObject(b, test = TRUE))Output:
[1] TRUE
[1] "w must be positive"Tantangan
Mudahclass Account di Account.R memiliki slot owner dan balance. Lengkapi file ini:
- tambahkan aturan dengan
setValidity()(dibungkus dalaminvisible()) yang mengembalikanowner must not be emptyataubalance must not be negative; - buat generic
deposit(acc, amount)danwithdraw(acc, amount)beserta methodAccount-nya:depositmenghentikan proses denganamount must be positive(gunakancall. = FALSE) untuk jumlah 0 atau kurang; keduanya mengubah saldo, memanggilvalidObject(), lalu mengembalikan akun; - tambahkan method
show()yang mencetakada: 50dan baris baru.
Kode yang disediakan membaca pemilik, lalu baris dep 50 atau wd 20, dan mencetak akun setelah setiap perubahan atau refused: beserta masalahnya.
Tulis kodemu di Account.R. main.R berisi kode input/output yang disediakan dan tidak boleh diedit.
Coba sendiri
source("Account.R")
# Kode input/output yang disediakan: biarkan apa adanya
input <- suppressWarnings(readLines(file("stdin")))
acc <- tryCatch(new("Account", owner = input[1], balance = 0),
error = function(e) { cat("error: ", sub(".*object: ", "", conditionMessage(e)), "\n", sep = ""); NULL })
if (!is.null(acc)) {
for (line in input[-1]) {
p <- strsplit(line, " ")[[1]]
amount <- as.numeric(p[2])
acc <- tryCatch({
changed <- if (p[1] == "dep") deposit(acc, amount) else withdraw(acc, amount)
print(changed)
changed
}, error = function(e) {
cat("refused: ", sub(".*object: ", "", conditionMessage(e)), "\n", sep = "")
acc
})
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Object
1Dasar S3
Bekerja dengan fileList dengan classFungsi KonstruktorMethod print dan formatValidator dan helperUlasan: Suhu4Enkapsulasi di R
Closure sebagai objectEnvironment sebagai objectFungsi accessorMelindungi stateRangkuman: Meter Parkir2S3 Generics dan Method
Generics dan UseMethodMethod DefaultMethod untuk Base GenericsDasar-Dasar NextMethodRekap: Luas Bangun5S4 class
Mendefinisikan class S4Slots dan AksesPemeriksaan ValiditasMethod showRingkasan: Katalog Produk8Kelas Referensi
Mendefinisikan Kelas ReferensiPembaruan method dan fieldSemantik PenyalinanPewarisan dan callSuperRangkuman: Antrean Tugas11Proyek: Manajemen Perpustakaan
Buku dan AnggotaMeminjam Buku3Pewarisan S3
Vektor classUrutan Pencarian methodMemperluas dengan NextMethodMemeriksa dengan inherits()Ulasan: Penggajian Staf6S4 Generik dan method
Membuat Generikmethod untuk Fitur BawaanDispatch Berdasarkan Dua ArgumensetValidity dan validObjectRangkuman: Uang dan Mata UangLatihan sendiri: Compiler R online