Given public class Vehicle private String make car
Given: public class Vehicle{ private String make; //car info instance data private String model; private int year; private double mpg; public Vehicle(String mk, String mdl, int yr, double mileage){ make = mk; model = mdl; year = yr; mpg = mileage; } public void set. Make(String nmake) { make = nmake; } public void set. Model(String nmodel) { model = nmodel; } public void set. Year(int nyear) { year = nyear; }
public String get. Make() { return make; } public String get. Model() { return model; } public int get. Year() { return year; } public double get. Mileage() { return mpg; } public String to. String() { return year + " " + make + " " + model; } }
• Inheritance: extend classes by adding methods and fields This is one form of software reuse !! • Example: Car class a Car is a Vehicle with trunksize class Car extends Vehicle { new methods new instance fields }
• Car automatically inherits all methods and instance fields of Vehicle Car mycar = new Car(“Ford”, ”Mustang”, 1969); //assume Car constructor exists mycar. set. Mpg(10. 5); // OK to use Vehicle method with Car object • Extended class = superclass (Vehicle), extending class = subclass (Car)
An Inheritance Diagram • Every class extends the Object class either directly or indirectly Figure 1: An Inheritance Diagram
• In subclass, specify added instance fields and additional methods ; public class Car extends Vehicle{ // data private boolean convertible; private double trunksize; public void set. Convert(boolean conv){ convertible = conv; } public boolean get. Convert() { return convertible; } //calculate distance that can currently be traveled public double distance (double gallons) { return gallons * get. Mileage(); //use superclass method to access // private data inheritied from Vehicle }
• In subclass, change (override) methods ; //class Car continued…………. . //OVERRIDE the to. String method public String to. String() { return get. Year() + " " + get. Model() + " trunk cap: " + trunksize; } Note again, that call to inherited public method uses implicit object (no object need be specified) } //can USE superclass method public String to. String() { return super. to. String() + "trunk cap: ” + trunksize; }
Inheriting Instance Fields • A subclass has no access to private fields of its superclass • Subclass must use public interface • Inherit field: All fields from the superclass are automatically inherited • Add field: Supply a new field that doesn't exist in the superclass • Can't override fields • What if you define a new field with the same name as a superclass field? § Each object would have two instance fields of the same name this. varname, super. varname § Fields can hold different values § Legal but extremely undesirable
Inheriting Methods • Override method: § Supply a different implementation of a method that exists in the superclass § Must have same signature (same name and same parameter types) § If method is applied to an object of the subclass type, the overriding method is executed • Inherit method: § Don't supply a new implementation of a method that exists in superclass § Superclass method can be applied to the subclass objects • Add method: § Supply a new method that doesn't exist in the superclass § New method can be applied only to subclass objects
Invoking a Super Class Method • Can't just call to. String() in to. String() method of Car • That is the same as this. to. String() • Calls the same method (infinite recursion) • Instead, invoke superclass method super. to. String() Continued…
Inheritance Hierarchies • Sets of classes can form complex inheritance hierarchies • Example: Figure 3: A Part of the Hierarchy of Ancient Reptiles
Inheritance Hierarchies Example: Swing hierarchy Figure 4: A Part of the Hierarchy of Swing User Interface Components Continued…
Subclass Constructors • super followed by a parenthesis indicates a call to a superclass constructor public Car (String mk, String mdll, int yr, double miles, double trk){ super(mk, mdl, yr, miles); trunksize = trk; } • Must be the first statement in subclass constructor • If subclass constructor doesn't explicitly call a super class constructor, default super is implicitly called § Default constructor: constructor with no parameters § If all constructors of the superclass require parameters, then the compiler reports an error!
Subclass Constructors • Note: Vehicle does not have default constructor … • If we defined Car constructor as follows: public Car (String mk, String mdll, int yr, double miles){ set. Make(mk); set. Model(mdl); set. Year(yr); set. Mpg(miles); } This method will not compile, as implicit call to default Vehicle constructor is not possible!!
Converting Between Subclass and Superclass Types • Ok to convert subclass reference to superclass reference Car my. Car = new Car(“Chevy”, “Camaro”, 1973); Vehicle a. Car = my. Car; Object the. Car = my. Car; Note: all three reference variables are referring to the same object
• Superclass references don't know the full story: a. Car. set. Mpg(7. 8); // OK a. Car. distance(67); //NO!! // No--not a method of the class to which a. Car belongs • When you convert between a subclass object to its superclass type: § The value of the reference stays the same–it is the memory location of the object § But, less information is known about the object
• Why would anyone want to know less about an object? • To write reusable code when code only needs to know about superclass features… • FOR EXAMPLE …. . what if we also had a Truck class (next slide)
Suppose we have a Truck class too public class Truck extends Vehicle{ private boolean trailer. Hitch; private double bed. Length; public void set. Trailer. Hitch(boolean hitch){ trailer. Hitch = hitch; } public double get. Len() { return bed. Length; } //calculate Load that can be carried public double calc. Load (double lb. Per. Cubic. Foot) { return (bed. Length * lb. Per. Cubic. Foot) / …etc ; } // to. String etc………… }
Class Usage //can create and assign to same type reference Vehicle v 1 = new Vehicle(“ford”, “mustang”, 1966, 28. 5); Car c 1 = new Car(“vw”, ”rabbit”, 1978, 35. 2); Truck t 1 = new Truck(“MAC”, ”pickup”, 1968, 16. 0); //a subclass is the superclass type, but not vice versa Vehicle v 2 = new Car(“cadillac”, ”seville”, 1988, 16. 0); Vehicle v 3 = new Truck(“MAC”, ”pickup”, 1968, 16. 0); Car c 2 = new Vehicle(“gmc”, ”yukon”, 122, 13. 5); //error //public superclass methods can be called v 1. set. Make(“Mercury”); t 1. set. Make(“Toyota”); c 1. set. Make(“Nissan”); by subclass object
Application can work with Carsa and Trucks using same code public class App{ public static void main(String[] args){ Vehicle new. Vehicle ; // one list to store all Vehicles Array. List<Vehicle> inventory = new Array. List<Vehicle>(); //while user wishes to enter vehicles while(JOption. Pane. show. Input. Dialog("Enter a vehicle? ? Y/N"). equals("Y")){ String whichone = JOption. Pane. show. Input. Dialog("(C)ar or (T)ruck"); switch (whichone. char. At(0) ) { //determine which kind case 'C': new. Vehicle = new Car(); break; case 'T': new. Vehicle = new Truck(); break; default: new. Vehicle = new Car(); // car assumed as default type } // use same code to get details for cars & trucks new. Vehicle. set. Make(JOption. Pane. show. Input. Dialog("make? ")); new. Vehicle. set. Model(JOption. Pane. show. Input. Dialog(“ model ? ")); new. Vehicle. set. Year(Integer. parse. Int(JOption. Pane. show. Input. Dialog ("year? "))); inventory. add(new. Vehicle); }
Application can work with Cars and Trucks using same code // what is our inventory String output = ""; for ( int i=0; i<inventory. size(); i++) output = output + "n" + inventory. get(i); JOption. Pane. show. Message. Dialog(null, output); } } Simple loop to outputs all Vehicle information -The correct version of to. String is selected at run time --- POLYMORPHISM!!
Converting Between Subclass and Superclass Types • Occasionally you need to convert from a superclass reference to a subclass reference Vehicle my. Ride = new Car(“Chevy”, “Camaro”, 1973); my. Ride. set. Conv(true); // will cause compile error because // compiler doesn’t know it’s a Car Can only call set. Conv with a Car object Car this. Car = (Car) my. Ride; this. Car. set. Conv(true); • This cast is dangerous: if you are wrong, an exception is thrown
• Solution: use the instanceof operator • instanceof: tests whether an object belongs to a particular type if (my. Ride instanceof Car) { Car this. Car = (Car) my. Ride; this. Car. set. Conv(true); }
Polymorphism • Polymorphism: ability to refer to objects of multiple types with varying behavior • Polymorphism at work: public void print. It(Vehicle ride){ System. out. println( ride. to. String() ); • Depending on types of ride, different version of to. String is called
Access Control • Java has four levels of controlling access to fields, methods, and classes: § public access • Can be accessed by methods of all classes § private access • Can be accessed only by the methods of their own class § package access • The default, when no access modifier is given • Can be accessed by all classes in the same package • Good default for classes, but extremely unfortunate for fields § protected access • Can be accessed by subclasses and package
Recommended Access Levels • Instance and static fields: Always private. Exceptions: § public static final constants are useful and safe § Some objects, such as System. out, need to be accessible to all programs (public) § Occasionally, classes in a package must collaborate very closely (give some fields package access); inner classes are usually better
Recommended Access Levels • Methods: public or private • Classes and interfaces: public or package § Better alternative to package access: inner classes • In general, inner classes should not be public (some exceptions exist, e. g. , Ellipse 2 D. Double) • Beware of accidental package access (forgetting public or private)
Object: The Cosmic Superclass • All classes defined without an explicit extends clause automatically extend Object Figure 8: The Object Class is the Superclass of Every Java Class
Object: The Cosmic Superclass • Most useful methods: § String to. String() § boolean equals(Object other. Object) § Object clone()
The String to. String() Method String to. String() is called whenever you concatenate a string with an object: import java. awt. Rectangle; Rectangle rec 1 = new Rectangle(5, 10, 20, 30); System. out. println(“rec 1” + rec 1); //outputs “rec 1 java. awt. Rectangle[x=5, y=10, width=20, height=30]" Object class provides a to. String(), so all objects have one!!
What if you don’t override the tostring Method ? • Object class to. String() method executed • Object class knows nothing about the specifics of your class • Object class to. String consists of only two piece of info it has, class name and hash code (value based on storage address) • Try it: code a class Widget with no to. String and write an application with: • 1. Widget my. Widget = new Widget(); • 2. System. out. println(my. Widget);
Overriding the tostring Method • To provide a nicer representation of an object, override to. String: public String to. String() { return “Widget: Size: 5 } "; Very simple to override to. String, just provide a to. String method which returns a String which is how you would want the object represented textually.
If (coin 1 == coin 2) • == tests for equal location Two References to Same Objects
If (coin 1. equals( coin 2) ) • Object class equals also tests for equal location Two References to Same Objects
Need to override the equals method so that equal contents are checked • equals is intended to test for equal contents Two References to Equal Objects Continued…
Overriding the equals Method When redefining equals method, you cannot change object signature public boolean equals (Object obj) { } Continued…
Overriding the equals Method Equals method should be based on instance data of two objects …. . public boolean equals (Object obj) { if (make. equals(obj. make) &&model. equals(obj. model )&& year == obj. year & mpg == obj. mpg) return true; else return false; } But… this will not compile because an Object object does not have make, model, year and mpg instance fields.
Overriding the equals Method need to CAST Object obj to a Vehicle object …. . public boolean equals (Object obj) { Vehicle vobj = (Vehicle) obj; if (make. equals( vobj. make) && model. equals(vobj. model) && year == vobj. year &&mpg == vobj. mpg) return true; else return false; }
Overriding the equals Method Need to be sure that obj IS an object before you cast to avoid Class. Cast. Exception. public boolean equals (Object obj) { if (obj instanceof Vehicle) { Vehicle vobj = (Vehicle) obj; if (make. equals(vobj. make) && model. equals(vobj. model)&& year == vobj. year &&mpg == vobj. mpg) return true; else return false; } This will work fine for Vehicle objects, but We will need to use this method when checking Equality of our subclasses too … need to be more specific when checking for equal class types
Overriding the equals Method Need to be sure that obj IS an object before you cast to avoid Class. Cast. Exception. public boolean equals (Object obj) { if (get. Class(). equals(obj. get. Class() )) { Vehicle vobj = (Vehicle) obj; if (make == vobj. make && model == vobj. model && year == vobj. year &&mpg == vobj. mpg) return true; else return false; } get. Class() is a method inherited from the Object class which returns a Class object
Overriding equals in the Car subclass public boolean equals (Object obj) { if (super. equals(obj) == false) return false; else { // we now know they are both Cars, and // super class fields are equal // need to check additional Car field Car tobj = (Car) obj; return ( convertible == tobj. convertible && trunksize == tobj. trunksize); }
Object assignment ……. • Copying an object reference gives two references to same object Vehicle my. Car = new Car(); Vehicle car = my. Car;
Object class has a Object clone() Method • Object class clone() method returns a copy of the invoking object • Using the clone() method is inherited from the object class by all subclasses, BUT ACCESS is PROTECTED, so method not accessible by application class. Vehicle my. Vec = new Vehicle(“Toyota” , “Corolla”, 1967, 34. 5); //Vehicle inherits // clone method from Object class Vehicle another. Vec = (Vehicle) my. Vec. clone(); //BUT application can not call it!! This is a security measure added to the Java language with Java 1. 2. At that point the Java language’s popularity as a Web programming language was becoming apparent.
An object can ONLY be cloned IF it’s class overrides the Object clone() method public class Vehicle { public Object clone() { //same signature for override return super. clone(); // calls superclass Object’s clone } Vehicle my. Vec = new Vehicle(“Toyota” , “Corolla”, 1967, 34. 5); Vehicle another. Vec =(Vehicle) my. Vec. clone(); BUT …. Java has one more security measure for cloning.
An object can ONLY be cloned IF it’s class overrides the Object clone() method //class which overrides Clone MUST implement. Cloneable public class Vehicle implements Cloneable { { public Object clone() { try{ return super. clone(); //Object’s clone throws checked exception if //cloneable not implemented, so must // be called within a try/catch block } catch(Exception e) { return null; } }
The Object. clone Method • Creates shallow copies Figure 12: The Object. clone Method Makes a Shallow Copy
- Slides: 47