Why is inheritance So important, when you can Just create different classes and use them separately - oop

I have been learning about Object-Oriented Programming. I am currently learning about inheritance but don't know where to apply it and use it. I really want to know about it because I strictly focus on the Application of different functionalities and how to use them.

Inheritance is incredibly useful for encapsulation. It promotes the reusability of code without rewriting the code and it is even helpful in decreasing the time complexity of the program which can be really advantageous in competitive coding.

Inheritance is mostly used to share functionality between kindred classes - that's even why the word for it is inheritance. Your child class inherits methods and fields of the parent class and therefore has access to the same functionality as the parent class.
The primary use case is to avoid code duplication or to make the design of complex objects a bit easier - but this is already well covered and doesn't need another elaboration.
But in the end, software architecture and design is always something which is subject to opinions - there may be best practices which really make sense to adhere to but on the other hand: You don't always have the time to design and code clean software.

Related

Design Issues with Inheritance Implementation

Initial Situation:- I had 20 different classes, one each containing code to provide feed to each downstream system, so 20 classes for 20 systems. No I hire a architect to simplify my code.
Architect suggested applying OOP principles that we should use inheritance and move common functionality to base class and use is a relationship with 20 classes.
Problem:- This increased my testability efforts, earlier we had separate code for each downstream so need to regress with one system only but now for any change in base class, we need to test with 20 systems, so applying OOP's created more problems.
What should be the design to solve this problem?
In short, you can try to use composition instead of inheritance. This might result in a more stable downstream-specific object which then doesn't need to be tested when common things change. Depending on your exact case this may or may not help, but is a sensible alternative at least.
Obviously we don't know your exact circumstances. In general inheritance is really problematic and should be avoided if possible.
A bit more specifically, inheriting from a baseclass to share code (I'm assuming this is your case, I don't know for sure) is also not a good practice. So strike two for inheritance.
Composition involves creating a useful abstraction for the common things. Basically a standalone object or objects that do something useful, but not downstream specific. Then using those objects in the downstream-specific objects, instead of inheriting any of it.

Deriving from a concrete class?

In book 'Head First Design Patterns', one of the way mentioned to not violate 'Dependency Inversion' principle is as:
No class derive from a concrete class.
Is it possible to follow this rule thoroughly? In many commonly used frameworks and libraries its common to find classes not following this rule.
Inheritance is an important part of c#, ruling it out would be a waste.
Nevertheless, the book emphasizes the open for extension closed for change SOLID principle and this is actually a good thing.
Not to derive from concrete classes ( note, abstract classes and interfaces are not concrete ), helps you to adapt this paradigm. Inheritance is not typically suited for extension, and makes inversion harder ( because the latter relies on interfaces and concretes are not interfaces ).
So in practice, you'll see that base classes are often abstract. Not all, and not every framework adopts it. Sometimes there are good reasons to inherit from a concrete. But the book, is in it's way a easy read and to go into details on the exceptions would make it much harder to read.
So bottom line: no, one should not follow the rule at all cost but only do concrete inheritance if one of the following:
you know what you are doing (so you have a really really really good reason)
you know it doesn't matter ( because it's a simple project/object)
you know the concretes will be contained to the project itself (internals)
As problems in programming are very different, it's hard to tell. Sometimes you it's usefull to do it, sometimes it's not.
It's also possible to redesign the situations that you think you can't to actually achieve this. But in the new design you may end up with more classes that you don't really need and are only used to achieve this.
The question in this case is: Is having more stuff just to achieve some principle without having problems in your code a good design?
In my experience it is better to try and avoid inheriting from concrete classes. Try to design you code so that you don't inherit from concrete classes. This will make your code better to read and understand as it guides you to designing your abstractions better. But sometimes it's usefull to do just that.
As you mentioned frameworks do that. Especially GUI frameworks. You see a lot inheritance from concrete classes there. That's because it's usefull to add additional behavior to already existing controls.
For example a Button is fine on it's own, but sometimes you may need to add an additional behavior for your needs. Inheriting from Button and just adding the new things you need is just fine. Can you do it another way? Sure, but is it worth adding addtional classes and/or interfaces or coping code from Button just to avoid inheriting from a concrete class? Is is so bad? Where can it hust?
You do achieve extensibility this way, as the framework will still work just fine.
GUI frameworks also use composition a-lot too, so what you get is a combination of composition with inheritance from both concrete and abstract classes. Just use the right one where you need it.
Not all problems are like that with a hierarchical structure with a a-lot of related objects. Sometimes inheritance can hurt extensibility and using composition is a better choise.

Could override be deprecated?

There is a Design Principle that says Favor composition over inheritance and its advertised benefit is that it simplifies design. Let's agree on that as background for this question.
So, could override be deprecated? Could we, in theory, get rid of it for good?
Let's be a bit over zealous on the above mentioned Design Principle and take it to the extreme: composition all the way. One reason should be enough for now, override abuse.
One question arises: are we, programmers, going to loose something? Is any power lost trying to prevent some possible abuse?
So, what applications are there for override and can they be achieved otherwise? Should they?
Not only is this a completely radical and impractical proposal, it's not a particularly compelling one. Just because a feature gets abused doesn't mean that it should be removed entirely. People have been abusing all sorts of things for a very long time, but that hardly implies that they don't serve a useful purpose when used correctly.
Design patterns are one thing; designing an intentionally limited language to conform with your ideal notion of a good design pattern is quite another. To my mind, it's an exercise in futility. Programmers will still find something to abuse.
And I take issue with the central assumption that any use of override is inappropriate or abusive. There are lots of cases where you want to take advantage of inheritance implying an is-a relationship. Sure, this model doesn't fit the real world 100% of the time, but there are plenty of times that it does.
The Animal and Shape class examples that you read about in textbooks might be a bit contrived, but I frequently use inheritance in real-world applications.
That's not to imply that I disagree with the sentiment that one should generally or when in doubt, favor composition over inheritance. But that's not saying that inheritance is bad and should never be used.
If you remove inheritance altogether you remove a significant feature of OOP design.
Using inheritance allows you to use a "is a" design, which has a strong meaning in OOP design, and of course saves code redundancy.
If you'd use only encapsulation you'd have to either expose the members (which isn't always what you want (raises design complexity because of the amount of stuff the programmer needs to know about).
Or, make wrapper methods that will call the member's methods (which is redundant).
Besides that, lets assume you know the difference between overriding and hiding, you can see that most OOP languages will choose to use strictly overriding when given the choice.
This is because overriding is usually more intuitive than hiding.
So, if you remove overriding, and still allow inheritance, you are left with hiding. That usually leads to many runtime errors and un-expected results with type conflicts.
Farther more you won't be able to have things like an array or list of base class pointers that point a lot of different derived classes. Because if you don't have overrides it won't be able to call the specified derived class method, it will only call the same base class method for all of them.
I've added a response on behalf of astander extracting from his link (hope you don't mind)
For example, one advantage with inheritance is that it is easier to
use than composition. However, that ease of use comes at the cost that
it is harder to reuse because the subclass is tied to the parent
class.
One advantage of composition is that it is more flexible because
behavior can be swapped at runtime. One disadvantage of composition is
that the behavior of the system may be harder to understand just by
looking at the source. These are all factors one should think about
when applying composition over inheritance.
I'm always using polymorphism. I always seem to have a bunch of objects with some common concept behind them and a lot of code that is interested in that concept--that is, they care about Animals, not Lions and Tigers and Bears or even Carnivores. Interfaces often work better for this than superclasses, so I suppose I could get by without subclassing. (Are interfaces okay when subclassing is not?) However, I have often found that a lot of classes using an interface have identical code for the interface methods. Changing the interface to a superclass can let me get rid of a lot of duplicate code. The other situation I find myself in is where a large, complex class does what I need except for one teeny, tiny little thing. With subclassing, I can create a new class that does exactly what I need in just a few lines.
There may be a language component to this debate. When I'm writing in Java I subclass at a furious rate. When I'm writing in C# I think long and hard before overriding anything or even using interfaces. I'm not sure why and it may have more to do with the type of work I do in those languages than the languages themselves. But working in C#, I am quite sympathetic to this idea, while when working in Java...well, I'd have to toss almost all my Java code if I couldn't override.

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.

Design classes - OOPS features

I am interested in improving my designing capability (designing of classes with its properties, methods etc) for a given.
i.e. How to decide what should be the classes, methods and properties?
Can you guys suggest me good material for improving on this?
Please see:
Any source of good object-oriented design practises?
Best Resources to learn OO Design and Analysis
among many....
Encapsulation: The wrapping up of data and functions into a single unit is known as encapsulation. Or, simply put: putting the data and methods together in a single unit may be a class.
Inheritance: Aquiring the properties from parent class to child class. Or: getting the properties from super class to sub class is known as inheritance.
Polymorphism: The ability to take more that one form, it supports method overloading and method overriding.
Method overloading: When a method in a class having the same method name with different arguments (diff parameters or signatures) is said to be method overloading. This is compile-time polymorphism – using one identifier to refer to multiple items in the same scope.
This is perhaps a question which every programmer thinks of one day.
The designing capability comes with your experience gradually. What I would say is in general scenario if you can visualize the Database objects for a given problem, the rest is a cakewalk (isnt true sometimes if you work on a techie project with no DB)
You can start thinking of objects which are interacting in the real world to complete the process and then map them to classes with appropriate properties and then methods for defining their behavior. Ten you can focus on the classes which contribute to running the workflow and not to any individual real world object.
This gets a lot simplified if we focus on designing the DB before we jump directly to code design.
A lot depends on the pattern you choose - If you see a problem from MVC perspective, you will naturally be drawn towards identifying "controller" classe first and so on.
I guess I need not repeat the golden sources of design and OOPS wisdom - they already posted here or there.
I would recommend you to read up on some UML and design patterns. That gets you going with the thinking in "drawing" terms. You can also get a good grasp of a big class/object a lot easier.
One particular book that is good in this area.
Applying UML and Patterns
Give a look a Domain-Driven Design, which defines entities, value objects, factories, services and repositories and the GRASP patterns (General Responsibility Assignment Software Patterns) e.g. Expert, Creator, Controller.
Have a look at the part 1 screencast the first part is not silverlight but just a command line calculator that starts out as a single bit of code, and is then broken down into classes.