我有一个协议P,它返回一个对象的副本:
protocol P {
func copy() -> Self
}
Run Code Online (Sandbox Code Playgroud)
以及实现P的C类:
class C : P {
func copy() -> Self {
return C()
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我是否输入返回值,因为Self
我得到以下错误:
无法将类型为"C"的返回表达式转换为返回类型"Self"
我也试过回来了C
.
class C : P {
func copy() -> C {
return C()
}
}
Run Code Online (Sandbox Code Playgroud)
这导致以下错误:
非终结类'C'中的方法'copy()'必须返回
Self
以符合协议'P'
没有什么可行的,除了我前缀class C
为final
ie 的情况:
final class C : P {
func copy() -> C {
return C()
}
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我想继承C,那么什么都行不通.有没有办法解决?
public class MyGeneric<T, E> {}
public class Extend1<T, E> extends MyGeneric<T, E> {}
public class Extend2 extends MyGeneric<String, Object> {}
Run Code Online (Sandbox Code Playgroud)
据我所知,上例中的两个子类都是有效的.我想知道Java何时知道在实例化子类时何时定义超类中给出的类型,以及何时它们是实际的类名(即它如何知道T,E不是类名)?
附注,是否允许(即使不常见)为泛型类型使用多个字母?如果(通过计划的某些严重错误)类型与现有类冲突,例如
public class E{}
public class Foo<E>{}
Run Code Online (Sandbox Code Playgroud)
那会发生什么?
编辑:感谢您及时回答.要回答我的第一个问题,Joachim的答案是最有效的.
为了回答这一点,aioobe的答案更加清晰
我有3个班:
public class Alpha {
public Number number;
}
public class Beta extends Alpha {
public String number;
}
public class Gama extends Beta {
public int number;
}
Run Code Online (Sandbox Code Playgroud)
为什么以下代码编译?而且,为什么测试通过没有任何运行时错误?
@Test
public void test() {
final Beta a = new Gama();
a.number = "its a string";
((Alpha) a).number = 13;
((Gama) a).number = 42;
assertEquals("its a string", a.number);
assertEquals(13, ((Alpha) a).number);
assertEquals(42, ((Gama) a).number);
}
Run Code Online (Sandbox Code Playgroud) 当您在子类中重写方法时降低方法的可见性时,为什么编译器会给出错误消息?
我当前项目的UITableViewCell行为令我感到困惑.我有一个相当简单的UITableViewCell子类.它为基本视图添加了一些额外的元素(通过[self.contentView addSubview:...]
并设置元素上的背景颜色,使它们看起来像黑色和灰色矩形框.
因为整个表格的背景具有这种具体的纹理图像,所以每个单元格的背景都需要透明,即使在选中时也是如此,但在这种情况下它应该变暗一点.我已经设置了一个自定义的半透明选定背景来实现这个效果:
UIView *background = [[[UIView alloc] initWithFrame:self.bounds] autorelease];
background.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
background.opaque = NO;
[self setSelectedBackgroundView:background];
Run Code Online (Sandbox Code Playgroud)
虽然这样会产生正确的背景效果,但当我选择单元格时会出现奇怪的副作用; 所有其他背景在某种程度上turnt 关闭.这是一个截图.底部单元看起来应该并且未被选中.顶部单元格被选中,但它应该显示黑色和灰色的矩形区域,但它们已经消失了!
谁知道这里发生了什么,更重要的是:我怎么能纠正这个?
假设我有班级
class A {
protected:
int x,y;
double z,w;
public:
void foo();
void bar();
void baz();
};
Run Code Online (Sandbox Code Playgroud)
在我的代码和其他代码中定义和使用.现在,我想写一些可以很好地在A上运行的库,但它实际上更通用,并且能够操作:
class B {
protected:
int y;
double z;
public:
void bar();
};
Run Code Online (Sandbox Code Playgroud)
我确实希望我的库是通用的,所以我定义了一个B类,这就是它的API.
我希望能够告诉编译器 - 不是在我不再控制的A的定义中,而是在其他地方,可能在B的定义中:
请注意,请尝试将其
B
视为超类A
.因此,特别是,将它放在内存中,这样如果我重新解释A*
为aB*
,我的代码期望B*
s会起作用.并请然后实际接受A*
的B*
(和A&
作为B&
等等).
在C++中,我们可以通过另一种方式执行此操作,即如果B是我们无法控制的类,则可以执行"子类已知类"操作class A : public B { ... }
; 我知道C++没有相反的机制 - "通过新的B类超类化已知的A类".我的问题是 - 这个机制最接近可实现的近似值是多少?
笔记:
class A
.我只能修改B
知道两者A
和的代码的定义和代码 …子类化pandas类似乎是一个常见的需求,但我找不到关于这个主题的参考.(似乎熊猫开发者仍在努力:https://github.com/pydata/pandas/issues/60).
关于这个主题有一些SO主题,但我希望这里有人可以提供一个更系统的帐户,目前最好的方法是将pandas.DataFrame子类化,满足两个,我认为,一般要求:
import numpy as np
import pandas as pd
class MyDF(pd.DataFrame):
# how to subclass pandas DataFrame?
pass
mydf = MyDF(np.random.randn(3,4), columns=['A','B','C','D'])
print type(mydf) # <class '__main__.MyDF'>
# Requirement 1: Instances of MyDF, when calling standard methods of DataFrame,
# should produce instances of MyDF.
mydf_sub = mydf[['A','C']]
print type(mydf_sub) # <class 'pandas.core.frame.DataFrame'>
# Requirement 2: Attributes attached to instances of MyDF, when calling standard
# methods of DataFrame, should still attach to the output. …
Run Code Online (Sandbox Code Playgroud) 当您继承对象并希望扩展初始化代码时,有两种方法.覆盖__construct(),并实现超类构造函数调用的初始化方法.
方法1:
class foo
{
public function __construct ($arg1, $arg2, $arg3)
{
// Do initialization
}
}
class bar extends foo
{
public function __construct ($arg1, $arg2, $arg3)
{
parent::__construct ($arg1, $arg2, $arg3);
// Do subclass initialization
}
}
Run Code Online (Sandbox Code Playgroud)
方法2
class foo
{
public function init ()
{
// Dummy function
}
public function __construct ($arg1, $arg2, $arg3)
{
// Do subclass defined initialization
$this -> init ();
// Do other initialization
}
}
class bar extends foo
{
public …
Run Code Online (Sandbox Code Playgroud) 方案
我有一种情况,其中一个被调用的基类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结尾的文件名 …
subclassing ×10
java ×3
objective-c ×2
overriding ×2
php ×2
base-class ×1
c++ ×1
class ×1
cocoa-touch ×1
dataframe ×1
generics ×1
idiomatic ×1
jls ×1
oop ×1
pandas ×1
phpunit ×1
polymorphism ×1
properties ×1
protocols ×1
python ×1
superclass ×1
swift ×1
synthesis ×1
uitableview ×1
unit-testing ×1