The definition of a class from the last chapter is
An instance of a subclass is partly an instance of the superclass in that it has all the instance variables that the superclass has, and it has all the methods of the superclass. The subclass can replace or extend the methods of the superclass, but it can do nothing about the instance variables. And, as stated before, the subclass can also add instance variables and new methods that the superclass doesn't have.
Let's start building a simple example to explore the ideas of inheritance.
First we will create a class called Pet which will store the name
and age of a particular pet. Pet will be the superclass for all of the
derived classes discussed later in this section.
public class Pet {
public Pet(String n, int a) {
name = n;
age = a;
}
public void describe() {
System.out.println("I have a pet named " + name + ".");
System.out.println(name + " is " + age + " years old.");
}
public void talk() {
System.out.println("Meaningless noise");
}
private String name;
private int age;
}
There is nothing special about this superclass,
it is a class just like any other class, in fact, this is very much like our Person example.
Suppose we run the following code
Pet yogi = new Pet("Yogi", 1);
yogi.talk();
yogi.describe();
Here is the instance of Pet that is created.

And, as expected, the output of the code snippet will be
Meaningless noise I have a pet named Yogi. Yogi is 1 years old.
Nothing new here.
Now let's make a sublcass of Pet called Fish.
public class Fish extends Pet {
public Fish(String n, int a) {
super(n, a);
}
public void talk() {
System.out.println("Glub, glub");
}
}
The keyword extends says that Pet is the superclass
of Fish. Another way to phrase this is that Fish
is a subclass, or a derived class, of Pet.
Suppose we run the following code
Fish fish = new Fish("Eric", 2);
fish.talk();
As expected, the output will be
Glub, glub
Here is the instance of Fish that is created.
Notice that Fish adds no instance variables of its own,
but, as was said above,
it does get all the instance variables from Pet.

Don't worry just yet about what super means in the
constructor for Fish.
Here is another subclass of Pet called Cat.
Notice the use of extends again.
public class Cat extends Pet {
public Cat(String n, int a) {
super(n, a);
}
public void talk() {
System.out.println("Meow");
}
public void sharpenClaws() {
System.out.println("Which couch is next, I wonder???");
}
}
Suppose we run the following code
Cat c = new Cat("Emily", 7);
c.talk();
c.sharpenClaws();
Like Fish,
Cat adds no new instance variables of its own, but it
inherits all the instance variables from Pet.
Here is the instance of Cat created in the code above.

Notice that the class Cat has an extra method called
sharpenClaws() that isn't found in the Pet
class. Cat will have all the methods in
Pet and this new one.
The output of the code fragment above will be
Meow Which couch is next, I wonder???
Still wondering about what the super keyword means in the
constructor for Cat? Soon!
And here is one more class derived from Pet called
Ferret.
public class Ferret extends Pet {
public Ferret(String n, int a) {
super(n, a);
}
private String teeth = "Sharp";
}
Unlike the last two subclasses, Ferret does add an
instance variable of its own called teeth. It still gets
all of the instance variables of Pet, it just adds one of it's
own. Here is a sample instance of Ferret.

Notice that no new methods have been added to Ferret.
Now let's see how method inheritence works. Here is a main driver which creates
instances of our various subclasses and calls methods talk() and describe()
on them.
public static void main(String[] args) {
Cat emily = new Cat("Emily", 1);
Fish eric = new Fish("Eric", 2);
Ferret entropy = new Ferret("Entropy", 5);
emily.talk();
eric.talk();
emily.describe();
entropy.talk();
}
Here is the output from the above code.
Meow Glub, glub I have a pet named Emily. Emily is 1 years old. Meaningless noise.
Let's try and understand what we're seeing.
Our first method call is
emily.talk();
emily is of type Cat. We look in the class definition
for Cat and notice that there is a method called
talk() which has no arguments. So we use the method talk() found in
Cat. It doesn't matter that there is a definition of
talk() in Pet as we found one in
Cat and we use the first one we find. So Emily says
Meow
Now let's look at the next line.
eric.talk();
eric is of type Fish. We look in the class definition
for Fish and notice that there is a method called
talk(). So we use the method talk() found in
Fish. This is the same thing as happend with
emily.talk() except that eric
is an instance of class Fish so we had to start looking in class Fish
for the method. So Eric says
Glub, glub
Now let's look at something a little more involved.
emily.describe();
emily is of class Cat, so we start looking in Cat
for the definition of describe(). We don't find a method
called describe() in Cat. What we now have to do
is look for the method in the superclass for Cat. So we look at the
class definition for Cat to the right of the
extends keyword. We see that the superclass for Cat
is Pet. Since we didn't find describe() in
Cat, we will now have to look for it in Pet since
Pet is the superclass of Cat. This is what method inheritence means.
And sure enough, we find a method called describe() in Pet.
I have a pet named Emily. Emily is 1 years old.
If we hadn't found a describe() in Pet, we would
had to look in its superclass. And if it wasn't in Pets
superclass we'd have to look in that classes superclass and on up the chain.
If we never find such a method and we end up in a class without a superclass
we would have a syntax error.
For instance
emily.scoobyDoo();
would be a syntax error because scoobyDoo() isn't defined either
in class Cat or class Pet. Pet has
no superclass, so we have to stop looking there.
One more example.
entropy.talk();
This works the same way as describe() did when we called it
on emily.
entropy is an instance of class Ferret, so we look in Ferret
for the definition of talk(). There isn't a method
called talk() in Ferret so what we now have to do
is look for the method in the superclass for Ferret. We look at the
class definition for Ferret to the right of the
extends keyword and see that the superclass for Ferret
is Pet. Since we didn't find talk() in
Ferret, we will now have to look for it in Pet since
Pet is the superclass of Ferret. We find a method with the correct
signature and generate the output
Meaningless noise.
When we called emily.talk(), we only used the
method called talk() in Cat even though there was a
method called talk() in Pet. This is because we started
looking for talk() in Cat and we use the
first one we find and ignore any others after that.
Ferret didn't have a method named talk() of its
own, so we had to go look in its superclasses.
We say that the talk() in Cat
overrides the talk() in Pet.
Why is this useful? It means we can put some reasonable default behaviour
in the method in the superclass and use the subclasses a specific behaviour
more appropriate to the subclass. Cat is the subclass
and cats say "meow" when they talk. An argument can be made that
"Meaningless noise" is a reasonable default if we don't know the noise
the pet makes, so that is the one that we put in the superclass.
Inheritance in Java involves a superclass and a subclass, sometimes called a derived class.
The subclass uses the extends keyword in its class definition to say what the superclass is.
Java implements what is called a single-inheritance model. What this means to you is that a subclass in Java can only extend one class.
The superclass of a class might also be a subclass of yet another superclass, you will see an example of this in the next section. We call this the class chain for a class, which is the superclass of the class, the superclass' superclass, and on up until there are no more superclasses.
A class in Java is a collection of instance variables and instance methods. When a class inherits
from a superclass it gets all of the instance variables and all of the instance methods from the superclass, which
will include any instance variables or instance methods from the superclass of the superclass, all the
way up the class chain. You saw an example of this with the class Ferret, which had an instance
variable of its own, but also inherited the instance variables from the class Pet.
Finding out which instance method to call has now been extended. As stated before, there
must be a method with the same number of arguments with the same types in the same order
for Java to know which method to call. It starts by looking for the method in the class
type of the class instance. If it finds the method in that class, that method will be called.
This happened above when we evaluated the statement emily.talk(). If the
class doesn't contain a method which matches the method signature of the method call being made
the search will continue with the class' superclass. If the class doesn't have a superclass, there is a
suntax error because no method could be found. If there is a superclass, its methods will be examined
for one with the proper signtature. We saw an example of this above when we evaluated
entropy.talk(). Its class Ferret did not define talk(), but
its superclass did.
This search will continue up the entire superclass chain until either a matching method is found or there are no more superclasses. If we run out of superclasses and have found no matching method, it is a syntax error.