Tino Intro To Java

Last modified: January 22, 2023

Inheritance

The Greenfoot system is designed to take advantage of a concept that was introduced to you in lesson 1 called inheritance. Inheritance is a core feature of object oriented programming and understanding it is important if you want to really understand what you are doing in Greenfoot. That is because almost all the classes you create in Greenfoot will extend one of the two core classes World or Actor. You need to understand what that means.

Making a subclass

To make a subclass, use the key word extends in the class declaration like this:

public class Rectangle extends Quadrilateral {

}

There are multiple ways to describe the relationship between classes Quadrilateral and Rectangle. Sometimes the relationship will be described as a subclass - superclass relationship and sometimes as a child - parent relationship.

  • Rectangle is a subclass of Quadrilateral.
  • Quadrilateral is the superclass of Rectangle.
  • Rectangle is a child of Quadrilateral.
  • Quadrilateral is the parent of Rectangle.

Thinking of Quadrilateral as the parent and Rectangle as the child is helpful in understanding the inheritance relationship because just like you inherit traits and behaviors from a parent, child classes also inherit from their parent class. The Quadrilateral class would define all the methods and properties common to all quadrilaterals and the Rectangle would modify those behaviors and properties and define new ones as needed.

When a Child class extends a Parent, the Child inherits all the public and protected methods and fields from the Parent. This what makes inheritance so powerful. When writing the Child class, it will automatically have all the features of the Parent class, so the programmer can focus only one what is different about the Child.

Lets walk through an example. In this example, we will create classes to model the users in a chat program. First we will define a User class to represent a normal user.

public class User {
    private String name;

    public User() {
        name = "Anonymous";
    }

    public String getName() {
        return name;
    }

    public void setName(String n) {
        name = n;
    }

    public void sendMessage(String message) {
        System.out.println(name + ": " + message);
    }
}

Next, we will define an Admin class to represent users who have the power to ban other users.

public class Admin extends User {
    public void ban(User user) {
        sendMessage(user.getName() + ", you have been banned!");
    }
}

Notice the Admin class is very short. It inherits the getName, setName, and sendMessage methods so it doesn't need to define those again. The only method it needs to define is ban. Inside the ban method, it calls sendMessage on itself, which it can do because sendMessage is inherited from User.

Constructors and super()

You may have noticed the Admin class does not define any constructors. If a class does not define a constructor, the compiler defines a default constructor automatically as follows:

public Admin() {
        super();
    }
    

The keyword super refers to the superclass of the class you write it in. If you "call" super by putting parentheses after it, then you are calling a constructor of the superclass. Since Admin extends User, then super() is calling the constructor User() which initializes name to "Anonymous" (see the User class above).

It is important to note that subclasses do not inherit constructors, but they are required to call a superclass constructor inside their constructor. If a constructor does not explicity call super(), then super() is called automatically by the compiler. Notice that the automatic call to super() does not pass any parameters, so if the superclass only has constructors that take parameters, then the subclass must call one of those explicity.

Earlier in this lesson, when you made your first Greenfoot program, you were given this code:

public class MyWorld extends World {
    public MyWorld() {    
        super(600, 400, 1); 
        Rocket r = new Rocket();
        addObject(r, 100, 200);  // adds the rocket to the world at x = 100 and y = 200
    }
}

In the MyWorld() constructor, it calls super(600, 400, 1). Since MyWorld extends World, then super(600, 400, 1) corresponds to World(600, 400, 1) which matches the constructor in the World class that takes three int values: World(int worldWidth, int worldHeight, int cellSize). If you were to remove that line from the code, there would be a compiler error because then the compiler would automatically call super() with no parameters, but if you look at the constructors for the World class, there is no constructor that takes no parameters defined. Since there were other constructors that were defined, the default constructor does not automatically get defined.

Dark Mode

Outline