while trying to get a grasp of polymorphism and inheritance, I made a small program to demonstrate these topics. The program consists of a superclass 'Tree' and three subclasses 'Birch', 'Maple', and 'Oak'. Tree's constructor makes it so that all trees start off with a height of 20 and 200 leaves. In Tree I have an abstract method called grow().
Here's the code for Tree:
public abstract class Tree {
private int height;
private int numberOfLeaves;
public Tree()
{
height = 20;
numberOfLeaves = 200;
}
public Tree(int aheight, int anum)
{
height = aheight;
numberOfLeaves = anum;
}
public int getHeight()
{
return height;
}
public int getNumberOfLeaves()
{
return numberOfLeaves;
}
public void setNumberOfLeaves(int anum)
{
numberOfLeaves = anum;
}
public abstract String getType();
public void setHeight(int aheight)
{
height = aheight;
}
public abstract void grow();
}
Here's the code in Birch for grow().
public void grow()
{
int height = super.getHeight();
super.setHeight(height++);
int num = super.getNumberOfLeaves();
super.setNumberOfLeaves(num+=30);
System.out.println("The Birch is Growing...");
}
However, when I call code to make an array of trees grow, none of their heights or number of leaves change.
Here's the code I used to populate the array of trees (I did it manually):
ArrayList<Tree> treeArray = new ArrayList<Tree>();
treeArray.add( new Oak());
treeArray.add(new Birch());
treeArray.add(new Maple());
And Here's the code I used to call grow:
for (Tree tree : treeArray)
{
tree.grow();
System.out.println("The " + tree.getType() + "'s height is " + tree.getHeight() + " and it's number of leaves is "+ tree.getNumberOfLeaves() +".");
}
Clearly, the values in the superclass aren't being modified. Any help will be appreciated! Thanks!
Change your code to :
int height = super.getHeight();
super.setHeight(++height);
note that you don't need to call super.method(). as long as the method is protected (public even better) you can just simplify it to :
int height = getHeight();
setHeight(++height);
You only call super. if you implement the method again in your child class and want to specifically call the parent class, which usually can be seen in constructor calling parent constructor.
One more thing : your accessor need to be changed a bit just for pre-caution case. see code below. Usually your IDE should support auto generation of accessor.
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
This code:
int height = super.getHeight();
super.setHeight(height++);
isn't going to change anything, because the increment of height will occur after the call to super.setHeight(). So you're just setting the height to its current value.
Related
I have written the instructions below and till now, I've came up with having two parameters and letting the method to assign the value and retrieving it. However, one of the instruction I had to follow was to include one constructor with no parameters, so I'm wondering what statement should I make inside the constructor without any parameters. It would be wonderful if anyone gives be a instruction. This is the code I've came up so far.
public class Rectangle {
//first constructor no parameters
//public<class name> (<parameters>)<statements>}
//two parameters one for length, one for width
//member variables store the length and the width
//member methods assign and retrieve the length and width
//returning the area and perimeter
static int recPerimeter(int l, int w) {
return 2*(l+w);
}
static int recArea(int l, int w) {
return l*w;
}
public static void main(String[] args) {
int p = recPerimeter(5, 3);
System.out.println("Perimeter of the rectangle : " + p);
int a = recArea(5,3);
System.out.println("Area of the rectangle : " + a);
}
}
First off, I would take some time to read the java tutorials. At least the "Covering the Basics"
There is a ton wrong with your example. You should store the the attributes of a rectangle - width and length as data members of the class which will get initialized with values through the constructors. If a default constructor is called with no values, then set the attributes to whatever you want. I set them to zero in the example.
Also, you need to normally create an instance of your class and then access it. Big red flag if you are having to prepend "static" to everything.
public class Rectangle {
private int recLength;
private int recWidth;
public Rectangle() {
recLength = 0;
recWidth = 0;
}
public Rectangle( int l, int w ) {
recLength = l;
recWidth = w;
}
public int calcPerimeter() {
return 2*(recLength+recWidth);
}
public int calcArea() {
return recLength*recWidth;
}
public static void main (String [] args) {
Rectangle rec = new Rectangle(5,3);
System.out.println("Perimeter = "+ rec.calcPerimeter());
System.out.println("area = " + rec.calcArea());
}
}
Say I have a method in a class that carries out movement (call it move(Earth)). The function is implemented in another class using inheritance and such like this:
animal.move(Earth)
Is it possible to randomize the actual implementation without messing with the function method?
public void rMove(Earth myEarth) throws InterruptedException
{
int x = (int) location.getX();
int y = (int) location.getY();
int xMax = myEarth.getX() - 1;
int yMax = myEarth.getY() - 1;
double w = Math.random();
int rMove = (int) (w + Math.random()*4);
switch(rMove)
{
case NOR:
location.setLocation(x,y-1);
break;
case SOU:
location.setLocation(x,y+1);
break;
case EAS:
location.setLocation(x+1,y);
break;
case WES:
location.setLocation(x-1,y);
break;
}
}
The class containing this method is extended into another class
public class Carnivore extends Animal
Within the class carnivore, the animal moves using the above function like this:
super.rMove(myEarth);
There's a whole bunch of other code involving the movement but I don't think it's relevant. My question is how to modify the above implementation without modifying the actual rMove.
I would look at having a separate method for the randomisation logic that can be overridden by the subclasses of Animal. I'm not a Java developer so the syntax might not be completely correct, but this gives you an idea. For example:
public abstract class Animal
{
public abstract int moveRandom();
}
public class Carnivore extends Animal
{
public int moveRandom() {
double w = Math.random();
int rMove = (int) (w + Math.random()*4);
return rMove;
}
}
public void rMove() {
int rMove = this.rMove();
}
I am currently trying to create a class that prints out a rectangle with a height and width 1. I have the program set up (there is a template we are supposed to use) and I incorporated all of the steps. However there is one problem with the return statement on the line "SimpleRectangle(){" it says it is missing a return statement but no matter what I return it still comes up with an error.
public static void main (String[] args){
SimpleRectangle rectangle1=new SimpleRectangle();
System.out.println("The area of radius "+rectangle1.perimeter+" is "+rectangle1.getArea());
}
double height;
double width;
SimpleRectangle(){
height=1;
width=1;
}
double getArea(){
return height*width;
}
double getPerimeter(){
return length+length+width+width;
}
}
This looks like a constructor for a class called SimpleRectange
SimpleRectangle(){
height=1;
width=1;
}
In the code you provide there doesn't seem to be such a class. Make sure your code is included in a class with that name and that it has all the fields you are accessing e.g.
public class SimpleRectangle {
double height;
double width;
double perimeter;
double length;
public static void main(String[] args) {
...
...
}
If your code is in a class with any other name you will get "Invalid method declaration. Return type required"
rectangle1.perimeter is not working because there is no field defined with that name, instead you have a method , therefore you need to call it
this is wrong, you need to do rectangle1.getPerimeter()
rectangle1.perimeter should be rectangle1.getPerimeter()
also you dont have a field called length. it's called height
double getPerimeter(){
return height+height+width+width;
}
the consturctor need to be public
public SimpleRectangle(){
height=1;
width=1;
}
You have several issues with your code it is not compiling
The current error is related to missing class definition, but there will be others.......
Try to not copy and past but to understand what you where missing, class definition, no field declaration for length, wrong call to method ecc.
I have included some public and private declaration I suggest that you study some also what this means...
AND NR 1 TRY TO USE AND IDE AS ECLIPSE, THIS WILL HELP YOU ENORMOUSLY AVOIDING AL OF THESE PROBLEMS AND WHEN YOU LEARN TO DEBUG YOU BECOME A PROGRAMMER., no need for SO, for debugging problems
public class SimpleRectangle {
private double height;
private double width;
public SimpleRectangle() {
this.height = 1;
this.width = 1;
}
public double getArea() {
return height * width;
}
public double getPerimeter() {
return height + height + width + width;
}
public static void main(String[] args) {
SimpleRectangle rectangle1 = new SimpleRectangle();
System.out.println("The area of radius " + rectangle1.getPerimeter() + " is " + rectangle1.getArea());
}
}
In order to use rectangle1.getPerimeter() or rectangle1.getArea(), you need to create a class that looks something like this:
public class SimpleRectangle {
double height;
double width;
SimpleRectangle() {
height = 1;
width = 1;
}
double getArea() {
return height * width;
}
double getPerimeter() {
return 2 * (height + width);
}
}
Then you need to create the object (as shown below) before you can use rectangle1.getPerimeter():
public class MainClass {
public static void main (String[] args) {
SimpleRectangle rectangle1 = new SimpleRectangle();
System.out.println("The area of radius " + rectangle1.getPerimeter() + " is " + rectangle1.getArea());
}
}
I have test case that does something like this
TestSquare.java
public void testEncaps() {
Shifting shift = new Shifting(150,260);
Square s = new Square(new Point(101,201),130,140,shift);
Point p = s.getMidPoint();
p.x = 215;
p.y = 315;
assertEquals(new Point(101,201),s.getMidPoint());
}
So on the last line, the s.getMidPoint() don't equal to the Point(101, 201) but instead gets overridden with 215,315. Here is my constructor code and get method.
Square.java
public Square(Point newP, int width, int height, Shift newS) {
this.newMidPoint = newP;
this.newWidth = width;
this.newHeight = height;
this.newShift= newS;
}
public Point getMidPoint() {
return newMidPoint;
}
So, s.getMidPoint() shouldn't be replaced with the Point object. What am I doing wrong?
This two codes are in different class. So there is no main method in Square.java
If you don't want another class to be able to edit Square's middle, return a new Point:
public Point getMidPoint() {
return new Point(newMidPoint);
}
Then your test will run green.
I am trying to return two numbers from this method. I thought this was correct. Where am I going wrong?
public int[] getDimension() {
int shapeWidth = 0;
int shapeHeight = 0;
// .....
int[] result = new int[] {shapeWidth, shapeHeight};
return result;
}
And then at a calling site, is this correct?
public int getWidth() {
return getDimension()[0];
}
I am asking because I believe there's a bug but I don't see it.
That's fine. Short but complete program to demonstrate it working:
public class Test {
public static void main(String args[]) {
int width = getDimension()[0];
System.out.println(width);
}
public static int[] getDimension() {
int shapeWidth = 5;
int shapeHeight = 10;
int[] result = new int[] {shapeWidth, shapeHeight};
return result;
}
}
You can make the result declaration line slightly simpler, by the way:
int[] result = {shapeWidth, shapeHeight};
Rather than using an array, I would recommend using a class
class Dimensions {
private int width;
private int height;
public Dimensions(int width, int height) {
this.width = width;
this.height = height;
}
// add either setters and getters
// or better yet, functionality methods instead
}
This will give you compile time referential integrity, which is much better than inferring based on "we know index 0 is width and index 1 is height".
If you still want to use an array, Jon's answer is spot on.
Your code looks fine, but try not to use an array if you only need a pair.
Since Java doesn't have tuples/pairs you have to implement them, but it's pretty easy. Refer to this question for a possible implementation.
public class Test {
public static void main(String args[]) {
int width = getDimension().getLeft();
System.out.println(width);
}
public static Pair<Integer, Integer> getDimension() {
int shapeWidth = 5;
int shapeHeight = 10;
return new Pair<Integer, Integer>(shapeWidth, shapeHeight);
}
}
This is better than a Dimension class, because you can use it everywhere in your code.