Lecture 9
- If I created a class called Human then it should have all the parts of a
human and methods to do all the things a human can do.
- Now what if I wanted to create a class called Man?
- Anatomically, a man is different from a woman but both of them are human.
- The class Human would contain all the things are that common to both men and women.
- The class Man would have all the things that are common to Human but it would have additional things like facial hair.
- I could write the Man class from the beginning but if I already have a Human class, why not add to the Human class?
- This is what inheritance is all about.
- I could make a copy of Human.java, rename it to Man.java and then add the things unique to a man.
- What if I did not have the Human.java source code?
class Man extends Human {
// add the things unique to a Man
}
- Now, all the things which are common to Human are common to Man.
- If the Human class had a method called eat() then the Man class now has a method called eat().
- The extends keyword tells Java to, conceptually, copy and paste all the Human class into the Man class.
- In this example, the Human class is the parent class of Man. Man is called a child of Human.
- What happens if I add new methods to the Man class? They are not passed back to the parent class.
class Man extends Human {
boolean beard = false;
public boolean hasBeard() {
return beard;
}
}
- The Man class has all the methods of a Human plus the hasBeard method.
- The Human class is unchanged.
- What is the syntax of all this like? Here is a sample Human class and a Man class:
class Human {
protected String name;
public Human(String n) {
name = n;
}
public String getName() {
return name;
}
}
class Man extends Human {
private boolean beard;
public Man(String name, boolean beard) {
super(name);
this.beard = beard;
}
public boolean hasBeard() {
return beard;
}
}
- Now if I execute the following:
Man me = new Man("Darrell", false);
System.out.print(me.getName());
if(me.hasBeard())
System.out.println(" has a beard.");
else
System.out.println(" has no beard.");
- To create an instance of Man I execute the first line of code.
- The string "Darrell" gets assigned to name and false gets assigned to beard in the constructor of the Man class.
- The statement super(name); tells Java "call the constructor of the parent of the current class"
- The parent of Man is Human so this is telling Java to call the constructor Human(name);
- Thus name gets assigned to n in the Human class constructor.
- After the constructor of Human is done, execution returns to the constructor of Man.
- The line after super(name); is the line this.beard = beard;
- If you look at the Man class constructor you will see that there is the variable beard as a parameter to the constructor and as a global variable.
- When I say this.beard I am referring to the global variable. When I say beard I am referring to the closest variable.
- In most cases, the closest variable is the global variable but in this case, the closest variable is the parameter.
- So the line is telling Java, "Make the global variable (this.beard) equal to the parameter (beard)."
- The next line of code has me.getName() which asks me (an instance of Man) for the man’s name.
- The Man class has no method called getName so it asks its parent.
- If the parent did not have a method called getName then we could have an error but since it does this code compiles fine.
- The next line of interest is me.hasBeard(). This is the same as code you have already been creating.
- In an earlier lecture I talked about public, private and protected modifiers.
- The public means the method or variable to accessible outside the class by completely different objects. Don’t use public if it violates encapsulation.
- The private/protected means the method or variable is only visible inside the object but there is a slight different between the two modifiers.
- If a method or variable is declared private then it is not passed on to its children.
- For example, if the Human class contained:
private boolean setName(String n)
- The Man class would not inherit the method. Thus something like the following would not work:
me.setName("Bob");
- So what if I wanted something that was private, i.e. I did not want other classes using it because it was for internal use only, but I did want my children to inherit it?
- This is what protected is for. If a method is protected then it is inherited by the children but it is still not visible to the other classes.
- Thus, if the method or variable is supposed to be accessible by everyone then make it public.
- Or, if the method or variable is supposed to be inherited by classes extending this class then make it protected.
- Otherwise, make it private.
- What if I added the following to the Man class?
public String getName() {
return "Man";
}
- When I make a call to me.getName() it will return "Man" all the time.
- The way Java resolves a method call is to look at the class in question. In this case the class type is Man.
- If there is a method in the class which has the correct number and type of inputs then we use that method.
- If there is no match then we go to the parent class and see if the parent class has a match.
- We keep going up the extends chain until a match is found or we get to the top.
- NOTE: if the class does not extend anything then it defaults to extends Object. The Object class is the ultimate parent of everything.
- The same holds true for variables. If I have the variable name in the Man class then it replaces the variable name in the Human class.
- What if I want to get to a hidden variable in the parent class? I can use:
super.name
super.getName();
- This tells Java to go to the method getName in the parent class rather than the version in the current class.
- Using the keyword super tells Java, go to the parent to look for the variable or method.
- When you extend a class there is a chance that it has extended a class. For example, the Applet class is extended from Panel. Panel is extended from Container. Container is extended from Component and Component is extended from Object.
- This means that when I use the Applet class, it does everything that is listed on page 673 to 675 of the text book plus it does everything that is in Panel, Container, Component and Object. If you combine all the methods of all these classes, that is what Applet has inherited.
- Chapter 8.3 talks about maintaining a class hierarchy. This is sound advice. Often you will look at the class and forget that it has more to offer. You forget about all the methods it has inherited.
- Creating a hierarchy is also important. You will have to decide how to plan things out. Again, this is something you should do before you start programming.
- If I create a Boy class does it extend Man? Would I have to make some things private instead of protected (e.g. beard).
- What about OldMan class? Where would it go in the hierarchy?
- There is no one good answer for all this.
- Polymorphism; the prefix poly- means "many" and the suffix –morphism means "quality of having XXXX forms." So the entire word means "quality of having many forms."
- HINT: If you come across a word you don’t understand, look in a dictionary. It sometimes gives you a clue, even if the actual word is not there.
- The following is valid Java:
Man me = new Man("Darrell", false);
Human h = me;
- When I see the reference h I know it is a Human and can call any of the methods in the Human class.
- Since me can call all the methods of the Human class, as well as the methods of the Man class, then the assignment of h = me makes sense.
Human h = new Human("Darrell");
Man me = (Man)h;
- Notice that I had to use casting to promote h to the class Man.
- Why would you want to do something like this?
- What if Human had an eat method and Man had an eat method?
Human h = new Human("Darrell");
Man m = new Man("Darrell", false);
Human temp = h;
temp.eat(); // calls the eat method of Human
temp = m;
temp.eat(); // calls the eat method of Man
- So now I can call two different methods with one reference.
- The temp reference is polymorphic.
- Now if a reference could be pointing to different classes, how do we determine which class it is referring to?
- We use the instanceof operator. The syntax of this operator is:
variableName instanceof className
h instanceof Man
- If h refers to an instance of the class Man then this statement is true. Otherwise, this statement is false.
- Where is a good place to use the instanceof operator?
- If I wanted to write a sort method I would write the method to sort instances of Object.
- How do you compare two Objects?
- The answer is to use the instanceof operator to determine what type the Object really refers to.
private boolean isInOrder(Object o1, Object o2) {
if(o1 instanceof Integer) {
// method to compare Integers
} else if(o1 instanceof String) {
// method to compare Strings
} else {
// method to compare everything else
}
}
- How would I compare them if they where Integers?
Integer i1 = (Integer)o1;
Integer i2 = (Integer)o2;
if(i1.intValue() < i2.intValue())
return true;
else
return false;