1.73k likes | 1.75k Views
Polymorphism. Legal assignments. Widening is legal Narrowing is illegal (unless you cast ).
E N D
Legal assignments • Widening is legal • Narrowing is illegal (unless you cast) class Test { public static void main(String args[]) { double d; int i; d = 5; // legali = 3.5; // illegal i = (int) 3.5; // legal }}
Legal method calls • Legal because parameter transmission is equivalent to assignment • myPrint(5)is likedouble d = 5; System.out.println(d); class Test { public static void main(String args[]) { myPrint(5); } static void myPrint(double d) { System.out.println(d); }} 5.0
Illegal method calls • Illegal because parameter transmission is equivalent to assignment • myPrint(5.0) is likeint i = 5.0; System.out.println(i); class Test { public static void main(String args[]) { myPrint(5.0); } static void myPrint(int i) { System.out.println(i); }} myPrint(int) in Test cannot be applied to (double)
Overloading class Test { public static void main(String args[]) { myPrint(5); myPrint(5.0); } static void myPrint(int i) { System.out.println("int i = " + i); } static void myPrint(double d) { // same name, different parameters System.out.println("double d = " + d); }} int i = 5double d = 5.0
Why overload a method? • Sometimes so you can supply defaults for the parameters • int increment() { return increment(1);} • Notice that one method can call another of the same name • Sometimes so you can supply additional information: • void printResult(String message) { System.out.println(message); printResult();}
Multiple constructors • You can “overload” constructors as well as methods • Counter() { count = 0; } • Counter(int start) { count = start; } • One constructor can “call” another constructor in the same class, but there are special rules • You call the other constructor with the keyword this • The call must be the very first thing the constructor does • Point(int x, int y) { this.x = x; this.y = y; sum = x + y; } • Point() { this(0, 0); System.out.println("At origin"); } • A common reason for overloading constructors is (as above) to provide default values for missing parameters
Superclass construction • The very first thing any constructor does, automatically, is call the default constructor for its superclass • class Foo extends Bar { Foo() { // constructorsuper(); // invisible call to superclass constructor ... • You can replace this with a call to a specific superclass constructor • Use the keyword super • This must be the very first thing the constructor does • class Foo extends Bar { Foo(String name) { // constructor super(name, 5);// explicit call to superclass constructor ...
Polymorphism • Polymorphism means many (poly) shapes (morph) • In Java, polymorphism refers to the fact that you can have multiple methods with the same name in the same class • There are two kinds of polymorphism • Overloading (which you have just seen) • Two or more methods with different signatures • Overriding (which you will see shortly) • Replacing an inherited method with another having the same signature
Signatures • In any programming language, a signature is what distinguishes one function or method from another • In C, every function has to have a different name • In Java, two methods have to differ in their names or in the number or types of their parameters • foo(int i)andfoo(int i, int j)are different • foo(int i)andfoo(int k)are the same • foo(int i, double d)and foo(double d, int i)are different • In C++, the signature also includes the return type • But not in Java!
Shadowing • This is called shadowing—name in class Dog shadows name in class Animal class Animal { String name = "Animal"; public static void main(String args[]) { Animal animal = new Animal(); Dog dog = new Dog(); System.out.println(animal.name + " " + dog.name); }} public class Dog extends Animal { String name = "Dog";} Animal Dog
Overriding class Animal { public static void main(String args[]) { Animal animal = new Animal(); Dog dog = new Dog(); animal.print(); dog.print(); } void print() { System.out.println("Superclass Animal"); }} public class Dog extends Animal { void print() { System.out.println("Subclass Dog"); }} • This is called overriding a method • Method print in Dog overrides method print in Animal Superclass AnimalSubclass Dog
How to override a method • Create a method in a subclass having the same name and the same number and types of parameters • Parameter names don’t matter • The return type must be the same • The overriding method cannot be more private than the method it overrides
Why override a method? • Dog dog = new Dog();System.out.println(dog); • Prints something like Dog@feda4c00 • The println method calls the toString method, which is defined in the Object class • Hence, every object can be printed (though it might not look pretty) • The method public String toString() may be overridden • If you add to class Dog the following: • public String toString() { return name;} • ThenSystem.out.println(dog); will print the dog’s name, which may be something like: Fido
A little puzzle • public class main { int main = 5; public static void main(String args[]) { main main = new main(); System.out.print(main); }} • This is a legal program (!); what does it print? • Answer:main@ecf76e • Next question: why?
Namespaces • Java figures out what kind of thing a name refers to, and puts it in one of six different namespaces: • package names • type names • field names • method names • local variable names (including parameters) • labels
The puzzle solved • public classmain{// type name • intmain= 5;// field name • public static voidmain(Stringargs[]) {// method name • mainmain= newmain();// local names (incl. args) • System.out.print(main); }} • Java prints out object main@ecf76e in local variablemain • We haven’t talked about package names or labels • Note that this is terrible style!
Another little puzzle • public class Test { static int five() { return 5; } public static void main(String args[]) { System.out.print(five); }}cannot resolve symbolsymbol :variable five location: class Test • Answer: five() is a method, but five looks like a local variable
What you should remember • A namespace is a place that Java keeps track of names • Java uses six different namespaces • If you name things intelligently, and don’t use the same name for different things, you don’t have to worry much about namespaces
Instance and class variables • You can declare variables within a class • These variables are called instance variables, or fields • Every object of that class has its own copy of those fields • The fields describe something about the object • You can also declare static variables within a class • There is only one of each static variable • A static variable is also called a class variable • The static variable describes something about the class as a whole
Method variables • You can declare variables within a method or within a constructor • These are called method variables, not fields • Method variables are basically used for computation • Method variables are strictly temporary, and are used only within that method • When a method returns (completes), all its variables are discarded
Example: a “Rabbit” class • class Rabbit { static int population; // class variable (counts Rabbits) double hunger; //instance variable double fear; // instance variable double courage = 0.75; // instance variable • void eat() { double temp; // method variable temp = courage * hunger; if (temp > fear) { System.out.println(“Eating!”); hunger = hunger - 1; } }}
Statements • You can declare variables inside a class or inside a method or a constructor • You can put statements (executable code) only within methods and constructors, not inside a class • Declarations with initializations are still declarations, not statements
Statements must be in methods(or in constructors) • class Rabbit { • double hunger; // OK--declaration • double fear = 5.0; // OK--still a declaration • hunger = 5.0; // illegal--assignment statement • Rabbit ( ) { hunger = 5.0; // OK—statement in a constructor} • void eat ( ) { hunger = hunger - 1; // OK—statement in a method} • }
Access from inside a class • Inside a class, you can access other fields and methods inside the class just by naming them • Example: • class Person { • int age; • void birthday( ) { age = age + 1; } • void growOlder( ) { birthday( ); }} • Equivalently, you can use the keyword this: • void birthday( ) { this.age = this.age + 1; } • void growOlder( ) { this.birthday( ); }
Accessing from outside a class, 1 • Outside a class (from some other class) you access instance variables and methods by • Naming the object you want to talk to • Putting a dot • Naming the variable or method • Example: • // if NOT in class Person, say:if (john.age < 75) john.birthday(); • Inside the class, the keyword this means “this object”: • if (this.age < 75) this.birthday(); // "this" may mean john
Accessing from outside a class, 2 • Outside a class (from some other class) you access class variables and methods by • Naming the class you want to talk to • Putting a dot • Naming the variable or method • Examples: • Person.population = Person.population + 1; • x = Math.abs(y);
Responsibility • In Java, objects are considered to be active • They have behaviors • They are responsible for their own data • Data (variables) must be kept consistent • Example: population should never be negative • In order for a class or object to be responsible for its own data, it must keep control of that data
Loss of control • Suppose a Rabbit object, bugsBunny, has a variable named hunger • Inside the class, this method is fine: • void eat ( ) { hunger = hunger - 1; } • From outside the class, the following is legal: • bugsBunny.hunger = bugsBunny.hunger - 1; • But should we be allowed to “reach inside” a rabbit? • The class needs to protect itself from errors in other classes (and from malicious behavior)
private variables and methods • If you declare a variable or method to be private, that variable or method can only be accessed from within the class • private methods also make sense, e.g.digest() • If you declare a variable or method to be public, then any code anywhere can access it • Typically, a class or object has both • Methods for use by the rest of the program • Methods and variables that it alone should control
Levels of access • private -- access only from within the class • “package” -- access from within the class, or from any class in the same directory (“folder”) • This is the default; there is nopackage keyword • protected -- access from within the class, or from within any subclass, or from any other class in the same directory • public -- access from anywhere at all
Levels of access, II • To make a variable or method visible • Only within this class: private • From this class and its subclasses: not possible • From this class and its subclasses, and any other class in this directory: “package” (default) • From this subclass and its subclasses, and any other classes in this directory: protected • From anywhere: public
Getters and setters • One way to control access is via getters and setters: • class Rabbit { • private double hunger; • // getterpublic double getHunger() { return hunger;} • // setterpublic void setHunger(double hunger) { this.hunger = hunger;} • This seems silly, but it’s much safer and more flexible
Immutable objects • Suppose a Planet has a mass, and you want to be able to see its mass but not change it: • class Planet { • private long mass; • // ConstructorPlanet(long mass) { this.mass = mass;} • //getterlong getMass() { return mass;} • // Notice there is no setter! • }
General approach • If you know the name of the package, click it in the upper left panel; or click All Classes • Click on the class in the lower left panel • Scroll in the right pane to find the summary of the field, method, or constructor you want • Or just read the general description • For more information, click the link in the summary to go to the detailed information
General description of the class Field summary Constructor summary Method summary Field detail Constructor detail Method detail In each case, the “summary” is the first sentence of the “detail” The main information area
Reading the method descriptions I • An example from the String class: • public char charAt(int index) • Returns the character at the specified index • public means accessible from anywhere • char is the return type • charAt is the name of the method • int is the type of parameter expected • index is just a suggestive name • Example use: char firstChar = myStr.charAt(0);
Reading the method descriptions II • Another example from the String class: • public static StringvalueOf(int i) • Returns the string representation of the intargument. • public means accessible from anywhere • static means this is a class method (see use below) • String is the return type, and is a hyperlink • valueOfis the name of the method • int is the type of parameter expected • i is just a suggestive name • Example use: String numeral = String.valueOf(m / n);
How was this documentation produced? • All Java documentation was produced by the javadoc program from javadoc (or just doc) comments in the source code • Your doc comments can be used in the same way to produce professional-looking documentation
Value of the API • Version packages classes methods • Java 1.0 8 212 1545 • Java 1.1 23 504 3851 • Java 1.2 60 1781 15060 • Java 1.3 77 2130 17158 • Java 1.4 135 2738 ? • Java 1.5 ? ? ? • You can only learn a small fraction of these • When you learn the kinds of things that are in the API, and learn to find your way around in it, you become a far more effective and efficient programmer • A good craftsman knows his/her tools
Errors and Exceptions • An error is a bug in your program • dividing by zero • going outside the bounds of an array • trying to use a null reference • An exception is a problem whose cause is outside your program • trying to open a file that isn’t there • running out of memory
What to do about errors and exceptions • An error is a bug in your program • It should be fixed • An exception is a problem that your program may encounter • The source of the problem is outside your program • An exception is not the “normal” case, but... • ...your program must be prepared to deal with it • This is not a formal distinction–it isn’t always clear whether something should be an error or an exception
Dealing with exceptions • Most exceptions arise when you are handling files • A needed file may be missing • You may not have permission to write a file • A file may be the wrong type • Exceptions may also arise when you use someone else’s classes (or they use yours) • You might use a class incorrectly • Incorrect use should result in an exception
The problem with exceptions • Here’s what you might like to do: • open a file • read a line from the file • But here’s what you might have to do: • open a file • if the file doesn’t exist, inform the user • if you don’t have permission to use the file, inform the user • if the file isn’t a text file, inform the user • read a line from the file • if you couldn’t read a line, inform the user • etc., etc. • All this error checking really gets in the way of understanding the code
Three approaches to error checking • Ignore all but the most important errors • The code is cleaner, but the program will misbehave when it encounters an unusual error • Do something appropriate for every error • The code is cluttered, but the program works better • You might still forget some error conditions • Do the normal processing in one place, handle the errors in another (this is the Java way) • The code is at least reasonably uncluttered • Java tries to ensure that you handle every error
The try statement • Java provides a new control structure, the try statement (also called the try-catch statement) to separate “normal” code from error handling: • try {do the “normal” code, ignoring possible exceptions} • catch (some exception) { handle the exception} • catch (some other exception) {handle the exception}
Exception handling is not optional • As in other languages, errors usually just cause your program to crash • Other languages leave it up to you whether you want to handle exceptions • There are a lot of sloppy programs in the world • It’s normal for human beings to be lazy • Java tries to force you to handle exceptions • This is sometimes a pain in the neck, but... • the result is almost always a better program