CMSC 202 Classes and Objects Encapsulation Version 909
CMSC 202 Classes and Objects: Encapsulation Version 9/09
Types of Programmers • Class creators – those developing new classes – want to build classes that expose the minimum interface necessary for the client program and hide everything else • Client programmers – those who use the classes (a term coined by Scott Meyer) – want to create applications by using a collection of interacting classes Version 9/09 2
OOP Techniques • Class creators achieve their goal through encapsulation. Encapsulation: • Combines data and operations into a single entity (a class) • Provides proper access control • Focuses on implementation • Achieved through information hiding (abstraction) Version 9/09 3
The Value of Encapsulation • Client programmers do not need to know how the class is implemented, only how to use it. • The information the client programmer needs to use the class is kept to a minimum. • Class implementation may be changed with no impact on those who use the class. Version 9/09 4
Access Control • Encapsulation is implemented using access control. – Separates interface from implementation – Provides a boundary for the client programmer • Visible parts of the class (the interface) – can be used and/or changed by the client programmer. • Hidden parts of the class (the implementation) – Can be changed by the class creator without impacting any of the client programmer’s code – Can’t be corrupted by the client programmer Version 9/09 5
Access Control in Java • Visibility modifiers provide access control to instance variables and methods. – public visibility - accessible by everyone, in particular the client programmer • A class’ interface is defined by its public methods. – private visibility - accessible only by the methods within the class – Others - later Version 9/09 6
Date 2 Class In this new date class, the instance variables have been labeled private. public class Date 2 { private String month; private int day; private int year; public void to. String( ) { return month + “ “ + day + “ “ + year; } Any Date 2 class method may use the class’ private instance variables. // set. Date and month. String same as Date 1 class }Version 9/09 7
Access Control Example Date 1 class - public instance variables were used Date 2 class - private instance variables are now used public class Date 2 Demo { public static void main( String[ ] args ) { Date 2 my. Date = new Date 2( ); my. Date. month = “July”; my. Date. day = 4; my. Date. year = 1950; // compiler error my. Date. set. Date( 7, 4, 1950 ); // OK – why? System. out. println( my. Date. to. String( )); } } Version 9/09 8
Private Instance Variables • Private instance variables are only usable within the class. • Private instance variables hide implementation details, promoting encapsulation. • Private instance variables are not accessible by the client programmer (class user). • Good programming practice: – Label all instance variables as private. – The class has complete control over how/when/if the instance variables are changed. – Instance variables primarily support class behavior. Version 9/09 9
Encapsulation Summary • Combine methods and data in a single class. • Use private instance variables for information hiding. • Minimize the class’ public interface. “Keep it secret, keep it safe. ” Version 9/09 10
Accessors & Mutator • Class behavior may allow access to, or modification of, individual private instance variables. • Accessor method – retrieves the value of a private instance variable – conventional to start the method name with get • Mutator method – changes the value of a private instance variable – conventional to start the name of the method with set • Gives the client program indirect access to the instance variables. Version 9/09 11
More Accessors and Mutators Question: Doesn’t the use of accessors and mutators defeat the purpose of making the instance variables private? Answer: No • The class implementer decides which instance variables will have accessors. • Mutators can: – validate the new value of the instance variable, and – decide whether or not to actually make the requested change. Version 9/09 12
Date 2 Accessor and Mutator public class Date 2 { private String month; private int day; // 1 - 31 private int year; // 4 -digit year // accessors return the value of private data public int get. Day ( ) { return day; } // mutators can validate the new value public boolean set. Year( int new. Year ) { if ( 1000 <= new. Year && new. Year <= 9999 ) { year = new. Year; return true; } else // this is an invalid year return false; // rest of class definition follows } Version 9/09 13
Accessor/Mutator Caution • In general you should NOT provide accessors and mutators for all private instance variables. – Recall that the principle of encapsulation is best served with a limited class interface. • Too many accessors and mutators lead to writing procedural code rather than OOP code. More on this later. Version 9/09 14
Private Methods • Methods may be private. – Cannot be invoked by a client program – Can only be called by other methods within the same class definition – Most commonly used as “helper” methods to support top-down implementation of a public method Version 9/09 15
Private Method Example public class Date 2 { private String month; private int day; // 1 - 31 private int year; // 4 -digit year // mutators should validate the new value public boolean set. Year( int new. Year ) { if ( year. Is. Valid( new. Year ) ) { year = new. Year; return true; } else // year is invalid return false; } // helper method - internal use only private boolean year. Is. Valid( int year ) { return 1000 <= year && year <= 9999; } } Version 9/09 16
More About Methods • Different classes can define a method with the same name. • Java can determine which method to call based on the type of the calling object. • Example: Date 2 birthday = new Date 2( ); Dog fido = new Dog( ); System. out. println(birthday. to. String( )); System. out. println(fido. to. String( )); – birthday. to. String( ) will call the to. String( ) method defined in the Date 2 class because birthday’s type is Date 2. – fido. to. String( ) will call the to. String( ) method defined in the Dog class because fido’s type is Dog. Version 9/09 17
Method Overloading • Two or more methods in the same class may also have the same name. • This technique is known as method overloading. Version 9/09 18
Overloaded set. Date • The Date 2 class set. Date method: public boolean set. Date( int month, int day, int year ) • Suppose we wanted to change only the day and year? – Define another method named set. Date: public boolean set. Date( int day, int year ) (After all, set. Date is a good descriptive name for what this method does. ) Version 9/09 19
Date 3 Class - Overloaded set. Date Method public class Date 3 { private String month; private int day; private int year; // 1 - 31 // 4 digits public boolean set. Date( int new. Month, int new. Day, int new. Year ) { // code here } public boolean set. Date( int new. Day, int new. Year ); { // code here, doesn’t change month } // to. String( ), month. String( ), set. Year( ), etc. follow } Version 9/09 20
Date 3 Demo Class public class Date 3 Demo { public static void main (String[ ] args) { Date 3 my. Date = new Date 3( ); my. Date. set. Date( 1, 23, 1982 ); System. out. println( my. Date. to. String( ) ); my. Date. set. Date( 4, 1999 ); System. out. println( my. Date. to. String( ) ); } } How does Java know which set. Date method to call? Version 9/09 21
Method Signature • A method is uniquely identified by – its name and – its parameter list (parameter types and their order). • This is known as its signature. Examples: public boolean Version 9/09 set. Date(int new. Month, int new. Day, int new. Year) set. Date(String new. Month, int new. Day, int new. Year) set. Date(int new. Day, String new. Month) 22
Return Type is Not Enough • Suppose we attempt to overload Date 3’s set. Day() method by using different return types. public void set. Day( int day ) { /* code here */ } public boolean set. Day( int day ) { /* code here */ } • This is NOT valid method overloading because the code that calls set. Day( ) can ignore the return value. birthday. set. Day( 22 ); • The compiler can’t tell which set. Day( ) method to call. • Just because a method returns a value doesn’t mean the caller has to use it. Version 9/09 23
Too Much of a Good Thing Automatic type promotion and overloading can sometimes interact in ways that confuse the compiler. Example: public class X { //version 1 public void print. Average ( int a, double b) {/*code*/} //version 2 public void print. Average ( double a, int b) {/*code*/} } And then consider this: X my. X = new X( ); my. X. print. Average( 5, 7 ); The Java compiler can’t decide whether to • promote 7 to 7. 0 and call the first version of print. Average, or • promote 5 to 5. 0 and call the second. Version 9/09 24
- Slides: 24