typeof
возвращает тип внутреннего представления C и не используется для отправки метода. Так что, строго говоря, вы не можете думать о типах как о «суперклассах».
Вместо этого есть базовые классы (числовой, символьный, список, функция и т. д.), которые примерно соответствуют именам, возвращаемым typeof
, но не всегда (например, тип double относится к числовому классу, специальный и замыкающий — к функция класса, а класс data.frame имеет тип список!).
В системах S3 и S4 вы можете создавать нетривиальные классы, используя базовые классы (но не обязательно расширять один из них!! Пример: setClass("foo", list(a="numeric",b="character")
не расширяет ни один из базовых классов).
Для объектов из этих базовых классов is.object
возвращает FALSE
. Как сказано в документации, эта функция предоставляет очень быстрый способ проверить, относится ли объект к пользовательскому классу S3 или S4 (т. е. не к одному из базовых классов).
После приведения x
к "подделке" ваш объект формально не относится к "числовому" классу:
is(x, "numeric")
#FALSE
но он интерпретируется как базовый «числовой» объект:
is.numeric(x)
#TRUE
Вот почему здесь работает +
. Итак, внутри, как уже сказал @Richie, метод по умолчанию интерпретирует x
как числовой базовый класс.
Этот концептуальный беспорядок происходит из-за неформального отношения S3 к классам. Вместо этого используйте S4.
соответствие между typeof(.) и базовым class(.):
typeof(.) class(.)
NULL "NULL" "NULL"
1 "double" "numeric"
1:1 "integer" "integer"
1i "complex" "complex"
list(1) "list" "list"
data.frame(x=1) "list" "data.frame"
pairlist(pi) "pairlist" "pairlist"
c "special" "function"
lm "closure" "function"
formals(lm)[[1]] "symbol" "name"
formals(lm)[[2]] "symbol" "name"
y~x "language" "formula"
expression((1))[[1]] "language" "("
(y~x)[[1]] "symbol" "name"
expression(x <- pi)[[1]][[1]] "symbol" "name"
person
VitoshKa
schedule
18.01.2011