Last modified: April 03, 2023
In HW 4, you created a MousePlayer whose code was nearly identical to the code from Player, except it was controlled by the mouse instead of the keyboard. Since a MousePlayer has so much in common with the Player, it would be nice if we could focus only on the parts that are different. This is exactly the purpose of subclasses and inheritance. Just like the player class inherits methods and fields from the Actor class, the MousePlayer could also inherit methods and fields from the Player class.
In Java, a class (the "child class", also called the "subclass") can be given the same attributes, methods, and constructors as another class (the "parent class", or the "super class") through inheritance.
Inheritance is achieved using the extends
keyword. For your MousePlayer, you can write something like:
public class MousePlayer extends Player {
// you won't have to rewrite every line of code from Player,
// because "extends" automatically adds every attribute, method, and constructor Player has to MousePlayer!
}
Note: We generally say that only public and protected methods and instance variables are inherited because private methods and instance variables are not accessible from within the subclass. For example, the Actor class has private instance variables x and y, but you cannot directly access them in your Actor subclasses because they are private. However, you can still call the public methods
getX()
andgetY()
and get the values of x and y or call the public setter methodsetLocation(int x, int y)
to set the values of x and y.
To access a public or protected attribute or method declared in the parent class, the child class can directly refer to that particular attribute or method as if it is declared directly in the child class. This is exactly what you have been doing when you called methods declared in the Actor or World classes.
Alternatively, you can use the super
keyword to specify that you are referring to something declared in the parent class.
To illustrate:
System.out.println(someAttribute); // ok
System.out.println(super.someAttribute); // ok
System.out.println(someMethod()); // ok
System.out.println(super.someMethod()); // ok
But what happens when you want to do something different in the child class? In that case, you can simply re-declare the method in the subclass exactly as it is declared in the super class. This is called Method Overriding. You have actually done this every time you declared an act() method because you are overriding the act() method declared in the Actor class.
To override a method inherited from the parent class, a child class just needs to declare the method exactly as it is declared in the parent class. For example:
Lets say you had this superclass
public class Mama {
public void sing() {
System.out.println("Hush little baby don't you cry, Mama's going to sing you a lullaby");
}
}
and this subclass:
public class Son extends Mama {
public void sing() {
System.out.println("Waaa waaaa waaaa");
}
}
If you called sing() on a Mama, it would print "Hush little baby don't you cry, Mama's going to sing you a lullaby", but if you called sing() on a Son, it would print "Waaa waaaa waaaa".
Note: If you were to accidentally write:
public class Son extends Mama {
public void sings() {
System.out.println("Waaa waaaa waaaa");
}
}
Then if you called sing() on a son, it would still print "Hush little baby don't you cry, Mama's going to sing you a lullaby" because it inherited the sing() method from Mama, but instead of overriding it, it made another method with almost, but not quite, the same name. In order to protect against typos like that, it can be useful to declare your intention to override a method by using the @Override
keyword like this:
public class Son extends Mama {
@Override
public void sing() {
System.out.println("Waaa waaaa waaaa");
}
}
The overriden method in the child class must have the exact same method name, access modifier, return type, and parameter type(s) as the method declared in its parent.
Let's rewrite your MousePlayer class to make it more concise using inheritance and overriding.
One way to do so is to override the entire act()
method.
But there's an even more concise way.
In your Player class, your act method might look like:
public void act() {
int direction = getCommand();
// then move your player according to the direction
// while enforcing the movement rules such as avoiding walls
}
Note: the return int of
getCommand()
is used to logically represent an arbitrary direction of movement. For example, 1 can represent moving up, 2 can represent right, etc. Alternatively you could have getCommand() return a String, such as "up", "down", "left", "right"
If your Player class looked like that, then you could make your MousePlayer class extend the Player class and just override the getCommand() method without having to rewrite any other code. All the movement rules are handled in the act() method inherited from the Player class and thus do not need to be rewritten.
Go ahead and modify your MousePlayer according to the above hints. When your submit, your MousePlayer should look something like:
public class MousePlayer extends Player {
@Override
public int getCommand(){
// put your code here
}
}
Now, your MousePlayer should be super short.
Zip your entire project folder and submit it below.
PX_LastName_FirstName_LodeRunner
.PX_LastName_FirstName_LodeRunner.zip
. For example if you were in 3rd period and named Michael Wang, then you would name the file P3_Wang_Michael_LodeRunner.zip
You must Sign In to submit to this assignment