方案
我有一种情况,其中一个被调用的基类AbstractRequest具有id <AbstractRequestDelegate>在头文件中声明的类型的委托属性:
@property (nonatomic, assign) id <AbstractRequestDelegate> delegate;
Run Code Online (Sandbox Code Playgroud)
抽象代表协议包含一些必要方法,并且与字"抽象"所指出的,无论是AbstractRequest与AbstractRequestDelegate旨在是子类/扩展.
其中一个例子是子类ConcreteRequest和扩展协议ConcreteRequestDelegates,它们都为抽象方法添加了额外的方法.目的是抽象和具体类方法都可以将消息发送到单个分配的委托实例.
在某个时间点,ConcreteRequest想要调用由ConcreteRequestDelegate定义的委托上的方法.由于委托的类型是id,因此编译器将发出警告,指出可能未实现此方法.
ConcreteRequest.m:38:警告:属性'委托'需要定义方法'-delegate' - 使用@synthesize,@ dynamic或提供方法实现
问题
这个警告是合理的,因为该属性毕竟是打字的id <AbstractRequestDelegate>.为了解决这个问题,我想向编译器说明分配给具体实例的委托必须是类型id <ConcreteRequestDelegate>.这对我来说听起来很合理,所以我在ConcreteRequest标头中添加了一个新属性,希望覆盖它的抽象:
@property (nonatomic, assign) id <ConcreteRequestDelegate> delegate;
Run Code Online (Sandbox Code Playgroud)
但这是编译器不同意我的地方,可能是有充分理由的.我本以为它会用一个错误的类型覆盖一个超级类的属性发出警告,但它只是要求我重新合成这个新属性.我不想去那里,因为那时超类的方法将无法访问相同的委托属性.
问题
有没有办法在具体子类中"重新声明"具有添加的类型信息的属性?或者你能否发现我的想法中的错误,因为这可能是一个相当常见的问题,直到现在我还没有遇到过?
干杯,
EP.
PS这项工作中出现的所有类和协议名称都是虚构的.任何与真实类和协议名称,开源或专利的相似之处纯属巧合.
如何创建扩展PHPUnit_Framework_TestCase的基类并将其用于子类化实际测试用例,而不需要PHPUnit对基类本身进行测试?
我有一系列相关的测试用例,我已经为其创建了一个基类,其中包含了所有测试用例都要继承的常见测试:
BaseClass_TestCase.php:
class BaseClass_TestCase extends PHPUnit_Framework_TestCase {
function test_common() {
// Test that should be run for all derived test cases
}
}
MyTestCase1Test.php:
include 'BaseClass_TestCase.php';
class MyTestCase1 extends BaseClass_TestCase {
function setUp() {
// Setting up
}
function test_this() {
// Test particular to MyTestCase1
}
}
MyTestCase2Test.php:
include 'BaseClass_TestCase.php';
class MyTestCase2 extends BaseClass_TestCase {
function setUp() {
// Setting up
}
function test_this() {
// Test particular to MyTestCase2
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,当我尝试在文件夹中运行所有测试时,它会失败(没有输出).
试图调试我发现问题在于基类本身是PHPUnit_Framework_TestCase的子类,因此PHPUnit也会尝试运行它的测试.(在那之前,我天真地认为只有在实际测试文件中定义的类 - 以Test.php结尾的文件名 …
我创建了一个自定义的UIView子类,并且不希望在UIView子类的代码中布局UI.我想用xib.所以我做的是以下内容.
我创建了一个类"ShareView",它是UIView的子类.我创建了一个XIB文件,其文件所有者设置为"ShareView".然后我链接我在"ShareView.h"中声明的一些出口.
接下来我有一个ViewController,MainViewController,它将ShareView添加为子视图.这段代码:
NSArray *arr = [[NSBundle mainBundle] loadNibNamed:@"ShareView" owner:nil options:nil];
UIView *fv = [[arr objectAtIndex:0] retain];
fv.frame = CGRectMake(0, 0, 320, 407);
[self.view addSubview:fv];
Run Code Online (Sandbox Code Playgroud)
但是现在我在ShareView中声明的插座上出现了NSUnknownKeyException错误.
我做这一切的原因是因为我想要一个UIView,在一个单独的XIB文件中有自己的逻辑.我在几个地方读到ViewControllers只用于管理全屏,即不是屏幕的一部分......那么我做错了什么?我想在单独的类中使用ShareView的逻辑,所以我的MainController类不会因为ShareView的逻辑而膨胀(我认为这是解决这个问题的一种方法吗?)
我在c#中有一个Asp.Net Web API 5.2项目,并使用Swashbuckle生成文档.
我有一个包含继承的模型,比如从Animal抽象类中获取Animal属性,从中派生出Dog和Cat类.
Swashbuckle只显示Animal类的模式,所以我尝试使用ISchemaFilter(他们也建议),但我无法使它工作,我也找不到合适的例子.
有人可以帮忙吗?
我最近正在处理我遇到的编码问题,有人看着代码说子类列表很糟糕(我的问题与那个类无关).他说你不应该这样做,而且它带来了一堆不好的副作用.这是真的?
我问的是列表是否通常对子类不好,如果是,那么原因是什么.或者,在Python中为子类化列表之前我应该考虑什么?
假设我有一个名为"Base"的类,以及一个名为"Derived"的类,它是Base的子类,并访问受保护的方法和Base的成员.
我现在想要做的就是让它没有其他类可以继承Derived.在Java中,我可以通过声明Derived类"final"来实现这一点.是否有一些C++技巧可以给我同样的效果?
(理想情况下,我希望除了Derived之外没有其他类可以将Base子类化.我不能只将所有代码放入同一个类或使用friend关键字,因为Base和Derived都是模板化的,模板参数比Derived少的基础....)
用于在PFObject子类上添加属性和方法的Parse文档在其示例代码中方便地跳过Swift语法,列出了Objective-C语法:
https://parse.com/docs/ios_guide#subclasses-properties/iOS
// Armor.h
@interface Armor : PFObject<PFSubclassing>
+ (NSString *)parseClassName;
@property (retain) NSString *displayName;
@end
// Armor.m
@dynamic displayName;
Run Code Online (Sandbox Code Playgroud)
有没有人想出一个解决Swift缺乏动态合成器的工作,以便用PFSubclassing实现属性和方法?我希望能够做到这样的事情:
class Armor : PFObject, PFSubclassing {
class func parseClassName() -> String! {
return "Armor"
}
}
var armor = Armor()
armor.displayName = "Iron Clad"
Run Code Online (Sandbox Code Playgroud) 我有一个UserForm类:
class UserForm(Form):
first_name = TextField(u'First name', [validators.Required()])
last_name = TextField(u'Last name', [validators.Required()])
middle_name = TextField(u'Middle name', [validators.Required()])
username = TextField(u'Username', [validators.Required()])
password = TextField(u'Password', [validators.Required()], widget=PasswordInput())
email = TextField(u'Email', [validators.Optional(), validators.Email()])
Run Code Online (Sandbox Code Playgroud)
并希望在UpdateUserForm中使密码字段成为可选:
class UpdateUserForm(UserForm):
password = TextField(u'Password', [validators.Optional()], widget=PasswordInput())
Run Code Online (Sandbox Code Playgroud)
但密码字段位于电子邮件字段之后,而不是之前.
如何在子类化时保留字段顺序?
此外,当我尝试更改密码字段验证器时它不起作用 - 密码仍然是必需的:/为什么?
class UpdateUserForm(UserForm):
def __init__(self, **kwargs):
self.password.validators = [validators.Optional()]
super(UpdateUserForm, self).__init__(**kwargs)
Run Code Online (Sandbox Code Playgroud)
要么
class UpdateUserForm(UserForm):
def __init__(self, **kwargs):
self.password = TextField(u'Password', [validators.Optional()], widget=PasswordInput())
super(UpdateUserForm, self).__init__(**kwargs)
Run Code Online (Sandbox Code Playgroud)
class UpdateUserForm(UserForm):
def __init__(self, formdata=None, obj=None, prefix='', **kwargs):
self._unbound_fields[4][1] = TextField(u'Password', …Run Code Online (Sandbox Code Playgroud) 我正在Swift中构建一个iOS应用程序,并利用Apple提供的Lister示例项目.
Lister使用两个模型对象:List和ListItem.我发现super.init()即使它们是NSObject的子类,它们都不会调用它们的初始化器.
但是,在Lister的Objective-C版本中,两个模型对象(AAPLList和AAPLListItem)都会调用[super init].
在斯威夫特编程语言中明确指出,"指定的初始化程序必须调用从他们的直接超类的指定初始化方法."(初始化程序链接在初始化的第1条)
这里发生了什么?为什么这是一个例外,如果你不应该总是在子类中调用super.init(),那么适用哪些规则?
subclassing ×10
c# ×2
ios ×2
objective-c ×2
python ×2
swift ×2
api ×1
base-class ×1
c++ ×1
final ×1
iphone ×1
keyword ×1
list ×1
nsobject ×1
oop ×1
openapi ×1
overriding ×1
php ×1
phpunit ×1
properties ×1
protected ×1
subclass ×1
swagger ×1
synthesis ×1
uiview ×1
unit-testing ×1
wtforms ×1