Reputation: 11754
I've been working in Java
for past few years, and now am learning Swift
. I was trying to implement Java
abstract classes in Swift
and found out that Swift
doesn't support it. I've also seen that the abstract
classes can be achieved through protocol
, but as my class contains generic type, I am bit confused about it.
I've created a Java
class structure and tried to convert it to Swift, But I failed. Here's the class
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]
Asking all my doubts and questions about this topic would be a mess. So the converted code (Java -> Swift)
will fix all my doubts. Could anyone help me by converting the above code to Swift
?
NOTE: I need forced overriding like in Java.
Upvotes: 3
Views: 529
Reputation: 273115
I strongly suggest you redesign your model in Swift. Just like when translating spoken languages, the outcome can sound very awkward, programming languages, when translated, can look awkward too. If you still want to translate from Java, read on.
The really hard problem to solve here is that B
is generic. If B
wasn't generic, everything would work way better in Swift.
For now, you just have to use a class
and pretend it is a protocol:
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"))
If B
were not generic (you are not using the generic argument anyway), then this can be done:
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"))
Upvotes: 1