Issues with writing a subclass of the Rectangle class in Java - java

I'm a student working on a project in Java where I need to practice using inheritance by extending the default Rectangle class; the child class MyRectangle needs to have constructors that accept parameters that describe the rectangle's border and fill colors as well as its dimensions. I also need to include getter/setter methods for the border/color attributes, a method that will rotate a rectangle by 180 degrees, and methods to calculate and return the area and perimeter of a rectangle. All of the required methods/fields are described in greater detail in the documentation file:///C:/Users/sweis/Downloads/MyRectangle.html
here, and the output should end up looking like this: https://i.stack.imgur.com/KP7LB.png
I've written some code, but I've gotten a lot of error messages referencing the portion of the program where I actually define the MyRectangle class and set up constructors, including "Non-static variable cannot be referenced from a static context" and "error: cannot find symbol". I'm pretty new at Java so I'm really not sure, but I'm afraid I'm fundamentally misunderstanding something about inheritance, and I'm struggling to resolve these errors on my own. I would really appreciate it if someone could look at what I've written so far and help me understand what I'm doing wrong so I can better understand this concept. Here are the portions that are causing problems:
import java.awt.Rectangle;
class Main {
public static void main(String[] args) {
MyRectangle mr1 = new MyRectangle(0, 0, 4, 2, "blue", "red", true);
MyRectangle mr2 = new MyRectangle(5, 5, 10, 3, "green");
MyRectangle mr3 = new MyRectangle();
System.out.println(mr1 + " " + "area = " + mr1.area() + " perimeter = " + mr1.perimeter());
System.out.println(mr2 + " " + "area = " + mr2.area() + " perimeter = " + mr2.perimeter());
System.out.println(mr3 + " " + "area = " + mr3.area() + " perimeter = " + mr3.perimeter());
System.out.println(mr4 + " " + "area = " + mr4.area() + " perimeter = " + mr4.perimeter());
}
public static class MyRectangle extends Rectangle {
public static int width, height;
public String color, borderColor;
public boolean border;
public MyRectangle() {
super();
}
public MyRectangle(int x, int y, int w, int h, String c) {
width = w;
height = h;
color = c;
}
public MyRectangle(int x, int y, int w, int h, String c, String bc, boolean b) {
borderColor = bc;
border = b;
}
public int area() {
return (width * height);
}
public int perimeter() {
return ((width * 2) + (height * 2));
}
public void setBorder(boolean newBorder) {
border = newBorder;
}
}
}
}
If you have any questions or need me to clarify anything I'll definitely do so. Thank you!

The issue not really with the inheritance here.
Non-static variable cannot be referenced from a static context
As main method is static, it can't access inner non-static class MyRectangle inside it. You have already added static keyword to your MyRectangle class definition so this should fix this issue. You call also move MyRectangle class outside your main class. This would automatically make it static as all "Top level classes are static by default".
There is another issue here, the variables width, height from MyRectangle class are defined as static. This would result in these variables shared across all the different MyRectangle objects that you have created and override each others values. So remove the static keyword from there as they need to be different for each instance.
error: cannot find symbol
Object mr4 is not created but used in the print statements, this would be resulting in cannot find symbol. So just creating this object should fix your issue.
After these fixes your code should look something like:
class Main {
public static void main(String[] args) {
MyRectangle mr1 = new MyRectangle(0, 0, 4, 2, "blue", "red", true);
MyRectangle mr2 = new MyRectangle(5, 5, 10, 3, "green");
MyRectangle mr3 = new MyRectangle();
MyRectangle mr4 = new MyRectangle(); // now mr4 is created
System.out.println(mr1 + " " + "area = " + mr1.area() + " perimeter = " + mr1.perimeter());
System.out.println(mr2 + " " + "area = " + mr2.area() + " perimeter = " + mr2.perimeter());
System.out.println(mr3 + " " + "area = " + mr3.area() + " perimeter = " + mr3.perimeter());
System.out.println(mr4 + " " + "area = " + mr4.area() + " perimeter = " + mr4.perimeter());
}
static class MyRectangle extends Rectangle {
public int width, height; // this should be non static
public String color, borderColor;
public boolean border;
public MyRectangle() {
super();
}
public MyRectangle(int x, int y, int w, int h, String c) {
width = w;
height = h;
color = c;
}
public MyRectangle(int x, int y, int w, int h, String c, String bc, boolean b) {
this(x, y, w, h, c); // this should initialise other args by calling different constructor
borderColor = bc;
border = b;
}
public int area() {
return (width * height);
}
public int perimeter() {
return ((width * 2) + (height * 2));
}
public void setBorder(boolean newBorder) {
border = newBorder;
}
}
}

Related

How to fix "Cannot invoke "java.awt.Point.getX()" because "this.p" is null"

For an inheritance practice assignment, I have a class Square which extends rectangle, and here are the relevant methods:
public class Square extends Rectangle {
private Point p;
private int sideLength;
public Square(Point p, int sideLength){
super(p);
this.sideLength = sideLength;
}
public String toString(){
return getClass().getName() + "\nCenter point: (" + p.getX() + ',' + p.getY() + ") \nSide Length: " + sideLength + " \nArea: " + this.getArea() + " \nPerimeter: " + this.getPerimeter();
}
}
there's also a getArea() and getPerimeter() method but neither of those are causing this issue.
I have a separate class to test this one:
public class SquareTest {
public static void main(String[] args){
ArrayList<Square> squareList = new ArrayList<>();
Point p1 = new Point(1, 1);
Point p2 = new Point(1, 2);
Point p3 = new Point(4, 1);
Point p4 = new Point(2, 3);
Point p5 = new Point(5, 4);
Square one = new Square(p1, 1);
Square two = new Square(p2, 2);
Square three = new Square(p3, 4);
Square four = new Square(p4, 4);
Square five = new Square(p5,5);
squareList.add(one);
squareList.add(two);
squareList.add(three);
squareList.add(four);
squareList.add(five);
for (Square each : squareList){
System.out.println(each.toString());
System.out.println();
}
}
}
What it's supposed to do is print out the toString() result for each of the five square objects, where one square looks like this:
Square
Center point: (1,1)
Side Length: 1
Area: 1
Perimeter: 1
but instead i get the following runtime error:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.awt.Point.getX()" because "this.p" is null
at Square.toString(Square.java:21)
at SquareTest.main(SquareTest.java:23)
I'm confused as to why it thinks this.p is null when I've clearly instantiated five Point objects. Any ideas?
NullPointerException was caused because you haven't initialized the p in Square class. Yu have just passed it to the Rectangle constructor so it is the p in Rectangle class which is getting initialized.
Since you are not using the point object in your Square rather than just passing it to the super class, there is no need to declare a Point object in the Square class. If your Rectangle class has a getter method for Point p then, you could use that in the Square class.
Assuming that Rectangle class has a getter method for p, You could refactor your Square class to :
public class Square extends Rectangle {
private int sideLength;
public Square(Point p, int sideLength){
super(p);
this.sideLength = sideLength;
}
public String toString(){
return getClass().getName()
+ "\nCenter point: (" + getP().getX() + ',' + getP().getY()
+ ") \nSide Length: " + sideLength
+ " \nArea: " + this.getArea()
+ " \nPerimeter: " + this.getPerimeter();
}
}

Most efficient way of using toString() JAVA

I have 2 classes of shapes one is rectangle and the second is circle, both extend "shape" class.
I should print the relevant info from each class for example x, y represent a point which is relevant to all of the shapes and the color as well.
rectangle class has its width and height and circle has a radius.
I'm trying to use toString method in each class by overriding, using super and adding more info but one thing looks strange. should I create a new string builder object for each method? looks quite not right even though it works. Tried looking it up online but so far its either this or using a bunch of string. Am I missing something?
here is what I did in shape class:
public String toString() {
StringBuilder shapeBuilder = new StringBuilder();
System.out.println(shapeBuilder.append("The x axis is: ").append(x).append(" and the y axis is: ").append(y).append(" The color of ")
.append(this.getClass().getSimpleName()).append(" is ").append(color));
return shapeBuilder.toString();
}
rectangle class:
public String toString() {
super.toString();
StringBuilder rectangleBuilder = new StringBuilder();
System.out.println(rectangleBuilder.append("The height of the rectangle is: ").append(height)
.append(" And the width is: ").append(width));
return rectangleBuilder.toString();
}
circle class:
public String toString() {
super.toString();
StringBuilder circleBuilder = new StringBuilder();
System.out.println(circleBuilder.append("the radius of the circle is: ").append(getRadius()));
return circleBuilder.toString();
}
I'm calling them from main using object name.toString();
The obvious problems are
In your Rectangle and Circle class, you called super.toString() and do nothing with the result. There is no reason calling it. Or, I guess what you are trying to do is something like : (e.g. Rectangle )
public String toString() {
return super.toString()
+ " height " + this.height
+ " width " + this.width;
}
In your case, you do not need to explicitly use StringBuilder. Simply
e.g. Shape class
public String toString() {
return "The x axis is: " + x
+ " and the y axis is:" + y
+ " The color of " + this.getClass().getSimpleName()
+ " is " + color;
}
is good enough. Always-use-StringBuilder is not necessary better.
Use System.out.println(super.toString() to print/use super class toString().
Code Below:
public class Shape {
int x;
int y;
#Override
public String toString() {
return "Shape [x=" + x + ", y=" + y + "]";
}
}
public class Rectangle extends Shape{
double width,height;
#Override
public String toString() {
System.out.println(super.toString());
return "Rectangle [width=" + width + ", height=" + height + "]";
}
public static void main(String[] args) {
Rectangle rectangle=new Rectangle();
rectangle.x=10;
rectangle.y=30;
rectangle.width=20;
rectangle.height=100;
System.out.println(rectangle);
}
}

Universal TweenEngine several values at once

I'm interpolating two values at once with TweetEngine (X and Y position), but only X is updated...
Accessor class:
private static class PersonTweenAccessor implements TweenAccessor<Person> {
public static final int POSITION_XY = 1;
#Override
public int getValues(Person target, int tweenType, float[] returnValues) {
switch(tweenType) {
case POSITION_XY:
returnValues[0] = target.position.x;
returnValues[1] = target.position.y;
return 1;
default:
return -1;
}
}
#Override
public void setValues(Person target, int tweenType, float[] newValues) {
switch(tweenType) {
case POSITION_XY:
target.position.set(newValues[0], newValues[1]);
Gdx.app.log("position", newValues[0] + "," + newValues[1]);
break;
}
}
}
Tween creation:
Gdx.app.log("Tween start", "From (" + position.x + "," + position.y + ") to (" + targetPoint.x + "," + targetPoint.y + ")");
Tween.to(this, PersonTweenAccessor.POSITION_XY, distance / speed)
.target(targetPoint.x, targetPoint.y)
.ease(TweenEquations.easeNone)
.setCallback(positionTweenCallback)
.start(GameWorld.tweenManager);
The output (of the log set in the setter) is this (trimmed to improve readability):
Tween start: From (50.0,20.0) to (283,25)
position: 51.305202,20.0
position: 52.14488,20.0
position: 53.2509,20.0
...
position: 280.70465,20.0
position: 281.80902,20.0
position: 282.85034,20.0
position: 283.0,25.0
As you can see, the first value is interpolated but the second is not, until the last access, where is set to its target value.
Your getValues method needs to return 2, not 1, because you have two values that you are modifying.

Null-Pointer Exception Error at toString

The null-pointer exception error occurs in my toString method. I'm at a loss as to why. The error can occur through multiple ways. Most commonly, an object's reference is declared but the object itself remains uncreated. I've declared and created (is initialized the right word?) Mycircle circle1 = new Mycircle (); and Mypoint center = new Mypoint ();
I suspected that I hadn't initialized any of my fields when I invoked my getter methods, but that's not true. The setter methods work cleanly -- I've been successful in inputting values. Doesn't that imply that my getter methods can access some non-null value.
import java.util.Scanner;
public class MyCircle {
private Mypoint center;
private double radius;
Scanner input = new Scanner (System.in);
public MyCircle() {
radius = 0.0;
Mypoint center = new Mypoint ();
System.out.println("Enter coordinates here");
center.setCoordinateX(input.nextDouble());
center.setCoordinateY(input.nextDouble());
}
public String toString(MyCircle object) {
return "Circle # " + "(" + object.center.getCoordinateX() + "," +
object.center.getCoordinateY() + ")" + ". Its radius is " +
object.radius;
}
public double calcArea(MyCircle object) {
double area = Math.pow(object.radius, 2) * Math.PI;
return area;
}
public static void main (String[]args) {
MyCircle circle1 = new MyCircle ();
circle1.radius = 3.0;
System.out.println(circle1.calcArea(circle1));
System.out.println(circle1.toString(circle1));
}
}
class Mypoint {
private double posX;
private double posY;
public void setCoordinateX(double x) {
posX = x;
}
public void setCoordinateY(double y) {
posY = y;
}
public double getCoordinateX() {
return posX;
}
public double getCoordinateY() {
return posY;
}
}
In your MyCircle constructor, you're creating a local variable called center here:
Mypoint center = new Mypoint ();
What you probably want is to initialize the instance member:
center = new Mypoint ();
Your code doesn't make much sense, presumably this
public String toString(MyCircle object)
{
return "Circle # " + "(" + object.center.getCoordinateX() + ","
+ object.center.getCoordinateY() + ")"
+ ". Its radius is " + object.radius;
}
Should be
#Override
public String toString() {
return "Circle # (" + center.getCoordinateX() + ","
+ center.getCoordinateY()
+ "). Its radius is " + radius;
}
Then let's fix your constructor, use this so you know you're updating the instance field (instead of shadowing it) -
public MyCircle() {
this.radius = 0.0;
this.center = new Mypoint(); // <-- this.center
System.out.println("Enter coordinates here");
this.center.setCoordinateX(input.nextDouble());
this.center.setCoordinateY(input.nextDouble());
}
First of all, your toString() method is untypical. You want a Circle#toString() with no argument and produce a print representaton of yourself (i.e. this instead of object=).
Your toString method can fail if:
object is null
object.center is null
object.center.getCoordinateX() or getCoordinateY() itself throws exception.
The later case would be visible in the stacktrace, the other two cases all show the same line number as the cause.
It looks like the second case is your problem (as you fill a local variable and not the field of MyCircle).
BTW: using a input scanner in a constructor is a horrible layering violation. You should seperate input/output/user interaction logic from the geometric (circly, point) classes.
There are many things wrong in your code beside what #Mike pointed out.
Getting input from the user within the constructor is bad. You should get the input in the main method, and pass it to the constructor. In addition, you don't initialize the radius. It remains 0.0.
The constructor call should look like this (the MyPoint object passed to the constructor should be initialized prior to calling the constructor) :
MyCircle circle1 = new MyCircle (center, radius);
The constructor should look like this :
public MyCircle(MyPoint center, double radius)
{
this.radius = 0.0;
this.center = center;
}
The toString and calcArea methods don't need a parameter. They should operate on the current object (this) :
public String toString()
{
return "Circle # " + "(" + this.center.getCoordinateX() + "," + this.center.getCoordinateY() + ")" + ". Its radius is " + this.radius;
}

toString() and accessors

public class Fan {
public static void main(String[] args){
Fan fan1 = new Fan();
fan1.setSpeed(FAST);
fan1.setRadius(10);
fan1.setColor("yellow");
fan1.setOn(true);
System.out.println(fan1.toString());
}
// fan speed variables
final static int SLOW = 1;
final static int MEDIUM = 2;
final static int FAST = 3;
// Other fan variables
private int speed;
private boolean on; // true means on
private double radius; // radius of fan
String color;
// No-arg constructor
public void Fan(){
speed = SLOW;
on = false;
radius = 5;
color = "blue";
}
// Mutator methods
public void setSpeed(int newSpeed){
if(newSpeed < 0)
System.out.println("Illegal speed!");
else
speed = newSpeed;
}
public void setOn(boolean newOn){
on = newOn;
}
public void setRadius(int newRadius){
if(newRadius < 0)
System.out.println("Illegal radius!");
else
radius = newRadius;
}
public void setColor(String newColor){
color = newColor;
}
// Accessor methods
public int getSpeed(){
return speed;
}
public boolean getOn(){
return on;
}
public double getRadius(){
return radius;
}
public String getColor(){
return color;
}
// toString method to output Fan data
public String toString(){
if(on = false)
return "Fan is off.";
else
return "Fan Properties:\n" + "Fan speed: " + speed + "\n"
+ "Color: " + color + "\n"
+ "Radius: " + radius + "\n";
}
}
The above piece of code is simple but I was wondering how the toString method uses the on variable even though I didn't supply parameters for that method. Also, why do we not need to invoke get methods in the main class and only need to invoke the set methods? (please explain how each method invokes one another until the final output)
Thanks a lot!
As far as you are in this class body you can access everything (except for static can not access non-static). That means that you can easily set and get variables like that:
var = <value>;
System.out.println(var);
However nobody stops you from using the accessor methods - getter and setters. It is just not required.
One final note:
if(on = false)
This will always fail - it does assignment to false and then checks the newly assigned value (which is false). You need to check for equality here. Like that:
if(on == false)
Or even better:
if(!on)
I just copied-pasted your code into a new file and compiled it. It compiled and ran. The output was
$ java Fan
Fan Properties:
Fan speed: 3
Color: yellow
Radius: 10.0
This is because the comparison in your toString method is wrong. It should be as following:
public String toString(){
if(on)
return "Fan Properties:\n" + "Fan speed: " + speed + "\n"
+ "Color: " + color + "\n"
+ "Radius: " + radius + "\n";
else
return "Fan is off.";
}

Categories