This is one of those weird programming terms that I never bothered to learn, but discovered that I had already been using for a long time.
Polymorphism is an object-oriented programming design pattern. When you create an object, you have one or more methods (or functions) that each have a predefined purpose, each being a tidy, reusable black of code that you can use over and over again. The concept of polymorphism allows you to have one reusable block of code, i.e., a function, and have another reusable block of code that implements the same functionality of the other block verbatim, in addition to extending that functionality in some way.
When I researched the term, polymorphism, I found plenty of examples that do a piss poor job of putting polymorphism into the context of a real-world programming scenario. I will now hereby attempt to make a better example. In my PHP framework, I have implemented my own file system. This file system has the ability to pull file content from a variety of sources and display files and folders in a neat, tidy GUI. For example, some of the files are pulled from a pseudo-file system that exists in a MySQL database. Other files are pulled directly from the server's file system, but the implementation of this is designed to be dependent on what OS the application is hosted on. I did it that way so that I could take advantage of OS-specific functionality. Another place you might pull files from are places like FTP or SSH servers. In fact, who's to say that the objects in your GUI file viewer, must fit 100%, the adhoc definition of a file? Maybe you want to access a mail server and display messages and message attachments in an inbox as files. My framework's file system is designed so that file content can come from any source. Creating a new source is done by creating an OOP API template that includes methods that each provide "file" data in the same way. This method of development facilitates the creation of plugins.
There are actually a few different ways that you can approach this problem, PHP5 provides object templating via interfaces. You can define a collection of methods and the arguments those methods should take, and their visibility indicator (private, protected, public) in an interface, then every time you want to implement a new way of accessing file content, you create a new object that implements that interface. Then, your file manager can intelligently pick the right interface to pull, depending on the content that you're accessing.
If you were to implement a polymorphic programming pattern, that programming pattern would define default functionality that would always be used. For example, you can have a base class that defines certain things about file management that are shared amongst all of the different ways that you access files. Then, in each individual object that implements a new template for accessing files, that new object extends the base object defining default functionality. Then the methods in that object call the default functionality of the parent object, and add whatever other functionality that you might need that is specific to that particular way of accessing files. So, in other words, polymorphism is one programming design pattern that helps facilitate code reusability.
The following example is one way this might look, when actually put into practice:
In the example, the generic methods that you want all of your file interface implementations to share are defined in an abstract class. Then, you create an interface that defines the API of all the methods that your file interface implementation will implement, you do this so that PHP will check your implementation for you, and if you make an error and leave out a method that your application needs to properly support a new file interface, PHP will bail out with a fatal error. So interfaces are really a tool to assist with debugging, and don't really add anything useful to the application from the standpoint of functionality.
In the implementation, which is the beginnings for a Unix-specific method of accessing files, the polymorphic programming pattern is implemented by extending the abstract class, implementing the interface, and then overriding the getIcon() method defined in the abstract class. You implement the getIcon() method in the hFileUnix object, because you want to extend the default method of getting file icons with additional functionality that's useful for when you're dealing with the Unix file system. Another interface might be called hFileWindows, which would have its own getIcon() method, which would have functionality useful for getting file icons on a Windows platform. Setting aside whether or not this approach of getting file icons would really be practical in a file application, you can see how you're able to define some kind of default functionality, and then override or extend that functionality within child objects.
Within the getIcon() method, you can do some logic to see if the file is an image, and respond with a thumbnail of the image, instead of a file icon, which you might have some interface-specific code for retrieving. If the file isn't an image, you fallback on the default logic defined in the abstract class, which you are able to call upon using the parent keyword.
Of course, you may not want to enforce the implementation of the getIcon() method in the interface portion, since you could conceivably just use the default method, by default, and only implement a polymorphic pattern where the need arises. The methods you choose to enforce implementation of will be entirely dependent on how the rest of your application functions, the gist of the thing being, you only want to enforce implementations of methods that your application cannot live without, ensuring an API pattern is met thus allowing you create and leverage a highly-reusable code base that's easy to extend in new ways. This is all the more useful, since often times, after you've created an application you'll come up with all sorts of new and creative ways that application can be evolved.
In closing, there is actually more than one way to approach this particular design goal. You can also have an object that uses the method and property overloading feature supported by PHP5. Method and property overloading allow you to call on properties and methods that are not defined, whereas those calls are diverted to magic functions where you are able to make your application respond dynamically depending on what method or property was called. This can be useful for a lot of things, one application that I've used that programming pattern for extensively is lumping lots of methods together that have identical or almost identical argument lists, or all have other code that has to be executed. Essentially, overloading lets you take the logic of several, independently defined methods, and stuff all that logic into just one method, allowing you to eliminate redundant code. In terms of the polymorphic programming pattern, you can also include default functionality using overloading, as needed, and your individual interfaces are dynamically loaded and called from that object. This is the approach that I actually took in the implementation of my own file management application, whichever you use really comes down to a matter of personal taste.