How diamond problem in oops is solved using "shared" strategy? - oop

Diamond problem is handled in some OOPS languages (eg. curl) by having the repeatedly inherited class as "shared"? I want to know how this works. Also, I want to know the role played by primary and secondary constructors in solving the diamond problem in these OOPS languages when shared strategy is used.
Suppose there are 4 classes say A,B,C and D. Let the inheritance structure is B and C inherit A and D inherits both B and C. Each class has a variable say A has a, B has b, C has c and D has d. How does the object creation happens for each class?

Citing Wikipedia at https://en.wikipedia.org/wiki/Multiple_inheritance at the Curl
bullet:
Curl allows only classes that are explicitly marked as shared to be
inherited repeatedly. Shared classes must define a secondary
constructor for each regular constructor in the class. The regular
constructor is called the first time the state for the shared class is
initialized through a subclass constructor, and the secondary
constructor will be invoked for all other subclasses.
From here, without knowing Curl and only with the quote above and this, where it is stated that
The object semantics of Curl are similar to those of Java and C++.
Given
A
/ \
B(A) C(A)
\ /
D(B,C)
I imagine (I don't know for sure) that the coder is responsible to disambiguate the problem by specifying the qualified name of the constructor to run, when invoking a parent constructor from the D(B,C) subclass.
It looks like A has to be declared shared, and when D is created, B runs a constructor that calls A (primary) constructor, C runs a constructor that calls A (secondary) constructor. The distinction between primary/secondary constructor call is automatic and transparent to the coder.
As two A constructors are invoked, two A objects are created in memory, that is the A class is shared with two different subclasses, but there is not a single "shared" A object, but two independent ones (see also virtual/nonvirtual inheritance that is somehow related (C++).)
For what I've read for several different languages, it is almost always the coder that disambiguates the diamond problem with qualification. Languages just define different or similar schemes of giving an error, or having a criteria to choose one of the multiple ambiguous definitions, like specific search order in the inheritance chain. Some other languages don't even allow multiple inheritance, but in some of these you are allowed to extend functionality by some ohter means (like interfaces).

Related

Liskov substitution principle violation

From Wikipedia,
Liskov's notion of a behavioral subtype defines a notion of
substitutability for objects; that is, if S is a subtype of T, then
objects of type T in a program may be replaced with objects of type S
without altering any of the desirable properties of that program (e.g.
correctness).
Suppose the following class hierarchy:
The base abstract class - AnimalWithFur. It has a read-only property furColor that is overridden in successors.
Base class's successor - Cat, which overrides furColor and returns gray.
Cat's successor - Tiger, which overrides furColor and returns striped.
Then we declare a method with an argument of type Cat (not AnimalWithFur).
Is sending a Tiger instance to that method a violation of the L in SOLID?
Strictly speaking, yes. The wiki article summation of Liskov says:
"...in a program...without altering any of the desirable properties of that program"
If you go back to the original paper by Barbara Liskov, it's literally stricter in its wording, 3.3.
Type Hierarchy:
If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2
(Empahsis mine)
So if you replace an instance of Cat with another instance that does something different, i.e. returning stripped not grey, then that is a Liskov violation in the original sense, because a program could be easily defined that relies on the color being grey, here:
program(Cat c){
println(c.furColor);
}
The behaviour of that program will change if you pass it a Tiger in place of a Cat.
However, in the normal way LSP is applied, it is not a violation if you did not add extra preconditions or postconditions. This is a more practical, less academic definition as people accept that when replacing an instance of one concrete type with another you do intend to change the behaviour of the program while maintaining desirable properties of that program. So presuming the client code can handle stripped like any other colour, and grey was not required for a "desirable" property of the program then it does not violate.
Short answer: not necessarily. I'd have said not with the information you've given. The key, for me, is that you don't say what the imagined new method is supposed to do.
You might consider the behaviour that you're requiring in your new method to be more important than the concern of a class hierarchy.
One way to do this is to define an interface for the behaviour your new method needs from the passed in instance / argument.
Then whichever class you might want to pass into that method can implement that interface and you break apart the concern of an inheritance hierarchy and move to being concerned with consistency of behaviour.
Your question nicely describe why to use class composition instead of class inheritance. Firstly, your code is illogical - Tiger is not a Cat in your sense, Tiger is one of Cats family. From code point of view, it is bad design to override and totally replace the behavior of parent class, this is actually liskov substitution violation - your Cat class means defined cat with some concrete color, and application expects to work with it respectively, but you are overriding it with inconsistent type and change the behavior.
If you would describe types hierarchy correctly, you would have abstract type Cat without furColor implemented, and types Tiger and HomeCat, but HomeCat could have different color, isn't?
If you want to have trivial example of LS violation, e.g.:
You are extending List interface with custom implementation, returning size always 10, but with different count of objects inside. Each normal application expects to work with list using for statement, but will have unpredictable behavior because you've broken LS principle, and List object does not behave as it is expected.

Can Coldfusion components share methods without being descendants of the same super class

We have used a homegrown version of object oriented coldfusion for a while and I'm just starting to experiment with cfc's and how it "should" be done...
If I understand correctly, cfinterface defines the signature of functions, and any class that implements that interface must have their own functions to do whats defined in the interface.
I'm kind of trying to do the opposite - the interface doesn't just define the function's signature, but also defines the logic of the function and anything that implements that interface can use its functions without having to define it itself. Does that exist besides creating subclasses?
For example, say you have classes A,B,C,D that all belong to the Animal class
A & B can walk
A & C can talk
B & D can sleep
Suppose the logic of walk, talk & sleep (if the object can do it) is the same regardless of the class doing it
Ideally, if A & B both implement the walking interface, they can walk without defining a separate walk method in each class.
Or borrowing a better example from this java multiple inheritance question
A Pegasus is a mix of a Horse and a Bird because it runs like a horse
but flies like a bird
Is that possible? (I think this is multiple inheritance?)
In short: no, an interface only defines a contract, it does not (and cannot) define functionality). Also CFML does not have the concept of multiple inheritance.
You will have to use single-inheritance and concrete implementations to effect what you need. I can't be bothered assessing your implementation-sharing requirements to work out what an approrpriate class hierarchy might be to minimise code duplication. I'm sure you can do that yourself (and it's not really part of your question anyhow).
One tactic you could try is to use mixins for your common methods. Store the common methods in a different library, and then inject them into your objects as required. So basically Mixins.cfc would implement walk(), talk(), sleep(), and you'd have an AFactory.cfc, BFactory.cfc, CFactory.cfc. When asking a factory for a new A, B or C, and the factory method injects the mixin methods before returning the instances. Obviously this is a fairly cumbersome process, and you'd want to use some sort of IoC container to manage all this.
A better question might come out of you showing us more real world examples... I suspect your domain design could perhaps stand improvement if you find yourself needing to do what your example suggests. Actual design requirements are seldom exposed with examples using animals.
You can do similar things with WireBox and its Virtual Inheritance feature:
http://wiki.coldbox.org/wiki/WireBox.cfm#Virtual_Inheritance
// Declare base CFC
map("BaseModel").to("model.base.BaseModel");
map("UserService").to("model.users.UserService").virtualInheritance("BaseModel");
It's basically very similar to what Adam described above; a base class is created, and references to it's public members are placed in the sub class.
https://github.com/ColdBox/coldbox-platform/blob/master/system/ioc/Builder.cfc#L535
There's no reason why you can't build something similar but you should know this has already been done.
Full disclosure, I am a contributing member of the *Box community.

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.

General OO design pattern

Consider the following general program structure:
Class A has an instance of Class B as a member variable
Class B has a collection member variable containing instances of class C
Events in class A are propagated to the C instances by A simply telling B about the event
What are the design patterns concerning instances of class C talking back to class A?
One option is instances of class C posting notifications to which class A subscribes. Another option is passing a reference to class A "down the chain" (from A to B then from B to each C). This latter option allows instances of C to talk directly to A.
If you mean design patterns literally (i.e. of the GoF variety) then these would be a few relevant options:
Command: pass a callback to the C items (directly or indirectly through B) so that when they want to talk back to A they can simply invoke this callback -- which can even have parameters
Iterator: B exposes a view of its aggregate collection directly to A; communication between A and C is then made directly
Mediator: Exposes notifications to which A and C might subscribe to; communication is done by posting events
Observer: What you already suggested as the first option
If on the other hand you really mean architectural patterns, then typical options are:
Your first option, A subscribing to C events. At first sight this doesn't look like an all-around good idea unless the event is extremely useful all the time, because it requires n objects to aggregate a pointer back to the callback which in the worst case they could even use just once.
Passing references to A is another option, but not a good one if you are going to pollute the public interface of A with methods just so that C can call back to it in very specific scenarios. It can be very effective if A already exposes a suitable interface, but be aware that you might need an adapter class between C calling back to A in order to not tightly couple C to A's interface.
A third option would be A iterating over (a view of) the collection provided by B directly and supplying callbacks to C instances; this has the advantages of being quite loosely coupled and that it will use the least amount of memory, but it might be a bit trickier to code.

can overriding of a method be prevented by downcasting to a superclass?

I'm trying to understand whether the answer to the following question is the same in all major OOP languages; and if not, then how do those languages differ.
Suppose I have class A that defines methods act and jump; method act calls method jump. A's subclass B overrides method jump (i.e., the appropriate syntax is used to ensure that whenever jump is called, the implementation in class B is used).
I have object b of class B. I want it to behave exactly as if it was of class A. In other words, I want the jump to be performed using the implementation in A. What are my options in different languages?
For example, can I achieve this with some form of downcasting? Or perhaps by creating a proxy object that knows which methods to call?
I would want to avoid creating a brand new object of class A and carefully setting up the sharing of internal state between a and b because that's obviously not future-proof, and complicated. I would also want to avoid copying the state of b into a brand new object of class A because there might be a lot of data to copy.
UPDATE
I asked this question specifically about Python, but it seems this is impossible to achieve in Python and technically it can be done... kinda..
It appears that apart from technical feasibility, there's a strong argument against doing this from a design perspective. I'm asking about that in a separate question.
The comments reiterated: Prefer composition over inheritance.
Inheritance works well when your subclasses have well defined behavioural differences from their superclass, but you'll frequently hit a point where that model gets awkward or stops making sense. At that point, you need to reconsider your design.
Composition is usually the better solution. Delegating your object's varying behaviour to a different object (or objects) may reduce or eliminate your need for subclassing.
In your case, the behavioural differences between class A and class B could be encapsulated in the Strategy pattern. You could then change the behaviour of class A (and class B, if still required) at the instance level, simply by assigning a new strategy.
The Strategy pattern may require more code in the short run, but it's clean and maintainable. Method swizzling, monkey patching, and all those cool things that allow us to poke around in our specific language implementation are fun, but the potential for unexpected side effects is high and the code tends to be difficult to maintain.
What you are asking is completely unrelated/unsupported by OOP programming.
If you subclass an object A with class B and override its methods, when a concrete instance of B is created then all the overriden/new implementation of the base methods are associated with it (either we talk about Java or C++ with virtual tables etc).
You have instantiated object B.
Why would you expect that you could/would/should be able to call the method of the superclass if you have overriden that method?
You could call it explicitely of course e.g. by calling super inside the method, but you can not do it automatically, and casting will not help you do that either.
I can't imagine why you would want to do that.
If you need to use class A then use class A.
If you need to override its functionality then use its subclass B.
Most programming languages go to some trouble to support dynamic dispatch of virtual functions (the case of calling the overridden method jump in a subclass instead of the parent class's implementation) -- to the degree that working around it or avoiding it is difficult. In general, specialization/polymorphism is a desirable feature -- arguably a goal of OOP in the first place.
Take a look at the Wikipedia article on Virtual Functions, which gives a useful overview of the support for virtual functions in many programming languages. It will give you a place to start when considering a specific language, as well as the trade-offs to weigh when looking at a language where the programmer can control how dispatch behaves (see the section on C++, for example).
So loosely, the answer to your question is, "No, the behavior is not the same in all programming languages." Furthermore, there is no language independent solution. C++ may be your best bet if you need the behavior.
You can actually do this with Python (sort of), with some awful hacks. It requires that you implement something like the wrappers we were discussing in your first Python-specific question, but as a subclass of B. You then need to implement write-proxying as well (the wrapper object shouldn't contain any of the state normally associated with the class hierarchy, it should redirect all attribute access to the underlying instance of B.
But rather than redirecting method lookup to A and then calling the method with the wrapped instance, you'd call the method passing the wrapper object as self. This is legal because the wrapper class is a subclass of B, so the wrapper instance is an instance of the classes whose methods you're calling.
This would be very strange code, requiring you to dynamically generate classes using both IS-A and HAS-A relationships at the same time. It would probably also end up fairly fragile and have bizarre results in a lot of corner cases (you generally can't write 100% perfect wrapper classes in Python exactly because this sort of strange thing is possible).
I'm completely leaving aside weather this is a good idea or not.