0

I have code like this:

class A {
    func method() { print("method from A") }
}

class B: A {
    override func method() { print("method from B") }
}

class C: A {
    override func method() { print("method from C") }
}


func run (_ obj: A) {
    doIt(obj)
}

func doIt(_ obj: A) {
    print("specific logic when object of A class")
    obj.method()
}

func doIt(_ obj: B) {
    print("specific logic when object of B class")
    obj.method()
}

func doIt(_ obj: C) {
    print("specific logic when object of C class")
    obj.method()
}


let obj = C()
run(obj)

I am getting output:

specific logic when object of A class method from C

but i would expect:

specific logic when object of C class method from C

How should I change the code to get this behavior?

David Silva
  • 1,939
  • 7
  • 28
  • 60
  • Overload resolution is done at compile time (compare e.g https://stackoverflow.com/q/41980001/2976878); inside `run(_:)`, the only thing the compiler knows about `obj` is that it's an `A`, so `doIt(_ obj: A)` is called. Make `doIt` an instance method on `A` (which you can override in subclasses) if you want polymorphism. – Hamish Nov 28 '17 at 20:53

2 Answers2

2

The problem is merely that you have made doIt three loose functions. Instead, make it three methods of the three classes:

class A {
    func method() { print("method from A") }
    func doIt() {
        print("specific logic when object of A class")
        self.method()
    }
}

class B: A {
    override func method() { print("method from B") }
    override func doIt() {
        print("specific logic when object of B class")
        self.method()
    }
}

class C: A {
    override func method() { print("method from C") }
    override func doIt() {
        print("specific logic when object of C class")
        self.method()
    }
}


func run (_ obj: A) {
    obj.doIt()
}

Now polymorphism does the work for you.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 1
    Indeed, in general the basic rule of object-oriented programming is: _any_ time you find your code trying to make a choice between classes, you're doing it wrong. You should be letting polymorphism _make_ the choice; that's what it's for. – matt Nov 28 '17 at 20:58
1

Although polymorphism is the best approach, here is another way you can do it

class A {
    func method() { print("method from A") }
}

class B: A {
    override func method() { print("method from B") }
}

class C: A {
    override func method() { print("method from C") }
}


func run<T: A>(_ obj: T) {
    doIt(obj)
}

func doIt<T: A>(_ obj: T) {
    print("specific logic when object of \(T.self) class")
    obj.method()
}

let obj = C()
run(obj)
TNguyen
  • 1,041
  • 9
  • 24