One of the most important aspects of OOP is data hiding. Can somebody explain using a simple piece of code what data hiding is exactly and why we need it?
I'm guessing by data hiding you mean something like encapsulation or having a variable within an object and only exposing it by get and modify methods, usually when you want to enforce some logic to do with setting a value?
public class Customer
{
private decimal _accountBalance;
public decimal GetBalance()
{
return _accountBalance;
}
public void AddCharge(decimal charge)
{
_accountBalance += charge;
if (_accountBalance < 0)
{
throw new ArgumentException(
"The charge cannot put the customer in credit");
}
}
}
I.e. in this example, I'm allowing the consuming class to get the balance of the Customer
, but I'm not allowing them to set it directly. However I've exposed a method that allows me to modify the _accountBalance
within the class instance by adding to it via a charge in an AddCharge
method.
Here's an article you may find useful.
Data or Information Hiding is a design principal proposed by David Paranas.
It says that you should hide the design decisions in one part of the program that are likely to be changed from other parts of the program, there by protecting the other parts from being affected by the changes in the first part.
Encapsulation is programming language feature which enables data hiding. However note that you can do data\information hiding even without encapsulation. For example using modules or functions in non Object Oriented programming languages. Thus encapsulation is not data hiding but only a means of achieving it.
While doing encapsulation if you ignore the underlying principal then you will not have a good design. For example consider this class -
public class ActionHistory
{
private string[] _actionHistory;
public string[] HistoryItems
{
get{return _actionHistory; }
set{ _actionHistory = value; }
}
}
This calls encapsulates an array. But it does not hide the design decision of using a string[] as an internal storage. If we want to change the internal storage later on it will affect the code using this class as well.
Better design would be -
public class ActionHistory
{
private string[] _actionHistory;
public IEnumerable<string> HistoryItems
{
get{return _actionHistory; }
}
}
Data Hiding is defined as hiding a base class method in a derived class by naming the new class method the same name as the base class method.
class Person
{
public string AnswerGreeting()
{
return "Hi, I'm doing well. And you?";
}
}
class Employee : Person
{
new public string AnswerGreeting()
{
"Hi, and welcome to our resort.";
}
}
In this c# code, the new keyword prevents the compiler from giving a warning that the base class implementation of AnswerGreeting is being hidden by the implementation of a method with the same name in the derived class. Also known as "data hiding by inheritance".
Information hiding (or more accurately encapsulation) is the practice of restricting direct access to your information on a class. We use getters/setters or more advanced constructs in C# called properties.
This lets us govern how the data is accessed, so we can sanitize inputs and format outputs later if it's required.
The idea is on any public interface, we cannot trust the calling body to do the right thing, so if you make sure it can ONLY do the right thing, you'll have less problems.
Example:
public class InformationHiding
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
/// This example ensures you can't have a negative age
/// as this would probably mess up logic somewhere in
/// this class.
private int _age;
public int Age
{
get { return _age; }
set { if (value < 0) { _age = 0; } else { _age = value; } }
}
}
By data hiding you are presumably referring to encapsulation. Encapsulation is defined by wikipedia as follows:
Encapsulation conceals the functional details of a class from objects that send messages to it.
To explain a bit further, when you design a class you can design public and private members. The class exposes its public members to other code in the program, but only the code written in the class can access the private members.
In this way a class exposes a public interface but can hide the implementation of that interface, which can include hiding how the data that the class holds is implemented.
Here is an example of a simple mathematical angle class that exposes values for both degrees and radians, but the actual storage format of the data is hidden and can be changed in the future without breaking the rest of the program.
public class Angle
{
private double _angleInDegrees;
public double Degrees
{
get
{
return _angleInDegrees;
}
set
{
_angleInDegrees = value;
}
}
public double Radians
{
get
{
return _angleInDegrees * PI / 180;
}
set
{
_angleInDegrees = value * 180 / PI;
}
}
}
Imagine that the users of your class are trying to come up with ways to make your class no longer fulfill its contract. For instance, your Banking object may have a contract that ensures that all Transactions are recorded in a log. Suppose mutation of the Bank's TransactionLog were publically accessible; now a consuming class could initiate suspect transactions and modify the log to remove the records.
This is an extreme example, but the basic principles remain the same. It's up to the class author to maintain the contractual obligations of the class and this means you either need to have weak contractual obligations (reducing the usefulness of your class) or you need to be very careful about how your state can be mutated.