As with any methodology used in programming, the object oriented concept is intended to provide a way of writing large and complex programs in a way that allows them to be easily built and maintained. The concept involves breaking the program up into smaller pieces each of which can be dealt with independently of all the other pieces of the program so that the section of the program being worked on can be handled without needing to constantly consider what any other part of the program is doing.
With object oriented programming we achieve this objective by creating the program as an aggregation of classes. Each class defines the attributes and possible states which the objects of that type will all have along with all of the pieces of processing logic that those objects will need to be able to handle in order to change the states of their attributes. Each class defines the common structure and behaviour that is shared by those objects that are instances of that class.
By defining the classes in an aggregation we can greatly simplify the code needed for the higher level classes by using the lower level classes to provide the structure and behaviour instead of having to include all of the processing at the same level. This allows us to keep each class to just a few hundred lines of code that can be handled almost completely independently of all of the rest of the code in our program. Only the public interface to each of the classes that the particular class uses need to be known in detail. The behaviour that is provided via calls to those interfaces only needs to be known at a high level with the exact way in which the behaviour is provided being left to that class.
In order to provide the necessary level of abstraction we need to effectively hide all of the information within each class apart from the interface. Different languages can provide different mechanisms for doing this but a common way used by a number of object oriented languages is to only make those behaviours (methods) defined as public visible from outside of the class itself. Doing this means that when dealing with a given class you need only know the public interfaces to the classes this one uses in order to work with the code in this class, you do not need to know how any of those classes do what they do unless you re working on those classes. As an example, if the class you are working on is 'car' then one of the classes that this class will use is 'engine' but we don't need to know how 'engine' works in order to be able to work with 'car', we just need to know the interfaces that 'engine' provides for 'car' to interact with it.
With object oriented programming we can also use inheritance to share common functionality between classes. This provides a different way in which the classes in our program form a hierarchy. We can define a class that provides all of the common functionality that several different classes will share and then define each of these classes so that they inherit the functionality provided by the common class. When we do this we will need to see the shared portion of the common class when we are working on any of the classes that share that functionality but we can still hide the actual functioning of the shared part so that we can deal with that independently. In many languages the interfaces for the interfaces that the common class shares with classes that inherit from it are defined as protected. This way of structuring classes also allows for polymorphism where the exact behaviour that is provided will depend on the specific class that a given object belongs to but where at the higher level we can use the same code. If we have a number of different types of 'car' then each will have a 'drive' behaviour but the implementation of that behaviour will differ depending on the type of 'car'.
By applying object oriented techniques to the design of our program we can treat the code as a number of almost completely separate classes. When dealing with a given class we need only deal with the code in that actual class, the public interfaces to any classes that it uses and the protected interface to any classes it inherits from. We can disregard all of the other code in the program and simply rely on each interface providing the expected/required behaviour. Even if those interfaces don't provide the expected behaviour that doesn't impact on how you work with the code in this class (you'd need to work on the class that isn't behaving correctly to fix the behaviour provided by its interface). This means that with a properly written object oriented program no matter whether the program consists of a few thousand lines of code or tens of millions of lines of code that you are only ever dealing with a few hundred lines of code at most at any one time and while working on those few hundred lines of code you can ignore the rest of the program completely. This also makes testing much easier as each class can be tested separately. The only requirement is that any classes used by a given class need to have been tested first so that you can test the current class knowing that the behaviour expected from the classes it uses will be correct.
It is quite possible to write code that meets the definition of object oriented but which doesn't actually achieve the purpose for which OO was created but then you will have code that doesn't achieve all of the benefits that OO was intended to provide.
This article written by Stephen Chapman, Felgall Pty Ltd.