В NSString есть статический метод +stringWithString:.
точнее, это метод класса.
Это не переопределяется/не переопределяется в NSMutableString.
В какао подклассу не нужно повторно объявлять метод. На самом деле, это просто произвело бы много шума (IMO). Нужно только переопределить метод, чтобы обеспечить его собственную реализацию.
поэтому мы не можем предположить, что это вернет NSMutableString.
Мы должны предположить, что он вернет изменяемую строку. Подкласс может переопределить свои инициализаторы и удобные конструкторы по мере необходимости, чтобы соответствовать требуемым контрактам без публичного повторного объявления метода - ему нужно определить метод только тогда, когда базовой реализации недостаточно.
Какую часть объективного C мне не хватает, чтобы понять, почему это работает и возвращает NSMutableString? Тем более, что базовый класс NSString не знает, что нам нужна изменяемая строка взамен.
Он «знает», потому что вы написали [NSMutableString stringWithString:@"bah"]
, а не [NSString stringWithString:@"bah"]
. Как и методы экземпляра, методы класса имеют неявный self
, который позволяет им передавать тип через методы класса. Следовательно, методы класса могут быть переопределены/переопределены по мере необходимости. Методы класса также могут использовать self
для определения или сообщения своего типа (пример ниже).
Можно сказать, что внутренне вызывается [Class alloc], который сгенерирует объект типа NSMutableString, но даже это чистое предположение, поскольку у нас нет исходного кода, а stringWithString: может делать все, что захочет внутри.
Это не должно быть догадками. В этом случае вы должны сообщить об ошибке, если вам вернули неизменяемую строку. В противном случае он работает так, как рекламируется, независимо от того, использовали ли они одно или несколько определений.
Все ли эти методы класса переопределены в подклассе?
В случае удобных конструкторов чаще используется один из назначенных инициализаторов:
такая реализация может иметь вид:
@implementation NSString
+ (id)stringWithString:(NSString *)arg
{
// self is either +NSString or +NSMutableString
return [[[self alloc] initWithString:arg] autorelease];
}
хотя часто могут быть сделаны исключения, и это часто бывает с оптимизированными неизменяемыми/изменяемыми типами:
@implementation NSString
+ (id)stringWithString:(NSString *)arg
{
return [arg imp_isMutable] ? [[[self alloc] initWithString:arg] autorelease] : arg;
}
...
@implementation NSMutableString
+ (id)stringWithString:(NSString *)arg
{
return [[[self alloc] initWithString:arg] autorelease];
}
...
И если да, то почему это не задокументировано?
Их не следует повторно объявлять или документировать, если единственным отличием является тип класса, который вы запросили, если только они не имеют каких-либо отклонений от базового класса или специального примечания - даже в этом случае было бы лучше создать метод с другим именем .
person
justin
schedule
01.12.2011