Last active
August 30, 2017 22:04
-
-
Save 46bit/4366791 to your computer and use it in GitHub Desktop.
An explanation of Duck Typing vs Polymorphism
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// When using Polymorphism, you might define an abstract class to send a message like | |
// follows, then fully implement it several times in different classes. | |
abstract class BaseMessage | |
public void setMessageText messageText | |
@messageText = messageText | |
end | |
public void send; | |
end | |
class EmailMessage extends BaseMessage | |
public void send | |
// code here to connect to mail server, send an email with @message, etc | |
end | |
end | |
class FacebookMessage extends BaseMessage | |
public void setMessageText messageText | |
// We can override the setMessageText definition in BaseMessage in both | |
// Polymorphism and Duck Typing | |
@messageText = messageText + "\n" | |
end | |
public void send | |
// code here to connect to Facebook and send the message | |
end | |
end | |
class NotAValidMessage // this class does not extend BaseMessage | |
public void setMessageText messageText | |
@messageText = messageText | |
end | |
public void send | |
// code here to do send this message somewhere | |
end | |
end | |
// If you then want to use any of these classes in a function, you do it like | |
// this. Whether the first argument is valid or not depends on it extending | |
// BaseMessage, thus passing NotAValidMessage would cause an error. | |
public void setMessageAndSend (BaseMessage message, messageText) | |
message.setMessageText(messageText) | |
message.send() | |
end | |
// If using duck typing, you'd define setMessageAndSend as follows: | |
public void setMessageAndSend (message, messageText) | |
message.setMessageText(messageText) | |
message.send() | |
end | |
// Notice that we don't specify any type for the first argument, merely | |
// assuming that what you pass does have functions named setMessageText | |
// and send. As such all of EmailMessage, FacebookMessage and | |
// NotAValidMessage can be passed to this alternative setMessageAndSend | |
// implementation. | |
________________________________________________________ | |
// It helps to consider why an example like this is useful. | |
// If you are working on a large application, you might allow users to | |
// send emails and Facebook messages but also you might allow your computer | |
// servers to message each other to perform different tasks. These two use | |
// cases might be rather different things, both conceptually and in the code | |
// base, so forcing them to extend the same class could seem inappropriate. | |
// If you want to let users schedule "Happy Christmas" messages for Christmas | |
// Day, then you'll want to have code that can cause a message to send without | |
// writing it twice for Emails and Facebook messages. Polymorphism is sufficient | |
// for this use case. | |
// However, if you now also want to schedule messages between your computer | |
// servers, you have the choice of duplicating your scheduling code used for | |
// user messages, or using duck typing to just make your message scheduling work | |
// for any type that can be sent. | |
// Questions? https://46bit.com/contact/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment