|
|
Suppose we made the data fields in the Card class public:
public class Card
{
public String suit; // "Spades", "Hearts", "Diamonds", "Clubs"
public String rank;
Card(...) // Constructor to create a Card< object
{
...
}
}
|
This will allow a program (myProg) to use the data fields directly:
public class Card
{
public String suit; // "Spades", "Hearts", "Diamonds", "Clubs"
public String rank;
Card(...) // Constructor to create a Card< object
{
...
}
}
|
Then changing the implementation of the Card class will cause errors in the user program:
public class Card
{
public int suit; // 0="Spades", 1="Hearts", 2="Diamonds", 3="Clubs"
public String rank;
Card(...) // Constructor to create a Card< object
{
...
}
}
|
Data field encapsulation requires that all data fields are defined as private:
public class Card
{
private String suit; // "Spades", "Hearts", "Diamonds", "Clubs"
private String rank;
Card(...) // Constructor to create a Card< object
{
...
}
public String getSuit()
{
return suit;
}
public void setSuit(String newSuit)
{
suit = newSuit;
}
}
|
$64,000 question: how can other classes use/access the data fields ?
When other classes needs to read some data field, we must provide a (public) accessor method:
public class Card
{
private String suit; // "Spades", "Hearts", "Diamonds", "Clubs"
private String rank;
Card(...) // Constructor to create a Card< object
{
...
}
public String getSuit() // Accessor or "getter" method
{
return suit;
}
public void setSuit(String newSuit)
{
suit = newSuit;
}
}
|
When other classes needs to write a data field, we must provide a (public) mutator method:
public class Card
{
private String suit; // "Spades", "Hearts", "Diamonds", "Clubs"
private String rank;
Card(...) // Constructor to create a Card< object
{
...
}
public String getSuit() // Accessor or "getter" method
{
return suit;
}
public void setSuit(String newSuit) // Mutator or "setter" method
{
suit = newSuit;
}
}
|
How will this help ???
Suppose we made the data fields in the Card class private:
public class Card
{
private String suit; // "Spades", "Hearts", "Diamonds", "Clubs"
private String rank;
Card(...) { ... } // Constructor to create a Card< object
public String getSuit() // Accessor method
{
return suit;
}
}
|
Then: other classes must use an accessor/mutator method to access a data field:
public class Card
{
private String suit; // "Spades", "Hearts", "Diamonds", "Clubs"
private String rank;
Card(...) { ... } // Constructor to create a Card< object
public String getSuit() // Accessor method
{
return suit;
}
}
|
Suppose we want to change the implementaion of the Card object:
public class Card
{
private int suit; // 0="Spades", 1="Hearts", 2="Diamonds", 3="Clubs"
private String rank;
Card(...) { ... } // Constructor to create a Card< object
public String getSuit() // Accessor method
{
return suit;
}
}
|
We can maintain compatibility by updating the accessor/mutator methods:
public class Card
{
private int suit; // 0="Spades", 1="Hearts", 2="Diamonds", 3="Clubs"
private String rank;
Card(...) { ... } // Constructor to create a Card< object
public String getSuit() // Adjust accessor method
{ String[] suitToString = {"Spades", "Hearts", "Diamonds", "Clubs"};
return suitToString[suit]; // Translates suit number to string !
}
}
|
Result: other classes that use the Card class will still work correctly:
public class Card
{
private int suit; // 0="Spades", 1="Hearts", 2="Diamonds", 3="Clubs"
private String rank;
Card(...) { ... } // Constructor to create a Card< object
public String getSuit() // Adjust accessor method
{ String[] suitToString = {"Spades", "Hearts", "Diamonds", "Clubs"};
return suitToString[suit]; // Translates suit number to string !
}
}
|
DEMO: demo/10-classes/19-encapsulation/repr-1 + repr-2/Demo.java + Card.java
|