Swift中的抽象类

时间:2018-04-21 07:24:21

标签: java ios swift

过去几年我一直在Java工作,现在正在学习Swift。我试图在Java中实现Swift个抽象类,并发现Swift不支持它。我也看到abstract类可以通过protocol来实现,但由于我的类包含泛型类型,我对它有点困惑。

我已经创建了一个Java类结构,并尝试将其转换为Swift,但我失败了。这是班级

import java.util.List;
import java.util.ArrayList;

public class HelloWorld{

     public static void main(String []args){
        D d = new D();
        d.sayHello();
        d.sayHi();
        d.sayGracias();

        System.out.println(d.get("Hello"));
     }

     static class A{
         public void sayHello(){
             System.out.println("Hello from A");
         }
     }

     static class B<R> extends A{
        public void sayHi(){
            System.out.println("Hi from B");
        }   
     }

     static abstract class C<M,R> extends B<R>{

         public abstract List<M> get(R r);

         public void sayGracias(){
            System.out.println("Gracias from C");
         } 
     }

     static class D extends C<String, String>{

         @Override 
         public List<String> get(String s){
             List<String> list = new ArrayList<String>();
             list.add(s);
             return list;
         }
     }

}

输出

Hello from A
Hi from B
Gracias from C
[Hello]

询问我对这个话题的所有怀疑和疑问将是一团糟。所以转换后的代码(Java -> Swift)将解决我所有的疑虑。任何人都可以通过将上述代码转换为Swift来帮助我吗?

注意:我需要像Java一样强制覆盖。

1 个答案:

答案 0 :(得分:1)

我强烈建议您在Swift中重新设计模型。就像翻译口语一样,结果听起来很尴尬,编译语言在翻译时也会显得很尴尬。如果您仍想从Java翻译,请继续阅读。

这里要解决的真正难题是B是通用的。如果B不是通用的,那么在Swift中一切都会更好。

目前,您只需使用class并假装它是一个协议:

class A {
    func sayHello() {
        print("Hello from A")
    }
}

class B<R> : A {
    func sayHi() {
        print("Hi from B")
    }
}

class C<M, R> : B<R> {
    // this fatalError() thing is really ugly, but I can't think of any other workarounds
    func get(r: R) -> [M] { fatalError() }
    func sayGracias() {
        print("Gracias from C")
    }
}

class D : C<String, String> {
    override func get(r: String) -> [String] {
        return [r]
    }
}

let d = D()
d.sayHello()
d.sayHi()
d.sayGracias()
print(d.get(r: "Hello"))

如果B不是通用的(你还没有使用泛型参数),那么可以这样做:

class A {
    func sayHello() {
        print("Hello from A")
    }
}

class B : A {
    func sayHi() {
        print("Hi from B")
    }
}

protocol C {
    // associated types in Swift are kind of like generic parameters for protocols
    associatedtype M
    associatedtype R
    func get(r: R) -> [M]
}

extension C {
    func sayGracias() {
        print("Gracias from C")
    }
}

// You have to specify that D inherits from B as well since protocols can't inherit from classes
class D : B, C {
    typealias M = String
    typealias R = String

    func get(r: String) -> [String] {
        return [r]
    }
}

let d = D()
d.sayHello()
d.sayHi()
d.sayGracias()
print(d.get(r: "Hello"))