Каковы некоторые из названий терминов и понятий в Objective C по сравнению с Java?

Я надеялся составить список некоторых различий в терминах между java и цель c, чтобы уменьшить мою путаницу. Это облегчает объяснение моих трудностей, когда я знаю, что называется.

Например:

  • null - nil
  • this - self
  • map - dictionary (даже не уверен в этом)

То, что я ищу, - это аналогичные сравнения или исправления с теми, которые я перечислил. Не только ограничивается элементами на языке, но и понятиями...

Ответ 1

Вы правы относительно map = dictionary. Я добавлю:

  • @public, @private, @protected (по умолчанию) - это только переменные экземпляра (не методы) и работают как модификаторы видимости С++ (т.е. вы объявляете их как заголовки разделов, а не перед каждой переменной).
  • Методы класса похожи на статические методы в Java
  • Существуют только две структуры данных: NSDictionary и NSArray (в неизменяемых и изменяемых вариантах). Они очень оптимизированы и хорошо работают для большинства ситуаций. Для всего остального CHDataStructures
  • @interface не работает как интерфейсы Java - он определяет переменные экземпляра и методы одного класса.
  • Вам нужны файлы заголовков. C виноват в этом. Это в значительной степени отстой, так как поддержание вещей - ненужная боль.
  • Нет понятия "пакет". Самое близкое - это фреймворк, но они не должны использоваться как пакеты Java (т.е. Не создавать их только для организации ваших классов).
  • Вместо "new Class()", скажем [[Class alloc] init]. Подумайте о "alloc" как новый оператор и init как конструктор.
  • id - общие указатели объектов, такие как ссылки типа Object в Java.
  • Базовым классом является NSObject. Наследование из NSObject не является автоматическим и должно быть явно указано.

Ответ 2

Другим концептуальным отличием является поведение при вызове методов (отправка сообщений) на нулевые объекты (до нуля).

Java

MyClass myObject = null;
myObject.doSomething(); <-- results in a NullPointerException

Obj-C

id myObject = nil;
[myObject doSomething]; <-- is valid

Здесь - очень хороший вопрос о том, что такое поведение.

Ответ 3

Философский ответ о alloc/init.

init не является конструктором. Понятно, что "конструкция" не существует в Objective-C. В Java (и других языках с конструкторами) вызов конструктора вернет новое создание объекта, который готов к работе. Точного эквивалента этому в Objective-C нет. (Можно утверждать, что методы класса удобства, такие как + array, + arrayWithObjects и т.д. Являются технически конструкторами, поскольку они переносят как распределение, так и инициализацию, но я бы сказал, что они все еще не являются конструкторами в том же смысле, что и Java-конструкторы.)

Вместо этого у нас есть концепция выделения и инициализации, два разных шага, которые при выполнении вместе действуют так, как если бы они были "конструктором". Метод класса + alloc просто запрашивает у блока необходимый размер памяти. IIRC, для этого используется функция calloc(). Не гарантируется, что любое обнуление будет иметь место во время выполнения функции alloc. Это означает, что нам нужно выполнить инициализацию самостоятельно, что мы делаем, сразу же вызвав метод -init.

ОДНАКО, -init (и все производные) - не что иное, как обычные методы экземпляра. Вы можете сообщать о них, когда захотите, чтобы "reset" экземпляр объекта в исходное состояние инициализировалось (хотя для этого необходимо учитывать некоторые изменения в управлении памятью). Это также означает, что вы можете сделать что-то смешное:

NSUInteger count = [[[NSArray alloc] autorelease] count];

Я не могу придумать, почему вы хотите это сделать, но дело в том, что вы можете. Далее следует подчеркнуть, что init не является конструктором. В приведенном выше примере объект существует к моменту возврата метода + alloc. Однако он не может быть правильно инициализирован, а это означает, что целое число без знака может не равняться нулю. Это может быть, но было бы неверно полагаться на это поведение (если, конечно, не оговорено иначе).

Одним из преимуществ разрушения конструкции в распределении и инициализации является то, что мы можем иметь большую степень контроля над тем, что происходит при инициализации. Например, в Java у вас может быть только один конструктор на подпись метода. Другими словами, если у вас есть конструктор, который принимает один аргумент "Object", то это единственный конструктор, который может. Вы не можете создать другой конструктор, который также принимает один аргумент Object.

В Objective-C типы параметров не являются частью сигнатуры метода (известный как "селектор" ), поэтому я могу создать инициализатор следующим образом:

- (id) initWithAnObject:(id)anObject;

Однако я также могу создать еще один инициализатор:

- (id) initWithADifferentObject:(id)anObject;

Я могу установить для них совершенно разные инициализации объекта, на который они вызывается. Это невероятно полезно!

Другим действительно полезным аспектом построения расщепления в распределении и инициализации является то, что вы можете связывать инициализаторы. AFAIK, вы не можете вызывать конструкторы из конструкторов в таких языках, как Java (ну, вы можете, но это не имеет такого же эффекта). Однако в Objective-C вы можете сделать что-то вроде этого:

- (id) initWithCapacity:(NSUInteger)initialCapacity {
  if (self = [super init]) {
    [self setInitialCapacity:initialCapacity];
  }
  return self;
}

- (id) init {
  return [self initWithCapacity:0];
}

Теперь, когда вы выделяете/инициализируете объект, настроенный таким образом, он будет "перенаправлять" и использовать инициализатор initWithCapacity, даже если вы вызвали init. (Так работает метод init NSArray). Это означает, что вы можете использовать условные инициализаторы. Например, если ваш -init-метод отправляет один инициализатор при определенных условиях, но использует другой в разных условиях.

Таким образом, модель Objective-C "выделять и инициализировать" намного мощнее, чем идея построения. Вы, как программист, имеете гораздо больший контроль над начальной фазой установки вашего объекта. Это действительно освобождающий сдвиг.

ps - init не является конструктором!;)

Ответ 4

Интерфейс = Протокол

Поле = переменная экземпляра ( "ivar" )

ArrayList = Array

вызвать метод = отправить сообщение

То, что вы указали, верны.

Ответ 5

Сверху моей головы:

  • Сериализация = Архивирование
  • Переменные экземпляра обычно получают через свойства вместо явных get/set accessors. (В прежние времена мы также использовали для записи аксессоров, но даже тогда они обычно имели бы форму foo/setFoo, а не getFoo/setFoo.)
  • Слуховой аппарат action/button/mouse/event примерно эквивалентен IBAction, хотя способ разработки GUI в Cocoa сильно отличается от Java.
  • Вместо одного блока class определения классов определяются @interface (для переменных экземпляра и деклараций метода) и директивы @implementation (для фактического кода метода).

Ответ 6

Предыдущие ответы охватывают большинство различий "разговорника", но есть несколько ключевых концептуальных различий, которые упоминаются... (Обратите внимание, что я упоминаю только о проблемах с Objective-C, а не Cocoa.)

  • Существует плоское пространство имен для классов и одно для протоколов. Существует не такая штука, как пакеты или иерархии пакетов. Все имена классов должны быть разными (и все имена протоколов должны быть разными) в приложении. Обычно это достигается с помощью ~ 2-буквенных префиксов.
  • Исключения зарезервированы для исключительного потока, почти всегда в результате ошибки программиста. Цели, для которых 95% + исключений Java лучше обслуживаются, возвращая NSError, если это необходимо.
  • Рассмотрим использование категорий вместо одноразовых подклассов, но оба они должны выполняться разумно и осторожно. (Категории делают иерархию наследования менее ограниченными, но влияют на все экземпляры класса. Они часто являются твердым выбором, если вы обычно подклассы, например, для элементов пользовательского интерфейса.) Часто (как в Objective-C и Java) решение лучше всего должно использовать композицию.
  • Вы можете использовать динамическую типизацию почти везде, как вам нужно, просто знайте, что это обоюдоострый меч. Это избавляет от необходимости много отливок, но ошибки, которые были бы пойманы во время компиляции в Java, вытесняются во время выполнения в Objective-C. Статическая типизация может использоваться везде, где требуется, и обеспечивает большую безопасность во время компиляции. (Java-разработчики часто рассматривают нестатическую типизацию как недостаток языка, но хорошо бы понять, какую гибкость она делает возможной.)
  • Вы можете свободно комбинировать функциональность и библиотеки C без JNI-оберток. Но вы также получаете все ограничения и ограничения прямой C. Да, было бы замечательно, если бы мы могли избавиться от необходимости заголовочных файлов, но это просто не произойдет для языков на C. Жизнь не всегда справедлива.: -)