Classes Virtuais
Parte da seção Programação Orientada a Objetos do Journey de R da Coddy. Lição 34 de 57.
Uma classe virtual descreve o que uma família de classes tem em comum e não pode ter objetos próprios. Declare-a com representation("VIRTUAL"); suas subclasses usam contains normalmente:
setClass("Shape", representation("VIRTUAL"))
setClass("Circle", contains = "Shape", slots = c(r = "numeric"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
cat(isVirtualClass("Shape"), is(new("Circle", r = 1), "Shape"), "\n")
cat(tryCatch({ new("Shape"); "made" }, error = function(e) "not allowed"), "\n")Saída:
TRUE TRUE
not allowed Um método para a classe virtual funciona para cada subclasse. Aqui, describe() para Shape chama area(), que cada subclasse implementa, portanto a descrição é escrita uma única vez:
setClass("Shape", representation("VIRTUAL"))
setClass("Circle", contains = "Shape", slots = c(r = "numeric"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
invisible(setGeneric("area", function(s) standardGeneric("area")))
invisible(setGeneric("describe", function(s) standardGeneric("describe")))
setMethod("area", "Circle", function(s) pi * s@r^2)
setMethod("area", "Square", function(s) s@side^2)
setMethod("describe", "Shape", function(s) sprintf("%s with area %.2f", class(s), area(s)))
for (s in list(new("Circle", r = 1), new("Square", side = 2))) cat(describe(s), "\n")Saída:
Circle with area 3.14
Square with area 4.00 Uma classe virtual pode declarar slots, que toda subclasse terá:
setClass("Shape", representation("VIRTUAL", label = "character"))
setClass("Square", contains = "Shape", slots = c(side = "numeric"))
sq <- new("Square", label = "tile", side = 2)
print(slotNames("Square"))Saída:
[1] "side" "label"setClassUnion() cria uma classe virtual a partir de classes existentes. Um slot desse tipo aceita qualquer uma delas, como um contato que seja um endereço de e-mail ou um número de telefone:
setClassUnion("Contact", c("character", "numeric"))
setClass("Friend", slots = c(name = "character", contact = "Contact"))
a <- new("Friend", name = "Ada", contact = "ada@x.org")
b <- new("Friend", name = "Bo", contact = 5550123)
cat(class(a@contact), class(b@contact), "\n")
cat(tryCatch({ new("Friend", name = "Cy", contact = TRUE); "ok" }, error = function(e) "refused"), "\n")Saída:
character numeric
refused Desafio
FácilOs pagamentos compartilham a classe virtual Payment (slot amount) e os genéricos fee() e receipt(), todos em Payment.R. Complete:
- em
Payment.R, o métodoreceipt()paraPayment:card: 100.00 + 2.00 fee, construído a partir do nome da classe em letras minúsculas, deamounte defee(); - em
Card.R, a classeCard(contémPayment) e seufee(): 2% do valor; - em
Cash.R, a classeCashe seufee(): 0.
O código fornecido lê linhas card 100 ou cash 20, imprime cada recibo e o total cobrado e, em seguida, verifica se Payment é virtual e não pode ser criado.
Seu código deve estar em Payment.R, Card.R e Cash.R. main.R contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
source("Payment.R")
source("Card.R")
source("Cash.R")
# Código de entrada/saída fornecido: mantenha-o como está
input <- suppressWarnings(readLines(file("stdin")))
total <- 0
for (line in input) {
p <- strsplit(line, " ")[[1]]
amount <- as.numeric(p[2])
pay <- switch(p[1], card = new("Card", amount = amount), cash = new("Cash", amount = amount))
cat(receipt(pay), "\n", sep = "")
total <- total + amount + fee(pay)
}
cat(sprintf("charged: %.2f", total), "\n", sep = "")
cat("Payment is virtual: ", isVirtualClass("Payment"), "\n", sep = "")
cat(tryCatch({ new("Payment", amount = 1); "created a Payment" }, error = function(e) "cannot create a Payment"), "\n", sep = "")
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos do S3
Trabalhando com ArquivosListas com uma ClasseFunções ConstrutorasMétodos de Impressão e FormataçãoValidadores e AuxiliaresRevisão - Temperaturas4Encapsulamento em R
Closures como ObjetosAmbientes como ObjetosFunções de AcessoProtegendo o EstadoRecapitulação - Parquímetro7S4 Herança
Estendendo com containscallNextMethodClasses VirtuaisVerificando Tipos com is()Revisão - Cuidador do Zoológico2Genéricos e Métodos S3
Genéricos e UseMethodMétodos padrãoMétodos para genéricos baseFundamentos de NextMethodRevisão - Áreas de formas5Classes S4
Definindo classes S4Slots e acessoVerificações de validadeMétodos showRevisão - Catálogo de produtos8Classes de Referência
Definindo Classes de ReferênciaMétodos e Atualizações de CamposSemântica de CópiaHerança e callSuperRecapitulação — Fila de Tarefas11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Compilador de R online