As I understand it in C # polymorphism is in the use of virtual members and in type casting, but I stumbled upon the mention of ad hoc polymorphism, and in no way can I understand how it differs from the use of virtual members?
- rsdn.org/forum/philosophy/2853873.1 - AK ♦
2 answers
As I understand it, ad hoc polymorphism is a type-based polymorphism. For different types of arguments, different function code is used.
One classic example is the method of overloading:
class C { public void f(int x) { Console.WriteLine("Cf(int)"); } public void f(string x) { Console.WriteLine("Cf(string)"); } } Here, the name f tied to two different methods, and the compiler chooses one or another method depending on the type of argument. This is an example of static ad hoc polymorphism: types must be known at the compilation stage, and the compiler knows exactly which method will be executed.
Another example of ad hoc polymorphism is the overriding of a virtual method:
class B { public virtual void f(int x) { Console.WriteLine("Bf(int)"); } } class D : B { public override void f(int x) { Console.WriteLine("Df(int)"); } } It also discriminates by type, but this time by the type of the implicit zero argument this . The selection of the overridden method is postponed at the time of execution; at the time of compilation, the compiler does not know exactly which of the group of redefined methods will be executed. This is an example of dynamic ad hoc polymorphism.
In addition, there is the concept of parametric polymorphism: this is a situation where the same method works with arguments of different types in the same way, regardless of their exact type. A trivial example for languages with inheritance (for example, C #) - a function that works with an object of some class C can often work without changes with an object generated from C class (this type of polymorphism is often called inclusion polymorphism ). A less trivial example is generic methods that can, depending on a generic parameter, work with different types of objects. Example:
class Enumerable { public T First(this IEnumerable<T> seq) { using (IEnumerator<T> en = seq.GetEnumerator()) { if (!en.MoveNext()) throw new InvalidOperationException(); return en.Current; } } } - Thanks for the detailed answer, but as I understood this use of
dynamic, although perhaps I didn’t figure it out correctly, the idea is that if some classes have a method of the same name (respectively, the method signature is the same), but these methods do not have a common parent or interface, then using dynamic, you can replace instances at runtime and call a method. - e1s 2:17 - one@ e1s: The
dynamicmethod inside is another valid example of parametric polymorphism. (But not ad hoc, in theory.) Although, calling the correct method usingf((dynamic)o)is again ad hoc polymorphism. - VladD 2:55 часто может без изменений работать с объектом порождённого от C класса- I will clarify: if this object follows the principle of Barbara Liskov's substitution . - ߊߚߤߘ
There are 3 main types of polymorphism (I will show on the example of php, c # I do not know):
- Ad hoc polymorphism - several function declarations with the same name but with different parameters, example:
When a function is called, the type of the argument will be selected.
function test (string $a, string $b) { return $a . $b; } function test (int $a, int $b) { return $a + $b; } // если бы в пхп поддерживалось, то вывело бы test('a', 'b') // 'ab' test(1, 4) // 5 - Parametric polymorphism - when the same function is executed, regardless of the types of arguments.
It is supported in php.
function test (string $a, string $b) { return $a . $b; } function test (int $a, int $b) { return $a + $b; } // если бы в пхп поддерживалось, то вывело бы test('a', 'b') // 'ab' test(1, 4) // 5 Parametric polymorphism is a true form of polymorphism, making the language more expressive and significantly increasing the code reuse rate. Traditionally, he is contrasted with ad hoc polymorphism (imaginary form).
- Subtype polymorphism - as far as I understand this is the most popular concept of polymorphism.
This is the ability of objects with the same specification to have a different implementation.
For example, there is a LoggerInterface interface, this is like a specification. If there are classes that implement this interface, for example, the FileLogger class and DBLogger, then this is called polymorphism.
interface LoggerInterface { public function log($logs); } class FileLogger implements LoggerInterface { public function log($logs) { // записывает логи в файл } } class DBLogger implements LoggerInterface { public function log($logs) { // записывает логи в БД } } Instead of an interface, there may be inheritance through an abstract (virtual) class or even a regular class.
That is, when there are methods in different classes that do the same, they can be given the same name and have these classes implement a single interface or inherit a single abstract class with this abstract method.