我正在尝试在Objective C中编写一个类方法.当我声明方法时,项目构建正常.但是每当我尝试调用该方法时,构建都会失败.这是我的代码.
头文件
#import <UIKit/UIKit.h>
@interface LoginViewController : UIViewController {
//Declare Vars
}
- (IBAction) login: (id) sender;
+ (NSString *) md5Hash:(NSString *)str;
@end
Run Code Online (Sandbox Code Playgroud)
源文件
+ (NSString *) md5Hash:(NSString *)str {
const char *cStr = [str UTF8String];
unsigned char result[16];
CC_MD5( cStr, strlen(cStr), result );
return [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
}
- (IBAction) login: (id) sender {
//Call the class method
[self md5Hash:@"Test"];
}
Run Code Online (Sandbox Code Playgroud) 我有以下困惑.据我所知,在声明方法时静态和类关键字之间的主要区别在于第二个可以在子类中重写.
问题
但是,当我在Swift 1.2中声明一个协议时,如下所示:
protocol MyProtocol
{
class func dummyClassMethod()
}
Run Code Online (Sandbox Code Playgroud)
编译器给出错误:
类方法只允许在类中; 使用'static'来声明静态方法
这个错误非常具有描述性,因为很明显MyProtocol不是一个类,但是我想让一个类func成为协议的一部分.
我试过的
我发现如果我将协议中的接口声明为静态,编译器很高兴我可以在采用此协议的所有类中使用此静态方法:
protocol MyProtocol
{
static func dummyClassMethod()
}
Run Code Online (Sandbox Code Playgroud)
这个问题
所以我的问题基本上就是这样吗?这个声明声明我的类方法不能在子节点中重写,但是在我的实现中我可以编写并使用以下内容:
class ClassA: MyProtocol
{
class func dummyClassMethod() {
}
}
class ClassB: ClassA
{
override class func dummyClassMethod() {
}
}
Run Code Online (Sandbox Code Playgroud)
现在我的dummyClassMethod不再是静态的......
编译器很好,一切正常 - 但为什么呢?
它是否特定于接口本身是静态的,但它的实现不是?
Objective-C解决方案
在ObjC中,这非常简单,编译和运行完美:
@protocol MyProtocol
+(void)dummyClassMethod;
@end
Run Code Online (Sandbox Code Playgroud) 正如我刚刚学到的,我可以这样使用super()
:
super(class, obj_of_class-or-_subclass_of_class)
代码如下:
#Case 1
class A(object):
def __init__(self):
print "A init"
class B(A):
def __init__(self):
print "B init"
super(B, self).__init__() #ok, I can invoke A's __init__ successfully
#Case 2
class A(object):
@classmethod
def foo(cls):
print "A foo"
class B(object):
@classmethod
def foo(cls):
print "B foo"
super(B, cls).foo() #ok, I can invoke A's foo successfully
#Case 3
class A(object):
def __new__(cls):
print "A new"
return super(A, cls).__new__(cls)
class B(A):
def __new__(cls):
print "B new"
return super(B, cls).__new__() …
Run Code Online (Sandbox Code Playgroud) 我知道他们做了什么,我已经看到了很多这两个例子,但我没有找到一个例子,我必须使用classmethod
而不是用一个替换它staticmethod
.
classmethod
我见过的最常见的例子是创建一个类本身的新实例,就像这样(非常简化的例子,没有使用方法atm.但你明白了):
class Foo:
@classmethod
def create_new(cls):
return cls()
Run Code Online (Sandbox Code Playgroud)
这会Foo
在调用时返回一个新实例foo = Foo.create_new()
.现在为什么我不能只使用它:
class Foo:
@staticmethod
def create_new():
return Foo()
Run Code Online (Sandbox Code Playgroud)
它完全相同,我为什么要使用classmethod
a staticmethod
?
有没有办法从同一个类中的另一个方法调用类方法?
例如:
+classMethodA{
}
+classMethodB{
//I would like to call classMethodA here
}
Run Code Online (Sandbox Code Playgroud) 我曾经读过(我认为在微软的一个页面上)当你不需要两个或更多类的实例时,这是一个使用静态类的好方法.
我正在用Python编写程序.如果我@classmethod
用于课堂的每一种方法,这是一种糟糕的风格吗?
class C
end
var = "I am a local var outside"
C.class_eval do
def self.a_class_method
puts var
end
end
Run Code Online (Sandbox Code Playgroud)
我知道,这是不正确的,因为def
创建了一个新的范围.我也知道use define_method
可以在不创建新范围的情况下创建实例方法,但我的观点是如何定义类方法.
这是一个关于使用python从不同形式的相同数据创建类或类型的实例的最佳实践的问题.使用类方法是否更好,或者更好地完全使用单独的函数?假设我有一个用于描述文档大小的类.(注意:这只是一个例子.我想知道创建类实例的最佳方法,而不是描述文档大小的最佳方法.)
class Size(object):
"""
Utility object used to describe the size of a document.
"""
BYTE = 8
KILO = 1024
def __init__(self, bits):
self._bits = bits
@property
def bits(self):
return float(self._bits)
@property
def bytes(self):
return self.bits / self.BYTE
@property
def kilobits(self):
return self.bits / self.KILO
@property
def kilobytes(self):
return self.bytes / self.KILO
@property
def megabits(self):
return self.kilobits / self.KILO
@property
def megabytes(self):
return self.kilobytes / self.KILO
Run Code Online (Sandbox Code Playgroud)
我的__init__
方法采用以位表示的大小值(位和唯一的位,我想保持这种方式),但是假设我有一个以字节为单位的大小值,我想创建一个类的实例.使用类方法是否更好,或者更好地完全使用单独的函数?
class Size(object):
"""
Utility object used to describe …
Run Code Online (Sandbox Code Playgroud) 采用以下示例脚本:
class A(object):
@classmethod
def one(cls):
print("I am class")
@staticmethod
def two():
print("I am static")
class B(object):
one = A.one
two = A.two
B.one()
B.two()
Run Code Online (Sandbox Code Playgroud)
当我使用Python 2.7.11运行此脚本时,我得到:
I am class
Traceback (most recent call last):
File "test.py", line 17, in <module>
B.two()
TypeError: unbound method two() must be called with B instance as first argument (got nothing instead)
Run Code Online (Sandbox Code Playgroud)
似乎@classmethod装饰器在类中保留,但@staticmethod不是.
Python 3.4的行为符合预期:
I am class
I am static
Run Code Online (Sandbox Code Playgroud)
为什么Python2不能保留@staticmethod,是否有解决方法?
编辑:从课堂上取两个(并保留@staticmethod)似乎有效,但这对我来说似乎仍然很奇怪.
python static-methods class-method python-2.7 python-descriptors
我理解为什么self 始终是类方法的第一个参数,这是完全有道理的,但如果它总是如此,那么为什么要为每个方法定义经历打字的麻烦?为什么不在幕后自动完成?
是为了清楚还是在某种情况下你可能不想把自己作为第一个论点?
class-method ×10
python ×6
class ×3
methods ×2
objective-c ×2
closures ×1
coding-style ×1
decorator ×1
dynamic ×1
instance ×1
ios ×1
protocols ×1
python-2.7 ×1
python-3.x ×1
ruby ×1
static ×1
swift ×1