Каковы различия и преимущества методов уровня класса в Objective-C по сравнению с Java - PullRequest
3 голосов
/ 04 июня 2011

Например, я знаю, что методы класса Objective C могут быть переопределены, а Java - нет.

Какая польза от этого и какие еще есть отличия?

Ответы [ 3 ]

11 голосов
/ 04 июня 2011

В двух словах, статические методы в Java - это просто функции, которые присоединены к классу. Они не работают как методы экземпляра в том смысле, что вы не можете использовать это или супер. У них фактически нет никакой реальной идеи о том, что они находятся в классе.

Методы класса Objective C очень разные. Они точно такие же, как методы экземпляра, за исключением класса. Это не слишком удивительно, учитывая, что классы являются объектами в Obj-C. Таким образом, они проходят все ту же динамическую диспетчеризацию, вы можете использовать self для доступа к другим методам класса, вы можете использовать super для вызова методов класса суперкласса. Это обеспечивает гораздо большую гибкость, поскольку вы можете делать все то же самое с методами класса, как вы можете с методами экземпляра, такими как обмен сообщениями nil, метод swizzling и т.д.

4 голосов
/ 04 июня 2011

Марк Пилкингтон ответ правильный. Вот конкретный пример, иллюстрирующий то, что вы можете делать с помощью методов класса Objective-C, но не с помощью статических методов Java.

Objective-C

@interface Parent : NSObject
+ (int)foo;
+ (int)bar;
- (void)printMyFoo;
@end

@interface Child : Parent
+ (int)bar; // Override bar only.
@end

@implementation Parent
+ (int)foo {
    return [self bar];
}

+ (int)bar {
    return 0;
}

- (void)printMyFoo {
    NSLog(@"%d", [[self class] foo]);
}
@end

@implementation Child
+ (int)bar {
    return 1;
}
@end

Теперь, если вы вызовете printMyFoo для экземпляра Parent и Child, вы получите разные результаты, потому что +[Parent foo] динамически отправляет вызов bar во время выполнения:

id parent = [[Parent alloc] init];
id child = [[Child alloc] init];
[parent printMyFoo]; // -> 0
[child printMyFoo];  // -> 1

Java

class Parent {
    static int foo() { return bar(); }
    static int bar() { return 0; }
    void printMyFoo() { System.out.println(foo()); }
}

class Child extends Parent {
    static int bar() { return 1; }
}

Теперь, если вы вызовете printMyFoo() на экземпляре Parent и Child, они оба напечатают одно и то же, потому что даже для дочернего элемента Parent.foo() вызывает Parent.bar() вместо Child.bar():

Parent parent = new Parent();
Child child = new Child();
parent.printMyFoo(); // -> 0
child.printMyFoo();  // -> 0
0 голосов
/ 04 июня 2011

Вот что говорит Java-документация по Oracle (первоначально Sun) о переменных и методах класса: http://download.oracle.com/javase/tutorial/java/javaOO/classvars.html

...