I understand the concept of an object, and as a Java programmer I feel the OO paradigm comes rather naturally to me in practice.
However recently I found myself thinking:
Wait a second, what are actually the practical benefits of using an object over using a static class (with proper encapsulation and OO practices)?
I could think of two benefits of using an object (both are significant and powerful):
Polymorphism: allows you to swap functionality dynamically and flexibly during runtime. Also allows to add new functionality 'parts' and alternatives to the system easily. For example if there's a
Car
class designed to work withEngine
objects, and you want to add a new Engine to the system that the Car can use, you can create a newEngine
subclass and simply pass an object of this class into theCar
object, without having to change anything aboutCar
. And you can decide to do so during runtime.Being able to 'pass functionality around': you can pass an object around the system dynamically.
But are there any more advantages to objects over static classes?
Often when I add new 'parts' to a system, I do so by creating a new class and instantiating objects from it.
But recently when I stopped and thought about it, I realized that a static class would do just the same as an object, in a lot of the places where I normally use an object.
For example, I'm working on adding a save/load-file mechanism to my app.
With an object, the calling line of code will look like this: Thing thing = fileLoader.load(file);
With a static class, it would look like this: Thing thing = FileLoader.load(file);
What's the difference?
Fairly often I just can't think of a reason to instantiate an object when a plain-old static-class would act just the same. But in OO systems, static classes are fairly rare. So I must be missing something.
Are there any more advantages to objects other from the two that I listed? Please explain.
EDIT: To clarify. I do find objects very useful when swapping functionality, or passing data around. For example I wrote an app that makes up melodies. MelodyGenerator
had several subclasses that create melodies differently, and objects of these classes were interchangable (Strategy pattern).
The melodies were objects too, since it's useful to pass them around. So were the Chords and Scales.
But what about 'static' parts of the system - that aren't going to be passed around? For example - a 'save file' mechanism. Why should I implement it in an object, and not a static class?
Thing
? – Jun 03 '14 at 21:28FileLoader
for one that reads from a socket? Or a mock for testing? Or one that opens a zip file? – Benjamin Hodgson Jun 03 '14 at 21:28System.Math
in .NET is an example of something that makes a lot more sense as a static class: you're never going to need to swap it out or mock it and none of the operations could logically be made part of an instance. I really don't think your 'saving' example fits that bill. – Benjamin Hodgson Jun 04 '14 at 06:42Engine
was designed for inheritance up front. Doing this puts you in a situation where updatingEngine
in ways that are correct (i.e. it still behaves as it should) can break subclasses. And even if you anticipated thatEngine
would need extending, the correct answer is still to use composition more often than not. – Doval Jun 04 '14 at 11:57Engine
was designed for inheritance up front, or if it wasn't and I want to apply the Strategy pattern on it in Car, than I wouldn't subclass it. I would create an abstract super class for itAbstractEngine
, which is designed for inheritance, and change the reference inCar
to this superclass. And possibly change the name ofEngine
toSimpleEngine
or something. Then the new engine would be too a subclass ofAbstractEngine
, not a subclass ofSimpleEngine
. Is this what you mean? – Aviv Cohn Jun 04 '14 at 12:54Engine
subclasses implement parts of their behavior differently, these differences in behavior should be instance fields ofEngine
. E.g. fieldsTube TubeThing
andScrew SomeScrew
.Tube
andScrew
are either abstract superclasses or interfaces, extended/implemented by different classes. Different combinations of objects of these classes are composed inside anEngine
object to create different behaviors, instead of heaving a number ofEngine
subclasses. The engine is than composed with a car. Correct? – Aviv Cohn Jun 04 '14 at 13:07Tube
andScrew
subclasses either. See Prefer composition over inheritance? and Why should I prefer composition over inheritance for more discussion. – Doval Jun 04 '14 at 13:13Tube
interface soTune someTune
can reference to them. How is this 'without interfaces'? – Aviv Cohn Jun 04 '14 at 13:24