sun certified java programmer, ©2004 gary lance, chapter 5, page 1 sun certified java 1.4...
TRANSCRIPT
Sun Certified Java 1.4 ProgrammerChapter 5 Notes
Gary Lance
[email protected]://home.comcast.net/~glance44/microhard/java2.html
Encapsulation
• You need to control the way in which variables are handled. Users can set variables to invalid values otherwise.
– make instance variables private or protected
– create public mutators to alter the instance variables.
• Put code in here for validation of data
– create public accessors to retrieve the variables
Java is Statically Typed
In a statically-typed language, such as Java and C++, a type is attached to a variable at compile time. Most often this occurs through the use of declaration statements:int a;double m;Person person;
Principle of Substitution
• This involves the relationship of a data type associated with a parent class to a data type associated with a child class in a statically-typed object-oriented language:
1. Instances of the child class must possess all data members associated with the parent class.
2. Instances of the child class must implement, through inheritance at least (if not explicitly overridden), all functionality defined for the parent class. New functionality can also be defined.
3. An instance of a child class can mimic the behavior of the parent class and should be indistinguishable from an instance of the parent class if substituted in a similar situation
Principle of Substitution
• If we have two classes A and B, such that class B is a subclass of class A:
• (in Java: class A extends B)
• it should be possible to substitute instances of class B for instances of class A in any situtation with no observable effect.
Principle of Substitution
All object-oriented languages will support the principle of substitution, although some will require additional syntax when a method is overridden. Most support the concept in a very straightforward fashion: the parent class simple holds a value from the child class. The one major exception to this is the language C++. In C++, only pointers and references truly support substitution; variables that are simpley declared as value (and not as pointers) do not support substitution.
Static and Dynamic Classes
The static class of a variable is the class that was used in the declaration of the variable. The static class (as the name suggests) is fixed at compile time and does not ever change. The dynamic class of a variable is the class associated with the value it currently holds. Again, as the name suggests, the dynamic class can change during the course of execution as a variable is assigned new values.
In Java, the binding of a method to execute in response to a message is determined by the dynamic value being held by the receiver.
In a few languages, the rules for overridding are more difficult. Most notable among these is C++. The binding of messages in C++ is complex, involving a number of choices of keywords and mechanisms for declaration.
Static and Dynamic Classes
• The static class is the class used to declare a variable, and the dynamic class is the class of the value it currently holds
• The legality of a message expression is determined by a variable’s static class.
• The meaning of a message expression is determined by a variable’s dynamic class.
Naming Conventions
• For mutators, start method names with “set”, followed by the name of the variable being changed.
• For accessors, same as above, but use “get”.
private int numWindows;
public void setNumWindows(int numWindows)
public int getNumWindows()
Example
public class Test {private int age; // instance variables should never be public
public void setAge(int age){// If age is negative, set it equal to 0, and continueif (age < 0)
age = 0;this.age = age;
}
public void getAge(){return age;
}}
IS-A means Inheritance
If one ‘thing’ IS-A type of another ‘thing’, then the first ‘thing’ should extend the second ‘thing’.
A school, house and garage ARE buildings:
public class Building{...}
public class House extends Building{...}
public class School extends Building{...}
public class Garage extends Building{...}
HAS-A does NOT mean Inheritance
Class Building has doors, windows, and other things, but class Building is not a door or a window. So, you would expect Building to have private instance variables that relate to doors and windows.
Assume there are classes that define doors and windows. Since there are many of each, and each can have different characteristics, maybe there are arrays of Door and Window objects:
public class Building {private Door[] doors;private Window[] windows;...
}
HAS-A and Delegation
If you need to lock up a building, then you need to close and lock the windows and doors. But the user should only need to execute a method on the Building class, and shouldn’t care how it is accomplished. Only the implementer needs to know.
Lock Up the Building
public class Building {
private Door[] doors;private Window[] windows;
public void lockUp() {for(int i = 0; i < windows.length; i+
+)windows[i].lockUp();
for(int i = 0; i < doors.length; i++)doors[i].lockUp();
}...
}
class Door {void lockUp() {
// code that implements// the closing and
locking // of doors
}...}
class Window {void lockUp() {
// code that implements// the closing and
locking // of windows
}...}
Rules for Overriding Methods
• The argument list must exactly match that of the overridden method.
• The return type must exactly match that of the overridden method.
• The access level can be less restrictive than that of the overridden method.
• The overridden method can’t throw exceptions not thrown by the method in the superclass.
• The overridden method can throw less exceptions than thrown by the method of the superclass.
• You cannot override a method marked ‘final’.
private Methods are not Inherited
You can’t call a method using a subclass reference if that method is defined as private in the superclass, and it does not explicitly exist in the subclass.
public class TestAnimals {public static void main(String[] args){
Horse h = new Horse();h.eat(); // ILLEGAL
}class Animal {
private void eat(){} // is NOT inherited, and is NOT visible in Animal
}
class Horse extends Animal {}
Overridden Methods
For a method to be overridden, that method name must exist in a superclass. This is an inheritance property.
The most frequently overriden method is probably the toString() method of Object. All subclasses of Object can create their own version of String toString(), and it will be called instead of the toString() method of Object.
Simple Example of Overriding
public class Animal {public void eat() {
System.out.println(“class Animal eat”);}
class Horse extends Animal {public void eat() {
System.out.println(“class Horse eat”);}
}
Calling Overridden Methods
public class TestAnimals {public static void main(String[] args){
Animal a = new Animal(); // dynamic class is AnimalAnimal h = new Horse(); // dynamic class is Horsea.eat(); // calls Animal method, since it is the dynamic classh.eat(); // calls Horse method, since it is the dynamic class
}}
public class Animal {public void eat(){..}
}
public class Horse extends Animal {public void eat() {...} // overrides eat() from superclass
}
Overridden Methods
You must never create the overriden method with greater restriction. Subclasses can thus “open up” the object by making them less restrictive (which means more visible).
1. private (most restrictive)
2. default
3. protected
4. public (least restrictive)
class SuperClass {private void method(){}
}
class SubClass1 extends SuperClass {void method(){}
}
class SubClass2 extends SubClass1 {protected void method(){}
}
class SubClass3 extends SubClass2 {public void method(){}
}
Overridden Methods
If you attempt to make an overridden method more restrictive, you will get a compiler error. In the code at the right, the protected method of SubClass1 was overridden in class SubClass2 with the more restrictive default (package) access:
Practice.java:15: method() in SubClass2 cannot override method() in SubClass1; attempting to assign weaker access privileges; was protected
void method(){}
class SuperClass {private void method(){}
}
class SubClass1 extends SuperClass { protected void method(){}
}
class SubClass2 extends SubClass1 {void method(){}
}
class SubClass3 extends SubClass2 {public void method(){}
}
Using ‘super’ to Access Superclass Members
Class Horse method printYourself() first calls the superclass method of the same name, and then does more processing. Used to avoid duplication of code.
public class Animal {public void printYourself() {}
}
class Horse extends Animal {public void printYourself() {
super.printYourself();// do something else
}}
Overloaded methods
• Within a class, methods with the same name but different argument lists (and possibly different return types) are called ‘overloaded methods’.
• Overloaded methods– must change the argument list– can change the return type– can change the access modifier– can declare new or broader checked exceptions– can be in the same class or in a subclass.
Overloading Examples
Note that the number, type and/or order of the arguments in the argument list is different for each overloaded method:
public void changeSize (int size, String name){}
public int changeSize (int size, float pattern){}
public void changeSize (float pattern, String name) throws IOException {}
Overloading
In class Bar, notice that it has the inherited method doStuff(int, String).Then, in class Bar, the method doStuff(int, float) is explicit. Since the argument list is different, the method that is explicit in class Bar
‘overloads’ the inherited method from the superclass. It does NOT override the superclass method, because the argument list is different:
public class Foo {public void doStuff (int y, String s){}
}
public class Bar extends Foo {// ok to add exceptions when overloadingpublic void doStuff (int y, float s) throws IOException {}
}
Constructors
• Constructors are given the responsibility of creating an object in memory, and returning a reference to that object.
• Constructors do not have a return type.
• They have the same name as the class.
• They can be overloaded.
• They are typically used to initialize instance variables.
• The JVM creates an implicit no-arg constructor if the class does not define any constructor.
Constructors
• A method can have the same name as a constructor, but that is not conventional.
• There is an implicit call super() to the superclass constructor. This is the first thing that happens in the subclass constructor.
• You can call any superclass constructor by supplying the correct arguments in super().
• Any access modifier can be used with constructors. Using private constructors requires a static method to call that constructor.
Constructors
• Abstract class, just like concrete classes, have constructors that are called by the subclass.
• Interfaces do not have any constructors, implicit or otherwise.
• You can call a constructor from another constructor, but not from a method in the class.
Constructor Examples
Calling a constructor from a method is illegal:
class Horse {Horse(){}void doStuff(){
Horse(); // can’t do this}
}
class Animal {Animal(String name){}
}
superclass does not have a no-arg constructor
class Horse extends Animal{Horse(){
super();}
}
Constructor ExamplesSubClass has an implicit default constructor which makes a call super() to
the superclass constructor. But a no-arg constructor does not exist in the superclass
class SuperClass {String name;SuperClass(String name){
this.name = name; }
}
class SubClass extends SuperClass {}
Practice.java:13: SuperClass(java.lang.String) in SuperClass cannot be applied to ()
Overloaded ConstructorsYou can create any number of overloaded constructors, based upon your
needs.
class Person {private String lastName;private String firstName;private Date birthDate;private Address address;
public Person(){...}public Person(Person p){...}public Person(String lastName, String firstName){...}public Person(String lastName, String firstName, Date date){...}public Person(String lastName, String firstName, Address address){...}etc...
}
Superclass ConstructorsA subclass can use the superclass
constructor to initialize inherited instance variables.
class SuperClass {String name;SuperClass(){}SuperClass(String name){
this.name = name;}
}
class SubClass extends SuperClass {SubClass(){}SubClass(String name){
super(name);}
}
A subclass can also explicitly initialize inherited instance variables.
class SuperClass {String name;SuperClass(){}SuperClass(String name){
this.name = name;}
}
class SubClass extends SuperClass {SubClass(){}SubClass(String name){
this.name = name;}
}
Overloaded Constructors
A class can make calls to other constructors in the class to instantiate the object.
The call to other constructors must be the first statement in a constructor.
class Address {
String street, city, state;
Address(){}
Address(String street){
this.street = street;
}
Address(String street, String city){
this(street);
this.city = city;
}
Address(String street, String city, String state){
this(street, city);
this.state = state;
}
}
Constructors
You can’t have both a call to the superclass constructor and an overloaded constructor within a constructor, as both must always be the first statement in a constructor.
The error from the code is:
Practice.java:24: call to this must be first statement in constructor
this(color)
class SuperClass {String name;
SuperClass(){}SuperClass(String name){
this.name = name;}
}
class SubClass extends SuperClass {String color;SubClass(){}SubClass(String color){
this.color = color;}
SubClass(String name, String color){super(name);this(color);
}}
Legal Return Types• If you overload a method, it is not
enough to just change the return types. You must also change the parameter list.
Practice.java:14: doIt() in SubClass cannot override doIt() in SuperClass; attempting to use incompatible return type
found : voidrequired: java.lang.String void doIt(){}
class SuperClass {String name;String doIt(){
return "";}
}
class SubClass extends SuperClass {void doIt(){} // illegal
}
class SubClass1 extends SuperClass {void doIt(String it) {} // OK
}
End of Chapter 5