八、Enhancing classes
Overloading Constructors
• Recall method overloading?
• Like methods, constructors can be overloaded
• An overloaded constructor provides multiple ways to set up a new object
Die die1 = new Die(); //creates a 6 sided die
Die die2 = new Die(20); //creates a 20 sided die
Object-Oriented Analysis
• One of the simplest ways to do object-oriented analysis involves finding nouns and verbs in the program’s specification.
• Many of the nouns will represent classes, and many of the verbs will represent methods.
• This simple technique doesn’t work perfectly, but it can be useful for generating ideas.
• So an initial analysis of a banking system might reveal:
• Nouns ie suggested classes in the specification for a banking system:
• Customer
• Account
• Verbs ie suggested methods in the specification for a banking system:
• Open (an account)
• Deposit (money into an account)
• Withdraw (money from an account)
• Close (an account)
Categories of Methods
• Most instance methods fall into one of several categories:
– Manager methods
– Implementor methods
– Access methods
Manager Methods
• Initialise objects
– Constructors
– Having additional constructors makes a class more useful.
Implementor Methods
• Implementor methods represent useful operations that can be performed on instances of the class.
• Implementor methods usually change the state of an object
• The Account class implementor methods:
– open,
– deposit,
– withdraw,
– close.
Access Methods
• For access to instance variables, the choice is:
– provide instance methods or
– make the variables public (but this violates good object orientation)
• Accessors (or getters)
– methods that return the value of a private variable.
– by convention, names of getters start with the word get
• Mutators (or setters)
– methods that change the value of a private variable.
– by convention, names of setters start with the word set
The this Reference
• Because an instance method is called by an object, the correct instance data is accessed
double balance = acct1.getBalance();
• The keyword this is used to refer to the object that invoked the method
• In the above, the this reference refers to acct1
• The following two methods are actually identical. The first is using the this reference implicitly, the second explicitly
public double getBalance ()
{
return balance;
}
public double getBalance ()
{
return this.balance;
}
Variable Type Differences
Local variables and parameter variables
int result = 0;
public Account (String owner, int account, double initial)
• Are declared within a method
• Only exist for the duration of the method’s execution
• Need to be initialised
– A method is not allowed to access the value stored in a local variable until the variable has been initialised
Instance variables
• belong to an object
– are created when an object is constructed
– exist as long as the object exists
• each object has its own copy
– that’s what allows objects to be different
• are automatically initialised (if not explicitly set in a constructor),
– zero for numeric and char variables
– false for boolean variables
– null for reference type variables
• every instance variable should be initialised in a constructor
Hidden Variables
• We cant declare a variable with the same name as one already in scope
– always use different variable names except in headers of for loops
• Beware of variable names with instantiable classes!!!
• An instance variable and a local variable could have the same name –
– the local variable with the inner scope will take precedence over (or hide) the variable in the outer scope (instance variable)
this used in Constructors
• The this reference can be used to refer to the instance variable of the object
private long acctNumber;
private double balance;
private String name;
public Account(String owner, long account, double balance)
{
this.balance = balance; // and so on for the other variables
}
• This approach is eliminates the need for different yet equivalent names
• It is often found in constructors
The static Modifier
• We have used methods that do not require objects
– eg methods of Math class
• These static or class methods are invoked through the class name - not through an object name
• To make a method static, we apply the static modifier to the method definition
static double sqrt (double num)
• And call the method by the class name
System.out.print (“sq rt of 9: “ + Math.sqrt(9));
Static (or Class) Variables
• The static modifier can be applied to variables as well
• It associates a variable with the class rather than an object
• They are declared with the word static
• Normally, each object has its own data space
• If a variable is declared as static, only one copy of the variable exists
• Eg in the Account class a useful class variable may be
private static double totalDeposits;
• All objects created from the class share access to the static variable
• Changing the value of a static variable in one object changes it for all others
• Eg to allocate a unique asset number every time a new asset object is created
– A static variable could hold the last used asset number
– Any new asset could increment this number by 1
Arrays of objects
• Because each object has a unique identifier we cant use them in loops as we would do with variables
Account acct1 = new Account((“J Bond", 72354, 102.56);
acct1.deposit(100.00);
• By storing objects in an array we can use the power of loops to process multiple objects
• Create an array of objects
Account[ ] acctArray = new Account[3];
• No actual objects have been created at this time
– This is merely an array waiting to receive Account objects
• We need to create each object in the usual way
– Call the constructor of the Account class
– Pass it any parameters it requires
– Assign it to a position in the array
acctArray[index] = new acctArray(name, number, balance);
• After you have instantiated the array with actual objects
– You can use getters and setters or other methods from the Account class to return or change instance variables
balance = acctArray[index].getBalance();or
System.out.println(acctArray[index].getBalance());
Using an array as a database
• Use a for loop to search every position in an array
int index;
for (index = 0; index < acctArray.length; index ++)
{
if (acctArray[index].getAcctNumber == 72354)
break;
}
• When the loop has terminated
– Test whether index is less than acctArray.length
– if so index indicates the position of the record in the array
– Use index to modify that object
acctArray[index].deposit(amount);
Comparing Strings for equality
• Remember to use the equals() method not ==
if (acctArray[index].getName() .equals (“J Bond”)
九、Inheritance
• Genetic inheritance - facts
– Eg Your blood type, hair colour, height, body shape
– Many facts about you (ie, your instance data) are inherited
• Genetic inheritance – behaviour
– eg Sports and leisure interests, loudly or quietly spoken
– Much of your behaviour (ie your methods) are inherited
• Many objects have similarities to other objects
– Eg cars and trucks are similar and examples of vehicles
• A class (car) can have a ‘parent’ (vehicle) from which it inherits some of its data and behaviour
• Inheritance allows a software developer to derive a new class from an existing one
• The existing class is called the parent class, base class or superclass
• The derived class is called the child class or subclass
• Creating employee objects from the Employee class
Employee accountant = new Employee();
Employee programmer = new Employee();
• Other employees may require additional data to number and salary eg company car registration number
• We could change the class to have
– 3 instance variables (empNumber, empSalary, empCarRego)
– 6 methods (getters and setters for the 3 variables)
• It is better programming to keep it as it is and reuse it
• Create a new class EmployeeWithCar that inherits all the instance variables and methods of the Employee class
• Then just add the extra instance variable and methods
Deriving Subclasses
• In Java, we use the reserved word extends to establish an inheritance relationship
public class EmployeeWithCar extends Employee
{
// class contents
}
Advantages of inheritance
• Saves time
– reusing data and methods that already exist
– makes programs easier to write
• Reduces errors
– methods have already been used and tested
• A simple Account class may have this instance variable:
private double balance;
• And these methods:
public double deposit (double amount)
public double withdraw (double amount, double fee)
public double getBalance ()
A SavingsAccount class may want to use these features and also have an interest rate
• A SavingsAccount is an Account, but with more features eg it has an interest rate
Writing Subclass Constructors
• A subclass doesn’t inherit constructors from its superclass
• The constructor for the SavingsAccount class will need to initialize both the balance and interestRate variables
– But the superclass instance variables are likely to be private so they cannot be referenced directly from the subclass
• The hard part of writing a constructor for a subclass is initializing the variables that belong to the superclass
• Writing constructors for a subclass is the same, except for initialisation of superclass variables (if private)
public SavingsAccount (double initialBalance, double initialRate)
{
balance = initialBalance; //ERROR
interestRate = initialRate;
}
• As balance was declared as private in the Account class this will not compile – the SavingsAccount class has no access to it
The super Reference
• A child’s constructor is responsible for calling the parent’s constructor
• The first line of a child’s constructor should use the super reference to call the parent’s constructor
• To access a superclass private instance variable we need to use a superclass method…or in this case constructor
• We want to use the parent's constructor to set up the "parent's part" of the object
• The super reference can be used to refer to the parent class, and is often used to invoke the parent's constructor
• The first line of a child’s constructor uses the super reference to call the parent’s constructor
Invoking the superclass constructor
• The SavingsAccount constructor invokes the Account constructor using the word super
public SavingsAccount (double initialBalance, double initialRate)
{
super (initialBalance); //invoke Account constructor
interestRate = initialRate;
}
• The account constructor will initialise the balance variable to the value stored in initialBalance
Superclass constructor parameters
• The subclass constructor must provide all the parameters required by the superclass constructor in order eg.
• If a subclass constructor fails to include super, the compiler will automatically insert super(); at the beginning of the constructor.
• If a subclass has no constructors at all, the compiler will create a no-arg constructor that contains super(); but no other statements.
Controlling Inheritance
• Visibility modifiers determine which class members get inherited and which do not
• Variables and methods declared with public visibility are inherited
• Those with private visibility are not actually inherited in that we need to use the superclass constructor and methods to access them
• But public variables violate our goal of encapsulation!
The protected Modifier
• There is a third visibility modifier that helps in inheritance situations: protected
• protected behaves the same as private within a class but allows a member of a base class to be inherited into the child class
private can only be accessed in the same class
protected can only be accessed in the same class or in a subclass
public can be accessed in any class
• Declaring instance variables protected exposes them to all subclasses
• This is a potentially unlimited number and may weaken an object-oriented goal of encapsulation
• If a subclass needs access to these variables it should be able to call a getter or setter method of the superclass
• We will not use protected variables
• Always declare instance variables private
Methods available to a subclass
• Inherit methods from the superclass
– superclass methods can be applied to subclass objects
account1.deposit(200.00);
• Define new methods
public void setInterestRate(double rate);
• Override methods from the superclass
– ie specify a method with the same signature (that is the same name, return type and parameter types) in the subclass
– this method defined in the subclass will take precedence
– Use super to call an overridden method
• Java looks first in the class of the calling object, then in the class’s superclass, then its superclass etc
• Consider the following statement:
account1.deposit(500.00);
• Java first looks for the deposit method in the SavingsAccount class, then in the Account class.
Overloading vs. Overriding
• Don't confuse the concepts of overloading and overriding
• Overloading deals with multiple methods in the same class with the same name but different signatures
• Overriding deals with two methods, one in a parent class and one in a child class, that have the same signature
• Overloading lets you define a similar operation in different ways for different data
• Overriding lets you define a similar operation in different ways for different object types
Never finish on Java, even not start.