9.1.5 Using Inheritance...............................................
The idea of inheritance is to form new classes as specialized versions of old
ones. In our previous employee example, for instance, we could form a new
class devoted to hourly employees,"hrlyemployee", as a subclass of"employee",
as follows:
k <- list(name="Kate", salary= 68000, union=F, hrsthismonth= 2)
class(k) <- c("hrlyemployee","employee")
Our new class has one extra variable:hrsthismonth. The name of the new
class consists of two character strings, representing the new class and the
old class. Our new class inherits the methods of the old one. For instance,
print.employee()still works on the new class:
>k
Kate
salary 68000
union member FALSE
Given the goals of inheritance, that is not surprising. However, it’s impor-
tant to understand exactly what transpired here.
Once again, simply typingkresulted in the callprint(k). In turn, that
causedUseMethod()to search for a print method on the first ofk’s two class
names,"hrlyemployee". That search failed, soUseMethod()tried the other class
name,"employee", and foundprint.employee(). It executed the latter.
Recall that in inspecting the code for"lm", you saw this line:
class(z) <- c(if(is.matrix(y)) "mlm", "lm")
You can now see that"mlm"is a subclass of"lm"for vector-valued response
variables.
9.1.6 Extended Example: A Class for Storing Upper-Triangular Matrices
Now it’s time for a more involved example, in which we will write an R class
"ut"for upper-triangular matrices. These are square matrices whose ele-
ments below the diagonal are zeros, such as shown in Equation 9.1.
⎛
⎝
1512
06 9
00 2
⎞
⎠ (9.1)
Our motivation here is to save storage space (though at the expense of a
little extra access time) by storing only the nonzero portion of the matrix.
NOTE The R class"dist"also uses such storage, though in a more focused context and with-
out the class functions we have here.
214 Chapter 9