Is it correct to say that objects can display polymorphism - oop

https://www.tutorialspoint.com/java/java_polymorphism.htm#:~:text=Polymorphism%20is%20the%20ability%20of,is%20considered%20to%20be%20polymorphic.
As per the link above, in which they say:
Polymorphism is the ability of an object to take on many forms.
I'm having trouble figuring out whether to take this literally or not.
From my knowledge of polymorphism, classes are polymorphic when they can have multiple children, each implementing a parent class method in a different way.
A function can be polymorphic as we can overload and override them so functions can display different behaviors.
I was told and taught that another form of polymorphism applies to objects that inherit from multiple parent classes.
In C++ for example an object may behave differently depending on its reference type if its methods aren't virtual.
Another example that comes to mind is in Java with multiple interfaces, I can look at an object as different types causing different expected behaviors.
Are these examples really considered polymorphism at play or is this just inheritance and Polymorphism best defines the first two examples (classes and methods)
Thanks

The literal meaning of the word "polymorphism" is what the tutorial says. However it makes very little sense to use the literal meaning of a technical term. In OOP, "polymorphism" means subtyping. There are other ways the term "polymorphism" is used in programming (ad-hoc and parametric polymorphism) but they are not related to OOP specifically.
"Polymorphic object" is not a standard term across the OOP literature. It has a very specific meaning in C++, and it's not "an object with several base classes". It is simply an object with at least one virtual function. From the OOP perspective, a C++ "polymorphic object" is just an object.
Deriving from more than one base classes is called multiple inheritance. I have never heard anyone using the term "polymorphism" for this.

Related

Is encapsulation just a capsula creation?

Recently I was talking to a very experienced programmer (8+ years of experience) and he told me that "combining data with functions that work with them in a capsula" is a wrong term for encapsulation. He told me that that was what encapsulation allowed me to do, but not what encapsulation itself was. He told me that as soon as inheritance is not possible without encapsulation, encapsulation must be just a capsula creation (class or anything like that). But today I got interviewed by a less experienced programmer and he was so sure all those classic definitions on wikipedia were right he told me not to even think of passing the interview. So I tried to google all that stuff about encapsulation, and about inheritence not being possible without encapsulation, but didn't find anything. But I can't believe that experienced programmer was wrong, he convienced not only me, but other experienced programmers too. Maybe that correct definition is just something that is lost in the chunks of useless and unimportant info?
So please, give me answers on these two questions:
1) can inheritence be possible without encapsulation? (A class's Inheritence from a class)
2) If not, then can we consider declaring a class encapsulation? Because only after declaring a class we can inherit.
Well, I'm Sorry, but I fail to see the connection between encapsulation and inheritance.
Encapsulation is hiding your internal implementation behind a publicly visible API.
Basically, it's a separation between a type's actual implementation and what it exposes.
In a broad sense, one can look at even the human body and see encapsulation:
For example: You are breathing air in and out, that's your public API, but the internals of what your body is doing with this air are hidden away inside your respiratory system - your lunges passes oxygen to your blood and collects from it carbon dioxide in return - thus changing the mixture ratio of the gasses in the air you breath, but none of this is visible to the outside world.
Inheritance, in the OOP world, is the ability to take a specific object, and derive an even more specific object from it, while adding capabilities (and sometimes mutating existing capabilities via overriding).
For example: A Dog is a kind of Mammal which is a kind of Animal.
An Animal might contain methods such as Eat() and properties such as Weight and Age.
A Mammal might override the Eat() method to implement suckling (from it's mother's breast) as an infant, but depending on it's age eating solid foods.
A Dog might introduce another capability such as Bark.
All of this have nothing to do with encapsulation as desribed in the previous paragraph.
Inheritance is tightly related to another core principle of object oriented programming called Polymorphism - basically, the ability to reference a derived class using it's base class type - perhaps you (or the interviewer) are confusing the two?
However, today is the first time I've seen another definition of encapsulation (and I've been working with oop languages for about two decades now):
A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.
Under that
definition, encapsulation is the process of creating capsules - stand-alone code snippets that holds data and ways to interact with it - a.k.a types, classes, etc', and is somewhat related to inheritance - in order to inherit a type, that type first needs to be defined.
However, the way I see it, this definition is not enough to define encapsulation. It can be a part of the definition, but not a stand-alone definition of encapsulation.

What is the difference between subtyping and inheritance in OO programming?

I could not find the main difference. And I am very confused when we could use inheritance and when we can use subtyping. I found some definitions but they are not very clear.
What is the difference between subtyping and inheritance in object-oriented programming?
In addition to the answers already given, here's a link to an article I think is relevant.
Excerpts:
In the object-oriented framework, inheritance is usually presented as a feature that goes hand in hand with subtyping when one organizes abstract datatypes in a hierarchy of classes. However, the two are orthogonal ideas.
Subtyping refers to compatibility of interfaces. A type B is a subtype of A if every function that can be invoked on an object of type A can also be invoked on an object of type B.
Inheritance refers to reuse of implementations. A type B inherits from another type A if some functions for B are written in terms of functions of A.
However, subtyping and inheritance need not go hand in hand. Consider the data structure deque, a double-ended queue. A deque supports insertion and deletion at both ends, so it has four functions insert-front, delete-front, insert-rear and delete-rear. If we use just insert-rear and delete-front we get a normal queue. On the other hand, if we use just insert-front and delete-front, we get a stack. In other words, we can implement queues and stacks in terms of deques, so as datatypes, Stack and Queue inherit from Deque. On the other hand, neither Stack nor Queue are subtypes of Deque since they do not support all the functions provided by Deque. In fact, in this case, Deque is a subtype of both Stack and Queue!
I think that Java, C++, C# and their ilk have contributed to the confusion, as already noted, by the fact that they consolidate both ideas into a single class hierarchy. However, I think the example given above does justice to the ideas in a rather language-agnostic way. I'm sure others can give more examples.
A relative unfortunately died and left you his bookstore.
You can now read all the books there, sell them, you can look at his accounts, his customer list, etc. This is inheritance - you have everything the relative had. Inheritance is a form of code reuse.
You can also re-open the book store yourself, taking on all of the relative's roles and responsibilities, even though you add some changes of your own - this is subtyping - you are now a bookstore owner, just like your relative used to be.
Subtyping is a key component of OOP - you have an object of one type but which fulfills the interface of another type, so it can be used anywhere the other object could have been used.
In the languages you listed in your question - C++, Java and C# - the two are (almost) always used together, and thus the only way to inherit from something is to subtype it and vice versa. But other languages don't necessarily fuse the two concepts.
Inheritance is about gaining attributes (and/or functionality) of super types. For example:
class Base {
//interface with included definitions
}
class Derived inherits Base {
//Add some additional functionality.
//Reuse Base without having to explicitly forward
//the functions in Base
}
Here, a Derived cannot be used where a Base is expected, but is able to act similarly to a Base, while adding behaviour or changing some aspect of Bases behaviour. Typically, Base would be a small helper class that provides both an interface and an implementation for some commonly desired functionality.
Subtype-polymorphism is about implementing an interface, and so being able to substitute different implementations of that interface at run-time:
class Interface {
//some abstract interface, no definitions included
}
class Implementation implements Interface {
//provide all the operations
//required by the interface
}
Here, an Implementation can be used wherever an Interface is required, and different implementations can be substituted at run-time. The purpose is to allow code that uses Interface to be more widely useful.
Your confusion is justified. Java, C#, and C++ all conflate these two ideas into a single class hierarchy. However, the two concepts are not identical, and there do exist languages which separate the two.
If you inherit privately in C++, you get inheritance without subtyping. That is, given:
class Derived : Base // note the missing public before Base
You cannot write:
Base * p = new Derived(); // type error
Because Derived is not a subtype of Base. You merely inherited the implementation, not the type.
Subtyping doesn't have to be implemented via inheritance. Some subtyping that is not inheritance:
Ocaml's variant
Rust's lifetime anotation
Clean's uniqueness types
Go's interface
in a simple word: subtyping and inheritance both are polymorphism, (inheritance is a dynamic polymorphism - overriding). Actually, inheritance is subclassing, it means in inheritance there is no warranty to ensure capability of the subclass with the superclass (make sure subclass do not discard superclass behavior), but subtyping(such as implementing an interface and ... ), ensure the class does not discard the expected behavior.

Is it a bad design to create a small class with two methods solely for inheritance?

I want to create a class with two methods, and no other purpose than so I can create two subclasses which inherit the methods. This class cannot function on its own. Is this a bad programming design or habit?
There are even classes that don't do anything, other than letting other classes derive from it. It doesn't matter whether the superclass can have useful instances themselves. Classes that only exist for other classes to derive from are often called abstract classes; some languages such as C++ also have syntax features to allow the compiler to give errors when you try to create an object from an abstract class. So it can't be THAT bad to have classes like this.
Beyond that, what's "bad practice"? If the setup makes the code easier to understand then it can't be bad.
Of course, if the two classes you intend to derive really don't have anything in common and those two methods are merely "hey, I noticed that 10 lines of code in that class are the same as these 10 lines in the other class", then making this into a common superclass may confuse more than help. Classes should still have some form of relationship. If it's just about sharing some code that randomly happens to show up here and there, standalone functions might be a better choice.
Basically, look at the names of the classes. If your new superclass is named something along the lines of "Some very generic name 'cause I have no idea what it is", then it's probably not "good design". If, on the other hand, you have a proper name for the superclass, and the names of the derived classes are still something that has a "kind of" relationship to the superclass, then it's probably not a bad thing.
Another strong hint for something being "good" is when you start using pointers to the superclass because you don't care whether you're dealing with one or the other subclass.
Its a good habit, it leads to better organization of functions. Another reason is you can just look at the inheritance tree and know that it is related to the two function class. There isn't much harm in it.
There is no inherent good or bad, in general. It depends a lot on the specifics of situation. But, in general, you should always try to follow the principles of object-orientation. For example, whenever you are creating a class, whether abstract or concrete, the class should have both data and behaviour. This rule is very important, it goes all the way to the very foundation of object-orientation. A class without data, is just a bunch of methods (this is procedural programming, not OO). A class without behavior, is a bunch of variables (again procedural, not OO). So, having both data and behavior together is important. But, they should have logical relation to each other, not randomly put together. For example, a method should access data in some way.
Of course, there are deviations from this rule. For example, you may have just a bunch of methods in a static class (like Math class in Java), or just a bunch of constanst in a Interface. But, they are exceptions not rule. They are there, out of necessity, for convenience. They are not true classes in the strict object-oriented sense.
So, always aim toward the right principles, and deviate only when there is no other way to accomplish it, and only as an exception, not as a rule.
The previous point was refering to how to structure a class. For designing relationship among classes, again, the logical path should be followed. Think through each concept that you are dealing with and see if each one makes sense as a class, and then see what is the relationship among these classes. If it looks the you have three concepts that can be organized in inheritance - two classes deriving from a parent, the so be it. If the parent class has two methods, its ok. Even if it has one method, it is still OK. As long as it represents a coherent logical unit.

Why avoid subtyping?

I have seen many people in the Scala community advise on avoiding subtyping "like a plague". What are the various reasons against the use of subtyping? What are the alternatives?
Types determine the granularity of composition, i.e. of extensibility.
For example, an interface, e.g. Comparable, that combines (thus conflates) equality and relational operators. Thus it is impossible to compose on just one of the equality or relational interface.
In general, the substitution principle of inheritance is undecidable. Russell's paradox implies that any set that is extensible (i.e. does not enumerate the type of every possible member or subtype), can include itself, i.e. is a subtype of itself. But in order to identify (decide) what is a subtype and not itself, the invariants of itself must be completely enumerated, thus it is no longer extensible. This is the paradox that subtyped extensibility makes inheritance undecidable. This paradox must exist, else knowledge would be static and thus knowledge formation wouldn't exist.
Function composition is the surjective substitution of subtyping, because the input of a function can be substituted for its output, i.e. any where the output type is expected, the input type can be substituted, by wrapping it in the function call. But composition does not make the bijective contract of subtyping-- accessing the interface of the output of a function, does not access the input instance of the function.
Thus composition does not have to maintain the future (i.e. unbounded) invariants and thus can be both extensible and decidable. Subtyping can be MUCH more powerful where it is provably decidable, because it maintains this bijective contract, e.g. a function that sorts a immutable list of the supertype, can operate on the immutable list of the subtype.
So the conclusion is to enumerate all the invariants of each type (i.e. of its interfaces), make these types orthogonal (maximize granularity of composition), and then use function composition to accomplish extension where those invariants would not be orthogonal. Thus a subtype is appropriate only where it provably models the invariants of the supertype interface, and the additional interface(s) of the subtype are provably orthogonal to the invariants of the supertype interface. Thus the invariants of interfaces should be orthogonal.
Category theory provides rules for the model of the invariants of each subtype, i.e. of Functor, Applicative, and Monad, which preserve function composition on lifted types, i.e. see the aforementioned example of the power of subtyping for lists.
One reason is that equals() is very hard to get right when sub-typing is involved. See How to Write an Equality Method in Java. Specifically "Pitfall #4: Failing to define equals as an equivalence relation". In essence: to get equality right under sub-typing, you need a double dispatch.
I think the general context is for the lanaguage to be as "pure" as possible (ie using as much as possible pure functions), and comes from the comparison with Haskell.
From "Ruminations of a Programmer"
Scala, being a hybrid OO-FP language has to take care of issues like subtyping (which Haskell does not have).
As mentioned in this PSE answer:
no way to restrict a subtype so that it can't do more than the type it inherits from.
For example, if the base class is immutable and defines a pure method foo(...), derived classes must not be mutable or override foo() with a function that is not pure
But the actual recommendation would be to use the best solution adapted to the program you are currently developing.
Focusing on subtyping, ignoring the issues related to classes, inheritance, OOP, etc.. We have the idea subtyping represents a isa relation between types. For example, types A and B have different operations but if A isa B we then can use any of B's operations on an A.
OTOH, using another traditional relation, if C hasa B then we can reuse any of B's operations on a C. Usually languages let you write one with a nicer syntax, a.opOnB instead of a.super.opOnB as it would be in the case of composition, c.b.opOnB
The problem is that in many cases there's more than one way to relate two types. For example Real can be embedded in Complex assuming 0 on the imaginary part, but Complex can be embedded in Real by ignoring the imaginary part, so both can be seen as subtypes of the other and subtyping forces one relation to be viewed as preferred. Also, there are more possible relations (e.g. view Complex as a Real using theta component of polar representation).
In formal terminology we usually say morphism to such relations between types and there are special kinds of morphisms for relations with different properties (e.g. isomorphism, homomorphism).
In a language with subtyping usually there's much more sugar on isa relations and given many possible embeddings we tend to see unnecessary friction whenever we're using the unpreferred relation. If we bring inheritance, classes and OOP to the mix the problem becomes much more visible and messy.
My answer does not answer why it is avoided but tries to give another hint at why it can be avoided.
Using "type classes" you can add an abstraction over existing types/classes without modifying them. Inheritance is used to express that some classes are specializations of a more abstract class. But with type classes you can take any existing classes and express that they all share a common property, for example they are Comparable. And as long as you are not concerned with them being Comparable you don't even notice it. The classes don't inherit any methods from some abstract Comparable type as long as you don't use them. It's a bit like programming in dynamic languages.
Further reads:
http://blog.tmorris.net/the-power-of-type-classes-with-scala-implicit-defs/
http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html
I don't know Scala, but I think the mantra 'prefer composition over inheritance' applies for Scala exactly the way it does for every other OO programming language (and subtyping is often used with the same meaning as 'inheritance'). Here
Prefer composition over inheritance?
you will find some more information.
I think lots of Scala programmers are former Java programmers. They are used to think in term of Object Oriented subtyping and they should be able to easily find OO-like solution for most problems. But Functional Programing is a new paradigm to discover, so people ask for a different kind of solutions.
This is the best paper I have found on the subject. A motivating quote from the paper –
We argue that while some of the simpler aspects of object-oriented languages are
compatible with ML, adding a full-fledged class-based object system to ML leads to an excessively complex
type system and relatively little expressive gain

OOP Reuse without Inheritance: How "real-world" practical is this?

This article describes an approach to OOP I find interesting:
What if objects exist as
encapsulations, and the communicate
via messages? What if code re-use has
nothing to do with inheritance, but
uses composition, delegation, even
old-fashioned helper objects or any
technique the programmer deems fit?
The ontology does not go away, but it
is decoupled from the implementation.
The idea of reuse without inheritance or dependence to a class hierarchy is what I found most astounding, but how feasible is this?
Examples were given but I can't quite see how I can change my current code to adapt this approach.
So how feasible is this approach? Or is there really not a need for changing code but rather a scenario-based approach where "use only when needed or optimal"?
EDIT: oops, I forgot the link: here it is link
I'm sure you've heard of "always prefer composition over inheritance".
The basic idea of this premise is multiple objects with different functionalities are put together to create one fully-featured object. This should be preferred over inheriting functionality from disparate objects that have nothing to do with each other.
The main argument regarding this is contained in the definition of the Liskov Substitution Principle and playfully illustrated by this poster:
If you had a ToyDuck object, which object should you inherit from, from a purely inheritance standpoint? Should you inherit from Duck? No -- most likely you should inherit from Toy.
Bottomline is you should be using the correct method of abstraction -- whether inheritance or composition -- for your code.
For your current objects, consider if there are objects that ought to be removed from the inheritance tree and included merely as a property that you can call and invoke.
Inheritance is not well suited for code reuse. Inheriting for code reuse usually leads to:
Classes with inherited methods that must not be called on them (violating the Liskov substitution principle), which confuses programmers and leads to bugs.
Deep hierarchies where it takes inordinate amount of time to find the method you need when it can be declared anywhere in dozen or more classes.
Generally the inheritance tree should not get more than two or three levels deep and usually you should only inherit interfaces and abstract base classes.
There is however no point in rewriting existing code just for sake of it. However when you need to modify, try to switch to composition where possible. That will usually allow you to modify the code in smaller pieces, since there will be less coupling between the classes.
I just skimmed the text over, but it seems to say what OO design was always about: Inheritance is not meant as a code reuse tool and loose coupling is good. This has been written dozens times before, see the linked references on the article bottom. This does not mean you should skip inheritance entirely, you just have to use it conciously and only when it makes sense. The article also states this.
As for the duck typing, I find the examples and thoughts questionable. Like this one:
function good (foo) {
if ( !foo.baz || !foo.quux ) {
throw new TypeError("We need foo to have baz and quux methods.");
}
return foo.baz(foo.quux(10));
}
What’s the point in adding three new lines just to report an error that would be reported by the runtime automatically?
Inheritance is fundamental
no inheritance, no OOP.
prototyping and delegation can be used to effect inheritance (like in JavaScript), which is fine, and is functionally equivalent to inheritance
objects, messages, and composition but no inheritance is object-based, not object-oriented. VB5, not Java. Yes it can be done; plan on writing a lot of boilerplate code to expose interfaces and forward operations.
Those that insist inheritance is unnecessary, or that it is 'bad' are creating strawmen: it is easy to imagine scenarios where inheritance is used badly; this is not a reflection on the tool, but on the tool-user.