answersLogoWhite

0

Why is object oriented system important with description?

Updated: 8/21/2019
User Avatar

Wiki User

8y ago

Best Answer

The easiest way to understand the importance of object oriented programming (OOP) is by example.

Suppose we want to create a new integral type that can store a 4-bit unsigned value. That is, we want to be able to store any decimal value in the range 0 through 15. Thus for a given type T, we want to see the following behaviours succeed:

T a = 12; // ok, 12 is within the valid range of T

T b = a; // ok, copy construct from the same type

int c = b; // ok, implicit conversion from T to int

T d = c; // ok, implicit conversion from int to T

However, we also want to see the following behaviours fail:

T e; // error: uninitialised

T f = 42; // error: 42 is outwith the range of T

T g = -b; // error: narrowing!

Without OOP, there is no way to catch these types of errors which means our code must constantly test the value of a T before using it. That's not impossible to achieve, of course, but it's a lot of extra work.

Our type T has an invariant (something that must hold true for all instances T). In this case, the value of a T must remain in the valid range at all times. Ideally we would like that invariant to be established at the point of instantiation but we also need to ensure that the invariant holds throughout the life-cycle of the instance. That is, we want to allow the value to be mutated, but in such a way that all invalid values are eliminated.

The first thing we need to consider is how we can physically represent a 4-bit unsigned integral. The smallest built-in datatype is a char, which is typically 8-bits long, so it makes sense to use a char for the representation. Thus we can define our type like so:

struct four_bit {

char data;

};

The problem with this is that the four_bit::data member is not encapsulated; there's nothing to prevent a user of a four_bit object from assigning invalid values:

four_bit x;

x.data = 42; // oops!

So the first thing we need to do is limit access to the representation using OOP:

class four_bit {

private:

char data;

};

Now the compiler can pick up the error:

four_bit x;

x.data = 42; // error: data is a private member!

We've now replaced one problem with another. Without access to the data member, how can we initialise it? OOP helps us here too. We simply need to define a public constructor:

class four_bit {

public:

four_bit (const char = 0);

// ...

};

four_bit::four_bit (const char c): data {0} {

if (c<0 c>15) throw std::range_error("four_bit range error");

data = c;

}

Note that we can (optionally) separate the implementation from the interface. The implementation can actually be placed in another file altogether (so long as that file includes the file containing the class definition). Users of our class need only see the interface (the class definition) because that alone provides all the information required to actually use the class.

This constructor throws an exception when the argument c is outwith the valid range. Often this is the best solution when dealing with an invariant however there are other possibilities depending upon the nature of the invariant. In this case we can't sensibly handle the error within the constructor itself, so we simply throw the exception back to the calling code. Note also that the argument defaults to zero. Not all classes have a natural default value, but for an otherwise integral type, 0 is acceptable.

The next thing we need to do is cater for assignment. For this we need to overload the assignment operator:

class four_bit {

public:

four_bit& operator= (const char);

// ...

};

four_bit& four_bit::operator= (const unsigned char c) {

if (c<0 c>15) throw std::range_error("four_bit range error");

data = c;

return *this;

}

Again, we throw an exception when the assignment contains an invalid argument. However, at this point we note that the assignment operator and the default constructor are almost identical. For a trivial class such as this it doesn't make a huge amount of difference, but code duplication is often a source of errors and it pays to keep duplication to a minimum. In this case we can simply invoke the assignment operator via the constructor:

four_bit::four_bit (const char c): data {0} {

this->operator= (c);

}

Note that although we've changed an implementation detail, any code that was already using our class is not broken by this change. So long as the class interface remains identical, users of our code will be completely unaware a change has actually taken place. This alone has enormous benefits because the scope of maintenance is isolated to the class itself. This means we can improve the class without adversely affecting the class consumers.

The final thing we need to do at this point is to provide some means of accessing the data. For this we might choose to use a simple conversion operator to return an unsigned char:

class four_bit {

public:

operator char() const {return data;}

// ...

};

Note that the implementation is declared inline. This is common when the implementation is a simple statement, which most accessors are. Note also that the return value is returned by value rather than by reference. This is fine because a char is a primitive data type which is trivial to copy. Had the member been a more complex type, returning by constant reference is often the best option, especially if the member defines a class invariant. We can also return by non-constant (mutable) reference, however we should only do so when the reference itself maintains its own invariant rather than defines one for our class.

With this operator, we can now perform implicit conversion:

four_bit x = 2;

char y = x;

We've now designed the basic interface to our 4-bit object. We can assign, mutate and access it, and the class itself encapsulates all the necessary error handling. There are still some things missing, however:

x = x * 2; // ok -- x is now 4

x *= 2; // error!

The reason the first operation works is because the expression x * 2 first performs an implicit conversion upon x which returns a temporary char with the value 2. Thus the expression is the equivalent to x = 2 * 2 or simply x = 4, both of which are catered for by the assignment operator. However, the second operator is as-yet undefined. We cannot convert x to a char because that conversion operator is (rightly) declared constant and that prevents us from assigning a value to x. So we must define the operator:

class four_bit {

public:

four_bit& operator*= (const char);

// ...

};

four_bit& four_bit::operator*= (const char c) {

return this->operator = (data * c);

}

Note that we define this operator in terms of the assignment operator because that's where we defined our error-handler. With this in place, the expression x *= 2 can now be evaluated. Once we add all the other compound arithmetic/assignment operators (+=, -=, /=, %=), our four_bit class will begin to behave much more like an integral type.

The class is trivial to write, but because all the behaviour we expect of our new type is encapsulated by its class, we can use the class just like we can any other integral type. The only real difference is that when we attempt to assign an invalid value, the class will throw an exception, thus alerting us to an error in our calling code. This greatly simplifies the calling code because we no longer have to check for errors at every possible call point; only those that are actually throwing exceptions need to be examined and we'll often find we've made a simple logic error which can be easily dealt with without introducing what would otherwise be redundant error-handling. Thus our code is smaller, more efficient and much easier to maintain.

User Avatar

Wiki User

8y ago
This answer is:
User Avatar

Add your answer:

Earn +20 pts
Q: Why is object oriented system important with description?
Write your answer...
Submit
Still have questions?
magnify glass
imp
Related questions

What object oriented system development?

What is object-oriented systems development


What is Object Oriented System Development?

What is object-oriented systems development


What is full form of oop's?

Object Oriented Programming


How the implementation and design of object oriented database system is differen from non object oriented database system?

DBMS Deesign implementation


What has the author David A Taylor written?

David A. Taylor has written: 'Object-oriented technology' -- subject(s): Database design, Object-oriented databases, Development, Computer software 'Object-oriented information systems' -- subject(s): Management information systems, Object-oriented databases, System design


OOPs stands for Object Oriented Programming then whats that extra s stands for?

As per the website, www.acronymfinder.com, OOPS stands for Object-Oriented Programming and Systems. Regards, Anthony anthonymail@rediffmail.com


List the advantage and disadvantage of database management system?

Answering "List the advantage and disadvantage of object oriented database model?" Answering "List the advantage and disadvantage of object oriented database model?"


How can object oriented programming help maintain complex computer system?

object oriented programming more closely models the real world in some aspects, this means that it -should- be more easily understandable for us


Why you use unified modeling languages?

to create visual models of object-oriented software intensive system


Is windows XP a procedural language or object oriented?

Windows XP is an operating system, not a programming language.


Where can one find tips on object oriented design?

Object-oriented design is a way of programming software by planning a system of interacting objects. There are many discussion groups and forums on the internet where programmers exchange tips and experiences.


What are risks of object oriented development?

There are no risks, as such. The point of object-oriented programming is to reduce the risks of invalidating data unintentionally. With a well-designed class system, there should be no risk whatsoever. With a badly-designed class system, the risks are as a great as those with structured or procedural programming.