Last chance! 50% off DataCamp Premium
Sale ends in
Objectgeoriënteerd programmeren (OOP) is een programmeerparadigma waarbij je software ontwerpt rond data of objecten in plaats van rond functies. Een methode is gewoon een functie, besproken in de OOP-context. Het is objectgeoriënteerd omdat alle verwerking draait om de objecten en velden. Elk object heeft verschillende eigenschappen en gedrag.
In objectgeoriënteerd programmeren kan het hele programma worden opgedeeld in verschillende klassen om de uitvoering snel te begrijpen. R is een functionele programmeertaal, en OOP helpt bij het beheren van grote systeemploegen. OOP wordt gebruikt om GUI-toepassingen te beheren, vaak webapplicaties. Objectgeoriënteerd programmeren is goed voor het bouwen van tools voor data-analyse, maar minder geschikt voor de data-analyse zelf.
Er zijn grofweg twee belangrijke OOP-systemen, hieronder beschreven:
Opmerking: Deze klassen worden later in detail besproken.
Objecten zijn instanties van een klasse. Alles in R is een object; voor meer informatie zie Datatypes in R. Ze kunnen ook eigen attributen hebben zoals class, attributes, dimnames, names, enz.
Objecten krijgen bijvoorbeeld een waarde toegewezen met <-, bekijk de volgende code waarin 'a1' en 'a2' variabelen zijn waaraan een numerieke waarde is toegekend.
a1 <- 10
a2 <- 20
Een object kan een reeks getallen krijgen; 'a3' is het object dat een vector met verschillende getallen bevat.
a3 <- c(10,20,30)
Hier zet c de getallen 10, 20, 30 in een vector.
Laten we een voorbeeld uit het echte leven nemen, zoals een leerling met de attributen naam, leeftijd, klas en geslacht; de leraar heeft een naam, leeftijd en geslacht.
st_name <- "andrew"
st_age <- 16
st_class <- 10
st_gender <- "male"
t_name <- "angelina"
t_age <- 26
t_gender <- "female"
student <- c(st_name, st_age, st_class, st_gender)
teacher <- c(t_name, t_age, t_gender)
print(student)
print(teacher)
[1] "andrew" "16" "10" "male"
[1] "angelina" "26" "female"
De bovenstaande code geeft de volgende output:
"andrew" "16" "10" "male"
"angelina" "26" "female"
In de bovenstaande code zie je een voorbeeld met verschillende typen objecten. De objecten 'student' en 'teacher', ook wel variabelen genoemd, bevatten het type 'character' en 'double'.
Een klasse is het blauwdruk waarmee je een object maakt en dat zijn ledematenvariabelen en attributen bevat.
Zoals eerder besproken zijn er in R twee klassensystemen: S3 en S4.
Deze klassen helpen bij het overbelasten van functies door ze op te splitsen in generieken en methoden.
functies = generiek + methoden
S3 is heel anders dan andere programmeertalen zoals C#, Java, enz. Omdat het eenvoudig te implementeren is, gebruikt het alleen het eerste argument voor dispatch. Daarom heb je als programmeur niet heel veel voorkennis nodig.
S3 werkt door een strikte naamgevingsconventie van generiek.punt.klasse te definiëren.
generic.class
De argumenten van methoden moeten de argumenten van de generiek bevatten en de methode moet een ...arg bevatten.
In het volgende voorbeeld zie je hoe je een S3-klasse construeert: er wordt een lijst gemaakt waarin componenten worden doorgegeven, samen met een juiste classname, en vervolgens wordt het resultaat afgedrukt.
In het volgende voorbeeld bevat 'studentBio' een lijst waarin componenten als lijst worden doorgegeven: 'student_name', 'student_age' en 'student_contact'. De klasse heet 'Student Info' en 'studentBio' is de nieuw aangemaakte klasse waarvan de waarden hieronder worden weergegeven.
studentBio <- list(studentName = "Harry Potter", studentAge = 19, studentContact="London")
class(studentBio) <- "StudentInfo"
studentBio
$studentName
[1] "Harry Potter"
$studentAge
[1] 19
$studentContact
[1] "London"
attr(,"class")
[1] "StudentInfo"
De bovenstaande code geeft de volgende output:
$studentName
"Harry Potter"
$studentAge
19
$studentContact
"London"
attr(,"class")
"StudentInfo"
Als je nog niet zo zeker bent over het schrijven van functies in R, lees dan A Tutorial on Using Functions in R!
Hieronder implementeer je je generieke functie met behulp van de volgende code.
De onderstaande code toont de generieke functie 'contact' waarbij de functie met het object als argument wordt aangeroepen. Ook wordt 'UseMethod' gebruikt met de generieke functie 'contact', waar de 'dispatch' van de methode plaatsvindt: het proces waarbij het resultaat varieert op basis van de doorgegeven argumenten.
contact <- function(object) {
UseMethod("contact")
}
Laten we een methode maken voor de specifieke klasse die je eerder hebt aangemaakt, 'StudentInfo'. De methode 'contact' gevolgd door puntnotatie met de klasse 'StudentInfo' wordt gebruikt; in de functiebody wordt het attribuut 'studentContact' benaderd met '$'.
contact.StudentInfo <- function(object) {
cat("Your contact is", object$studentContact, "\n")
}
contact(studentBio)
Your contact is London
De bovenstaande code gebruikt object$studentContact, waarbij het object als argument aan de functie is doorgegeven en met '$' het attribuut 'studentContact' wordt benaderd, wat de onderstaande output oplevert.
Your contact is London
De S4-klasse is strikter, conventioneler en sluit nauwer aan bij objectgeoriënteerde concepten. De klassen worden weergegeven door de formele klassedefinities van S4. Concreet heeft S4 setter- en getterfuncties voor methoden en generieken. In vergelijking met de S3-klasse kan S4 multiple dispatch faciliteren.
We bekijken de hierboven besproken R-klassen door ze te maken en te bespreken met een voorbeeld.
Een S4-klasse wordt gedefinieerd met de setClass-functie.
setClass()
Zoals eerder besproken wordt de S4-klasse gedefinieerd met de setClass()-methode. Je gebruikt de setClass()-methode om de S4-klasse te maken en te definiëren. We gebruiken een subroutine om te controleren of de data consistent is (validatie) en om standaardwaarden in te stellen (het paradigma).
Hieronder staat de code om de klasse en zijn slots te definiëren:
Het volgende wordt gebruikt om een klasse te definiëren, ook wel 'prototype' genoemd, waarin de slots zijn gedefinieerd: de classname is 'employee', name is een character, id is numeric en contact is een character.
setClass("employee", slots=list(name="character", id="numeric", contact="character"))
Met de volgende code kun je specifieke instanties of objecten van S4 maken.
Laten we een object maken met 'new' met binnenin de classname 'employee', waarbij de slots name, id en contact een waarde krijgen.
obj <- new("employee",name="Steven", id=1002, contact="West Avenue")
obj
An object of class "employee"
Slot "name":
[1] "Steven"
Slot "id":
[1] 1002
Slot "contact":
[1] "West Avenue"
An object of class "employee"
Slot "name":
"Steven"
Slot "id":
1002
Slot "contact":
"West Avenue"
De bovenstaande output laat zien dat het aangemaakte object van klasse "employee" is en dat de slot "name" de waarde "Steven" heeft, de slot "id" de waarde 1002 en de slot "contact" de waarde "West Avenue".
Om te controleren of een object een S4-object is, kunnen de volgende twee commando's worden gebruikt:
Het commando 'is.object(obj)' controleert of een variabele of instantie naar een object verwijst.
is.object(obj)
TRUE
De bovenstaande code geeft de volgende output:
TRUE
Het commando 'is.S4(obj)' controleert of een variabele of instantie een S4-object is.
isS4(obj)
TRUE
De bovenstaande code geeft de volgende output:
TRUE
De slot kun je benaderen met "@" in plaats van "$".
'obj@name' wordt gebruikt waarbij je de objectnaam met de slotnaam gebruikt om de naam 'Steven' te benaderen; hetzelfde geldt voor 'obj@id'.
obj@name
obj@id
'Steven'
1002
De bovenstaande code geeft de volgende output:
'Steven'
1002
We wijzigen de slotwaarde met de toekenningsoperator ("<-") waarbij aan 'obj@contact' een nieuwe waarde "North Avenue" wordt toegekend.
obj@contact <- "North Avenue"
obj
An object of class "employee"
Slot "name":
[1] "Steven"
Slot "id":
[1] 1002
Slot "contact":
[1] "North Avenue"
De bovenstaande code geeft de volgende output:
An object of class "employee"
Slot "name":
"Steven"
Slot "id":
1002
Slot "contact":
"North Avenue"
De output laat zien dat de slot "contact" is gewijzigd van "West Avenue" naar "North Avenue".
Als alternatief kun je 'slot()' gebruiken om de waarde te wijzigen.
'slot(obj, "id")' geeft aan dat de slot "id" wordt gewijzigd door toekenning van 1004, en het resultaat wordt afgedrukt met 'obj'.
slot(obj,"id") <- 1004
obj
An object of class "employee"
Slot "name":
[1] "Steven"
Slot "id":
[1] 1004
Slot "contact":
[1] "North Avenue"
An object of class "employee"
Slot "name":
"Steven"
Slot "id":
1004
Slot "contact":
"North Avenue"
De bovenstaande output laat zien dat de slot "id" is gewijzigd van 1002 naar 1004.
Laten we een functie maken die helpt om de output naar wens te printen, waarbij 'setMethod()' en de generieke functie 'show()' worden gebruikt. Ook worden alle slotwaarden benaderd met '@' en hun namen afgedrukt. Tot slot wordt de output verkregen met behulp van 'obj'.
setMethod("show",
"employee",
function(object) {
cat("Name:",object@name, "\n")
cat("Id:",object@id, "\n")
cat("Contact:", object@contact, "\n")
}
)
obj
Name: Steven
Id: 1004
Contact: North Avenue
Name: Steven
Id: 1004
Contact: North Avenue
De bovenstaande output laat zien dat de resultaten worden afgedrukt in de vorm van slotnamen met de bijbehorende slotwaarden.
Gefeliciteerd
Gefeliciteerd, je bent aan het einde van deze tutorial gekomen!
In deze tutorial heb je geleerd over objectgeoriënteerd programmeren (OOP) samen met R-objecten, verschillende klassen zoals S3 en S4, hoe je ze opzet, hoe je hun generieke functies maakt met voorbeelden, en nog veel meer.
Wil je meer leren over R? Bekijk de cursussen van DataCamp:
Leer meer over R
Cursus
Cursus
Cursus

blog
Adel Nehme
15 min