## [1] "numeric"
## [1] "ordered" "factor"
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.2000 0.4000 0.7000 0.7979 1.0400 5.0100
## Fair Good Very Good Premium Ideal
## 1610 4906 12082 13791 21551
Note que summary()pode produzir
diferentes resultados para variáveis numéricas e fatoriais.
Você poderia imaginar summary()uma
série de instruções if-else, mas isso significaria que apenas o autor
original poderia adicionar novas implementações.
A principal razão para usar OOP é o polimorfismo (literalmente: muitas formas). Polimorfismo significa que um desenvolvedor pode considerar a interface de uma função separadamente de sua implementação, possibilitando usar a mesma forma de função para diferentes tipos de entrada
Um sistema OOP possibilita que qualquer desenvolvedor estenda a interface com implementações para novos tipos de entrada/classes.
Portanto, classe define o tipo de objeto e os métodos descrevem o que esse objeto pode fazer, ou seja, é uma implementação para uma classe específica.
Existem dois paradigmas principais de programação orientada a objetos que diferem na forma como métodos e classes estão relacionados: encapsulados e funcionais:
Na OOP encapsulada , os métodos pertencem a
objetos ou classes, e as chamadas de método normalmente se parecem
com object.method(arg1, arg2)
Na OOP funcional , os métodos pertencem a
funções genéricas e as chamadas de método parecem
chamadas de função
comuns: generic(object, arg2, arg3).
Exemplo no python:
# Definição da classe 'Pessoa'
class Pessoa:
# Método de inicialização
def __init__(self, nome, idade):
self.nome = nome
self.idade = idade
# Método para apresentar a pessoa
def apresentar(self):
print(f"Olá, eu sou {self.nome} e tenho {self.idade} anos.")
# Instanciando objetos da classe 'Pessoa'
pessoa1 = Pessoa("João", 30)
pessoa2 = Pessoa("Maria", 25)
# Chamando o método 'apresentar' para cada objeto
pessoa1.apresentar()
pessoa2.apresentar()## [1] "list"
## $nome
## [1] "Leo"
##
## $idade
## [1] "30"
# Método genérico
class(pessoa) <-"Pessoa"
print.Pessoa <- function(x) { # a função genérica é o print
cat("Nome:", x$nome, "\n")
cat("Idade:", x$idade, "\n")
}
print(pessoa)## Nome: Leo
## Idade: 30
Existem vários sistemas OOP para escolher. Aqui vamos considerar os sistemas S3 e S4.
S3 e S4 usam função genérica OOP que é bastante diferente da OOP encapsulada usada pela maioria das linguagens populares atualmente
O S3 permite que suas funções retornem resultados avançados com exibição amigável e componentes internos fáceis de programar. S3 é usado em toda a base R
A função de um genérico S3 é encontrar a implementação específica para uma classe
O envio do método é realizado por UseMethod(),
que todo genérico chama
UseMethod()recebe dois argumentos: o nome da função genérica (obrigatório) e o argumento a ser usado para envio do método (opcional).
# Definição da função genérica 'foo'
minha_funcao_generica <- function(x) {
# Chamando useMethod para despachar para métodos específicos
UseMethod("minha_funcao_generica")
}
# Definição de métodos específicos para diferentes classes
minha_funcao_generica.default <- function(x) {
print("Método padrão chamado")
}
minha_funcao_generica.integer <- function(x) {
print("Método para números inteiros chamado")
}
minha_funcao_generica.character <- function(x) {
print("Método para caracteres chamado")
}
# Testando a função genérica com diferentes tipos de argumentos
minha_funcao_generica(5) # Chamará minha_funcao_generica.integer## [1] "Método padrão chamado"
## [1] "Método para caracteres chamado"
## [1] "Método padrão chamado"
setClass()),
genéricos ( setGeneric())
e métodos ( setMethod())new()com o
nome da classe e um valor para cada slot:## [1] "Leo Nascimento"
setGeneric():## [1] "idade"
setMethod():## [1] 32
setClass("Animal",
slots = c(
name = "character",
age = "numeric"
)
)
setMethod("idade", "Animal", function(x) cat("A idade é",x@age))
leao = new("Animal",name = "leão",age = 25)
idade(leao)## A idade é 25