2013-12-12 2 views
0

У меня есть класс, который наследуется от UIViewController. Этот класс предоставляет основные функции, которые необходимо реализовать нескольким контроллерам представлений, чтобы они наследовали этот класс. Причина, почему я не использую его для непосредственного создания каких-либо экземпляров.Objective-C Не переопределять методы, объявленные в реализации

И родительский, и дочерний класс имеют метод, называемый setupView, который вызывается в каждом классе 'viewDidLoad. Оба класса имеют точно такой же метод:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
// Do any additional setup after loading the view. 

    [self setupView]; 
} 

setupView не объявлен в interface, это просто определенный в implementation, что я, хотя не позволит какой-либо другой класс, чтобы иметь доступ к нему или изменить его. Однако, когда родительский viewDidLoad вызывается его дочерним элементом и выполняется [self setupView], его имя setupView вызывается вместо его собственного.

Я два вопроса:

  1. Почему класс I ребенок переопределить метод, который он не объявлен в интерфейсе?
  2. Как я могу предотвратить это?

--Edit--

Каждый setupView способ выполнения конфигурации, которые являются исключительными для этого вида контроллера. Например, родитель использует этот метод для настройки UIBarButtonItem, который требуется каждому дочернему классу, и ребенок использует его для настройки вида таблицы, который он будет использовать.

Я не хочу настраивать UIBarButtonItem в дочернем классе, потому что тогда мне придется делать это в каждом дочернем элементе, и именно поэтому я решил создать родительский класс. Я также не хочу использовать [super setupView], потому что ребенок не должен ничего знать об этом методе в родительском классе.

Возможность переопределить метод, который не объявлен в интерфейсе, не противоречит принципам инкапсуляции?

--Answer--

Любой метод в Objective-C может быть переопределен, в том числе и те, которые не объявлены в interface. Это означает, что методы в дочерних классах должны иметь разные имена, если только намерение не переопределяет метод.

ответ

2

Если ребенок реализует тот же метод, что и родительский, он в основном перезаписывает этот метод. Затем вы можете вызвать родительский метод с помощью [super methodName]. Так что, если вы перезаписать setupView в ребенке, а также хотят, чтобы назвать родителя setupView, вы должны назвать его от ребенка:

- (void)setupView 
{ 
    [super setupView]; 
    // child code 
} 
+0

Кроме того, вы должны удалить дополнительный вызов [self setupView] из viewDidLoad в дочернем. Оставьте эту работу родитель;) –

+0

Проверьте правильность. Я не хочу вызывать '[super setupView]', потому что ребенок не должен знать, что этот метод существует. Я думал, что один из них может переопределить или назвать методы, объявленные только в интерфейсе. Разве это небезопасно, если я буду использовать фреймворк и переопределить частный метод по ошибке? Я не знаю, существует ли этот метод, потому что он не объявлен в интерфейсе. Или это? Разве это не повторяет принципы инкапсуляции? –

+1

В этом случае вы должны использовать другое имя, setupBarButtons или что-то в этом роде. Поскольку переопределение метода будет переопределять его для хорошего в этом классе. –

0

, что вы можете сделать, это проверить, если класс является sublcass или нет а затем выполните настройку. Но это плохо, что нужно делать. потому что ваш подкласс должен использовать все от своих родителей.

1

Это подход по умолчанию. Ребенок переопределяет метод родителя.

Я вижу два возможных решения:

  • Используйте разные имена методов
  • Изменить ребенка следующим образом:

.

- (void)setupView 
{ 
    if([super respondsToSelector:_cmd]) 
     [super performSelector:_cmd]; 
    // child code 
} 
+0

Я думал, что только методы, объявленные в 'интерфейсе', могут быть переопределены. Способность этого делать не идет против принципов инкапсуляции? –

+0

Нет. Все методы. Это полиморфизм в Objective C –

+0

Разве это не опасно? Например, если я использую библиотеку, я не знаю, какие методы используются в «реализации», я знаю только методы, объявленные в «интерфейсе». Это значит, что я могу переопределить метод, который я даже не знаю, что он существует? –

Смежные вопросы