Модификатор переопределения может использоваться для виртуальных методов и должен использоваться для абстрактных методов. Это означает, что компилятор использует последнюю определенную реализацию метода.
blockquote>public class Base { public virtual void DoIt() { } } public class Derived : Base { public override void DoIt() { } } Base b = new Derived(); b.DoIt(); // Calls Derived.DoIt
будет вызывать
]Derived.DoIt
, если это переопределяетBase.DoIt
.Новый модификатор инструктирует компилятор использовать реализацию вашего дочернего класса вместо реализации родительского класса. Любой код, который не ссылается на ваш класс, но родительский класс будет использовать реализацию родительского класса.
blockquote>public class Base { public virtual void DoIt() { } } public class Derived : Base { public new void DoIt() { } } Base b = new Derived(); Derived d = new Derived(); b.DoIt(); // Calls Base.DoIt d.DoIt(); // Calls Derived.DoIt
Сначала вызовет
Base.DoIt
, затемDerived.DoIt
. Они фактически представляют собой два совершенно разных метода, которые имеют одно и то же имя, а не производный метод, переопределяющий базовый метод.Источник: Блог Microsoft
Короткий ответ: вы не можете; Objective-C не имеет понятия частных методов.
Проверьте ответ на этот аналогичный вопрос .
Вы не можете делать методы закрытыми в Objective-C. Вы можете поднять NSException , если вызывается неправильный инициализатор.
- (id)init
{
[NSException exceptionWithName:@"InvalidOperation" reason:@"Cannot invoke init." userInfo:nil];
}
Я видел, как это делалось двумя способами.
init
. Чтобы быть ясными, не делайте этого. Это необязательно и сделает ваши синглеты чрезмерно трудными для тестирования и подкласса.
edit, чтобы добавить примеры
- (instancetype)init {
[self doesNotRecognizeSelector:_cmd];
return nil;
}
- (instancetype)initPrivate {
self = [super init];
if (self) {
}
return self;
}
+ (instancetype)sharedInstance {
static MySingleton *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] initPrivate];
});
return sharedInstance;
}
- (instancetype)init {
return [[self class] sharedInstance];
}
- (instancetype)initPrivate {
self = [super init];
if (self) {
}
return self;
}
+ (instancetype)sharedInstance {
static MySingleton2 *sharedInstance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[self alloc] initPrivate];
});
return sharedInstance;
}
Использовать UNAVAILABLE_ATTRIBUTE
отменить метод init
и реализовать initPrivate
+ (instancetype)shareInstance;
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;
реализовать
+ (instancetype)shareInstance {
static MyClass *shareInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shareInstance = [[super allocWithZone:NULL] initPrivate];
});
return shareInstance;
}
- (instancetype)initPrivate {
self = [super init];
if (self) {
}
return self;
}
// MARK: Rewrite
+ (id)allocWithZone:(struct _NSZone *)zone {
return [MyClass shareInstance];
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}