Reputation: 353
I have a function which takes one argument. I wanted my function to accept two object types. How can I do it? Here is the example below:
func accept(user: Customer) {
...
}
It should accept Customer and Employee object reference.
accept(objRefCustomer)
accept(objRefEmployee)
Please help me in this case.
Upvotes: 8
Views: 6227
Reputation: 392
create a protocol
, and use it as argument type. protocol can be also empty, it will work anyway. Works with struct
and class
as well;
ex:
protocol SomeFakeProtocol {}
class SomeClass: SomeFakeProtocol { //code here }
struct SomeStruct: SomeFakeProtocol { //code here }
func someFunction(arg: SomeFakeProtocol) { //code here }
Benefits - you can allow to use only types you want to. And, sure, you can do things like this:
extension String: SomeFakeProtocol {}
Upvotes: 3
Reputation: 73186
You needn't necessarily use a superclass for this case (if Customer
and Employee
are struct value types; superclass option is not possible), but can rather use the more generic approach of protocols.
Define a protocol Users
which blueprints properties and methods for your Customer
and Employee
instances (if we let Customer
and Employee
conform to Users
, then we promise that instances of these two structures will have accessible the blueprinted properties and methods):
protocol Users {
var name: String { get }
func printTypeOfUser()
}
Define the Customer
and Employee
structures, and their conformance to the protocol Users
:
struct Customer : Users {
let name: String
init(name: String) { self.name = name }
func printTypeOfUser() {
print("Is a Customer!")
}
}
struct Employee : Users {
let name: String
let id: Int
init(name: String, id: Int) { self.name = name; self.id = id }
func printTypeOfUser() {
print("Is an Employee!")
}
}
Now you can define a generic function where its generic, say T
, is type constrained to types conforming to the protocol Users
, which in this case is equivalent to the Customer
or Employee
types
func accept<T: Users>(user: T) {
print("Name of user: \(user.name) [\(user.dynamicType)]")
user.printTypeOfUser()
// do something additional employee-specific if user is an employee?
if let employee = user as? Employee {
print("User is an employee with id: \(employee.id)")
}
}
Example usage of this function for Employee
as well as Customer
instances:
let employee = Employee(name: "John", id: 1)
let customer = Customer(name: "Sarah")
accept(employee) /* Name of user: John [Employee]
Is an Employee!
User is an employee with id: 1 */
accept(customer) /* Name of user: Sarah [Customer]
Is a Customer! */
Upvotes: 7
Reputation: 151
You don't need a super class, you can just pass an object of type AnyObject and in your function check the type of the object passed:
func accept(user: AnyObject) {
if let usr = user as? Person {
...
}
}
But if you have many types you want to pass you may want to make a protocol or a super class.
Upvotes: 1
Reputation: 5618
Instead of changing your Class structure and code base, you can use AnyObject
. It will also be easier for you if, for example, in future you have to make this function accept parameters of class WaterMelon
. Making all these classes inherit from a common parent class would be unnecessary overhead, not to mention hectic.
AnyObject is swift equivalent of objective c id
. AnyObject is a protocol that can represent an instance of any class type.
It also has a more general counterpart, Any
, which can represent any type at all (including structs
and enums
).
Following code will accept any class type parameter you pass:
func accept(sender : AnyObject) { //Or AnyObject? if you want to handle nil as well
...
}
To access properties of the classes you pass as AnyObject
, you can use type casting.
For example below code will check sender type and typecast it for you:
if let customerRef = sender as? Customer {
// ...
// Sender is of customer class type. Use it with customerRef that we created
let customerName = customerRef.dynamicType.sampleNameProperty //Access a property of class Customer
customerRef.funcOfCustomerClass() //Call a method of class Customer
}
else{
//Sender is not of customer class type.
//Then it must be Employee??? Handle cases for employee here.
}
Upvotes: 5
Reputation: 11692
You can create a super class called People
of Cutomer
and Employee
.
Then set user
as type of People
:
func accept(user: People) {
...
}
Upvotes: 2