Vetores de classe
Parte da seção Programação Orientada a Objetos do Journey de R da Coddy. Lição 12 de 57.
A herança S3 vem do vetor de classes. Um objeto com class = c("manager", "employee") é um gerente e também um funcionário. Quando um genérico não tem método para manager, o despacho prossegue e usa o método employee:
pay <- function(x) UseMethod("pay")
pay.employee <- function(x) x$salary / 12
m <- structure(list(name = "Ada", salary = 60000), class = c("manager", "employee"))
print(class(m))
print(pay(m))Saída:
[1] "manager" "employee"
[1] 5000Escrever o vetor de classes manualmente em cada construtor repete os detalhes do pai. Em vez disso, o construtor pai recebe um argumento class e o coloca à frente de sua própria classe, e o construtor filho chama o construtor pai:
new_employee <- function(name, salary, ..., class = character()) {
structure(list(name = name, salary = salary, ...), class = c(class, "employee"))
}
new_manager <- function(name, salary, reports) {
new_employee(name, salary, reports = reports, class = "manager")
}
m <- new_manager("Ada", 60000, 4)
print(class(m))
print(names(m))Saída:
[1] "manager" "employee"
[1] "name" "salary" "reports"O ... do construtor pai coleta os campos extras do filho, neste caso reports, e os coloca depois dos próprios campos do pai. Um funcionário comum não tem nenhum campo reports:
new_employee <- function(name, salary, ..., class = character()) {
structure(list(name = name, salary = salary, ...), class = c(class, "employee"))
}
e <- new_employee("Bo", 40000)
print(class(e))
print(names(e))Saída:
[1] "employee"
[1] "name" "salary"A ordem do vetor de classes é importante: a classe mais específica vem primeiro. Com a classe pai primeiro, seus métodos prevalecem e os métodos da classe filha nunca são usados:
title <- function(x) UseMethod("title")
title.employee <- function(x) "employee"
title.manager <- function(x) "manager"
right <- structure(list(), class = c("manager", "employee"))
wrong <- structure(list(), class = c("employee", "manager"))
print(title(right))
print(title(wrong))Saída:
[1] "manager"
[1] "employee"Desafio
FácilFuncionários e gerentes estão divididos em dois arquivos. Complete new_employee(name, salary, ..., class = character()) em Employee.R: ele retorna uma lista com name, salary e quaisquer campos extras de ..., com o vetor de classes c(class, "employee"). Em seguida, complete new_manager(name, salary, reports) em Manager.R, que chama new_employee() com o campo extra reports e a classe manager.
label() e seu método employee são fornecidos, portanto os gerentes recebem um rótulo sem ter um método próprio. O código fornecido lê linhas employee Bo 40000 ou manager Ada 60000 4 e imprime o vetor de classes, os nomes dos campos e o rótulo.
Seu código deve ficar em Employee.R e Manager.R. main.R contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
source("Employee.R")
source("Manager.R")
# Código de entrada/saída fornecido: mantenha-o como está
input <- suppressWarnings(readLines(file("stdin")))
for (line in input) {
p <- strsplit(line, " ")[[1]]
x <- if (p[1] == "manager") new_manager(p[2], as.numeric(p[3]), as.numeric(p[4])) else new_employee(p[2], as.numeric(p[3]))
cat("class: ", paste(class(x), collapse = ", "), "\n", sep = "")
cat("fields: ", paste(names(x), collapse = ", "), "\n", sep = "")
cat(label(x), "\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ímetro2Gené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