我正在尝试从协议扩展中覆盖实例方法,我遇到了一些麻烦。
对于上下文,我正在制作一个包含许多不同UICollectionViews的iOS应用程序。这些视图从不同的数据库(需要不同的回调函数)获取数据,并具有非常不同的布局。因为(数据库,布局)的任何组合都是可能的,所以如果没有大量的代码重复,很难创建一个漂亮的OOP类层次结构。
我有想法将布局函数(主要是在UICollectionViewDelegateFlowLayout协议中定义的那些)放入协议扩展中,因此我可以使用扩展的协议来装饰给定的UICollectionView子类,以实现所有相关的布局函数,但我有很难过。问题的实质包含在下面的代码中。
class Base {
func speak(){
print("Base")
}
}
class SubA: Base, ProtocolA {}
class SubB: Base, MyProtocolB {}
protocol MyProtocolA{
func speak()
}
protocol MyProtocolB{
func speak()
}
extension MyProtocolA{
func speak(){
print("A")
}
}
extension MyProtocolA{
func speak(){
print("B")
}
}
let suba = SubA()
suba.speak() // prints "Base", I want it to print "A"
let subb = SubB()
subb.speak() // prints "Base", I want it to print "B"
思想?
答案 0 :(得分:4)
仅当符合这些协议的类未实现该方法本身时,才会调用协议中的默认实现。课程'方法会覆盖协议的默认实现,而不是相反。
通常情况下,您可以执行以下操作:
<script>
$('a[href$=\\.pdf]').click(function() {
var myuri = this.href ;
alert(this.href);
/*alert just to make sure I got the right uri (which works fine)*/
cordova.plugins.fileOpener2.open(
'this.href', // You can also use a Cordova-style file uri: cdvfile://localhost/persistent/Download/starwars.pdf
'application/pdf',
{
error : function(e)
{
alert('Error status: ' + e.status + ' - Error message: ' + e.message);
},
success : function ()
{
alert('file opened successfully');
}
}
);
return false;
});
</script>
但如果你这样做
protocol MyProtocolA {
func speak()
}
protocol MyProtocolB {
func speak()
}
extension MyProtocolA {
func speak() {
print("A")
}
}
extension MyProtocolB {
func speak() {
print("B")
}
}
class SubA: MyProtocolA {}
class SubB: MyProtocolB {}
let suba = SubA()
suba.speak() // prints "A"
let subb = SubB()
subb.speak() // prints "B"
坦率地说,在您看到这一点时,class SubC: MyProtocolA {
func speak (){
print("C")
}
}
let subc = SubC()
subc.speak() // prints "C"
的使用在此示例中完全是多余的,因此我已将其删除。显然,如果您因其他原因需要从Base
继承,请随意。但关键的一点是,协议默认实现不会覆盖类&#39;实施,而是反过来。