7

For instance, we have the Java code like following;

enum Job {
    NINJA(3000000){
        public void attack() {
            //use Shuriken
        }
    },
    SAMURAI(4000000){
        public void attack() {
            //use Sword
        }
    };
    public final int salary;
    public abstract void attack();
    private Job(int salary) {
        this.salary = salary;
    }
}

In Swift, I don't think we can define a constructor and have any methods of enum.

I found out we can have a similar structure in the following Swift code, but cannot have any methods.

class Job {
    class Store {
        let salary : Int
        init(int salary) {
            self.salary = salary
        }
    }
    class var NINJA: Store{
        return Store(3000000)
    }
    class var SAMURAI: Store{
        return Store(4000000)
    }
}
// Job.NINJA.salary

Of course, I know Swift enum can have their own properties.

But if you have more properties in the following case, we must have so many switch at each properties. I think it's not smart.

enum Job {
    var salary: Int{
        switch self{
        case NINJA:
            return 3000000
        case SAMURAI:
            return 4000000
        }
    }
    case NINJA
    case SAMURAI
}

So, if you were me, how do you write your Swift code in this case?

4
  • Do you mean you cannot add attack() method to Store class? Commented Jul 17, 2014 at 15:47
  • Not only to define the "attack" method, I also want to define each property values close to their own enum element definition. Commented Jul 17, 2014 at 17:49
  • I've updated the code, so now it shows how you can override methods of custom members. Commented Jul 17, 2014 at 19:10
  • @MitsuakiIshimoto serious question: why is a Samurai paid more than a Ninja ? Commented May 12, 2016 at 7:57

2 Answers 2

4

Example using struct in swift:

struct MyEnum {

    static let TYPE1 = MyEnum(id: 1, text: "type 1")
    static let TYPE2 = MyEnum(id: 2, text: "type 2")

    let id: Int
    let text : String

    init(id:Int, text:String) {
        self.id = id
        self.text = text
    }

    func getId()->Int {
        return id;
    }

    func getText() ->String {
        return text;
    }

    static func values()->Array<MyEnum> {
        return [TYPE1,TYPE2]
    }

}

func == (left: MyEnum, right: MyEnum) -> Bool {
    return left.id == right.id
}

Usage example:

for e in MyEnum.values() {
    println(String(e.getId()) + " " + e.getText())
}

let type1 = MyEnum.TYPE1
if (type1==MyEnum.TYPE1) {
    println("is Type 1")
} else {
    println("is not Type 1")
}

Console output

1 type 1
2 type 2
is Type 1
Sign up to request clarification or add additional context in comments.

Comments

2

Here is how you can tweak your Job class in Swift so it behave as enum in Java:

class Job {
    class Store: Equatable {
        let salary: Int
        
        @private init(_ salary:Int) { // hope Swift will have private accessors one day
            self.salary = salary
        }
        
        func atack() ->() {}

    }
    
    class var NINJA: Store {
        class Ninja: Store {
            override func atack() ->() {
                println("Attack with shuriken.")
            }
        }
        return Ninja(3000000)
    }
    
    class var SAMURAY: Store {
        class Samuray: Store {
            override func atack() ->() {
                println("Attack with sword.")
            }
        }
        return Samuray(4000000)
    }
    
    class func CUSTOM(salary: Int) -> Store {
        return Store(salary)
    }
}

func == (lhs: Job.Store, rhs: Job.Store) -> Bool {
    return lhs.salary == rhs.salary
}

Usage examples:

var ninja = Job.NINJA
var samuray = Job.SAMURAY
var custom = Job.CUSTOM(23)

if (ninja == samuray) {
    println("Impossible")
} else {
    println("OK")
}

if (ninja == Job.NINJA) {
    println("Ninja salary: \(ninja.salary)")
} else {
    println("Impossible")
}

println("Object salary: \(Job.SAMURAY.salary)")
samuray.atack()

Output in playground:

OK

Ninja salary: 3000000

Object salary: 4000000

Attack with sword.

BTW: Should you need to compare salary values you can implement Comparable interface in Store class. Useful for sorting.

3 Comments

You need to override attack() method so there is no way to do it without subclassing. And there is no anonymous classes in Swift, so we cannot do in-place override like we can in Java.
Good! (except the class of NINJA = Job.Store)
This is lacking the most important thing; exhaustive feature. Without it, it does not even make any sense to create such workaround

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.