Menu
CoddyTech

Urutan Pencarian method

Termasuk bagian Pemrograman Berorientasi Object dalam perjalanan R di Coddy. Pelajaran 13 dari 57.

Untuk setiap pemanggilan, R menelusuri vektor class dari kiri ke kanan dan menjalankan method pertama yang ditemukan. Jika tidak ada class yang memiliki method, R menggunakan default. Object yang berbeda dalam satu hierarki dapat berhenti pada tingkat yang berbeda:

move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.default <- function(x) "stays"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
dog <- structure(list(), class = c("dog", "animal"))
rock <- structure(list(), class = "rock")
cat(move(penguin), move(dog), move(rock))

Output:

flies walks stays

Anak mengganti method induk dengan mendefinisikan method sendiri. Penggantian ini hanya memengaruhi anak dan apa pun di bawahnya; induk dan anak-anaknya yang lain tetap menggunakan method induk:

move <- function(x) UseMethod("move")
move.animal <- function(x) "walks"
move.bird <- function(x) "flies"
move.penguin <- function(x) "swims"
penguin <- structure(list(), class = c("penguin", "bird", "animal"))
sparrow <- structure(list(), class = c("bird", "animal"))
cat(move(penguin), move(sparrow))

Output:

swims flies

Setiap generic dicari secara terpisah. Satu object dapat menggunakan sound() dari class-nya sendiri dan move() dari parent, lalu sebuah method parent dapat memanggil generic lain yang kembali melakukan dispatch pada child:

sound <- function(x) UseMethod("sound")
move <- function(x) UseMethod("move")
describe <- function(x) UseMethod("describe")
sound.animal <- function(x) "..."
sound.dog <- function(x) "woof"
move.animal <- function(x) "walks"
describe.animal <- function(x) paste(x$name, "says", sound(x), "and", move(x))
rex <- structure(list(name = "Rex"), class = c("dog", "animal"))
print(describe(rex))

Output:

[1] "Rex says woof and walks"

Untuk object dengan atribut class, dispatch hanya melihat atribut itu lalu default. Object tersebut tetap merupakan list di dalamnya, tetapi method untuk list tidak dicoba:

size <- function(x) UseMethod("size")
size.list <- function(x) "a list"
size.default <- function(x) "default"
bag <- structure(list(1, 2), class = "bag")
cat(size(list(1, 2)), "/", size(bag))

Output:

a list / default
challenge icon

Tantangan

Mudah

Persegi adalah rectangle dengan sisi yang sama panjang. Di Rectangle.R, tulis method area.rectangle(), perimeter.rectangle(), dan name.rectangle(), yang mengembalikan rectangle 2x3. Di Square.R, lengkapi new_square(side), yang memanggil new_rectangle() dengan class square, lalu hanya override name() dengan name.square(), yang mengembalikan square 2. Persegi harus menggunakan area() dan perimeter() milik rectangle.

Fungsi generik dan new_rectangle() sudah disediakan. Kode yang disediakan membaca baris dengan dua angka (rectangle) atau satu angka (persegi), lalu mencetak square 2: area 4, perimeter 8.

Tuliskan kodemu di Rectangle.R dan Square.R. main.R berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

source("Rectangle.R")
source("Square.R")

# Kode input/output yang disediakan: biarkan tetap seperti ini
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
  n <- as.numeric(strsplit(line, " ")[[1]])
  s <- if (length(n) == 1) new_square(n[1]) else new_rectangle(n[1], n[2])
  cat(name(s), ": area ", area(s), ", perimeter ", perimeter(s), "\n", sep = "")
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Object

Latihan sendiri: Compiler R online