New to Java: SuperClass and SubClass - java

I am fairly new to Java and I am learning about Inheritance. I am trying to create a subclass called BetterRectangle under the superclass Rec1.
Rec 1 gets the x and y coordinates (location) and also gets the width and height (size) of the rectangle. BetterRectangle calculates the perimeter and area of the rectangle.
I get errors in the main method. It cannot find any of the symbols (i.e. cannot find rec1.getHeight(20) symbol).
public class Rec1 {
private double x;
private double y;
private double width;
private double height;
public void setLocation(double xCord, double yCord) {
x = xCord;
y = yCord;
}
public void setSize(double h, double w) {
height = h;
width = w;
}
public double getHeight(double h) {
return height;
}
public double getWidth(double w) {
return width;
}
}
public class BetterRectangle extends Rectangle {
public BetterRectangle(int x, int y, int width, int height) {
super(x, y, width, height);
super.setLocation(x, y);
super.setSize(width, height);
}
public double calcPerimeter() {
return super.getHeight() * 2 + super.getWidth() * 2;
}
public double calcArea() {
return super.getHeight() * super.getWidth();
}
}

Look closely:
Rectangle Rec1 = new Rectangle();
Rec1.getHeight(20);
The type of Rec1 is Rectangle. But the Rectangle class doesn't have a getHeight method. Maybe you wanted this:
Rec1 rec1 = new Rectangle();
rec1.getHeight(20);
Notice that I renamed the variable to rec1, and changed its type.

class BetterRectangle is extending Rectangle in your sample code. So here BetterRectangle would be child and Rectangle would be parent. Now BetterRectangle uses super keyword to access getHeight,getWidth etc...functions. since these functions are not present in Rectangle class it is giving compilation Error.
Instead of extending Rectangle class extend Rec1 class in BetterRectangle and then run the main Class Rectangle. This should work.

Look carefully here
Rectangle BetterRectangle = new Rectangle();
Rectangle Rec1 = new Rectangle();
You are declaring variables of type Rectangle instead of your own classes. I can't see your import statements but you are likely creating types of java.awt.rectangle. You're mixing up variable types and variable names. When creating instances of your own classes it should look like this:
Rec1 mySimpleRec = new Rec1();
BetterRectangle myBetterRec = new BetterRectangle()
When declaring things put them in this order "Type variableName = new Type()" or "Class variableName = new Class()".

Related

Override inherited method with different amount of parameters

There are two tasks to solve:
First a class rectangle should be inherited from the class GeoObjects.
Second a class square should be inherited from the class rectangle.
The abstract class GeoObjects was given.
abstract class GeoObjects{
public abstract double Perimeter();
public abstract double Surface();
public static void main (String [] argv){
double width = 4.0, height = 5.0, side= 3.0;
GeoObject rectangle = new Rectangle (width, height);
GeoObject square= new Square(side);
System.out.println ("Perimeter = " + rectangle.Perimeter());
System.out.println ("Surface= " + rectangle.Surface());
System.out.println ("Perimeter= " + square.Perimeter());
System.out.println ("Surface= " + square.Surface());
}
}
class Rectangle extends GeoObjects{
double width, height, side;
Rectangle (double width, double height){
this.width = width;
this.height= height;
}
public double Perimeter (){
return 2*(width+ height);
}
public double Surface(){
return width* height;
}
}
class Square extends Rectangle {
double side;
Square (double side){
this.side= side;
}
public double Perimeter (){
return 4*side;
}
public double Surface(){
return side*side;
}
}
I get the compiler information that the Square constructor has a different amount of variables than the one from Rectangle.
How can i solve this without hurting the requirement that Square has to be inherited from rectangle and not GeoObjects?
The compiler error message is informing you that you're attempting to call the superclass constructor in Rectangle with a different number of parameters than what the constructor has. You are not explicitly calling a superclass constructor in Square, so the compiler has inserted a call to the default superclass constructor in Rectangle -- effectively super(); as the first line in Square().
But there is no constructor in Rectangle with no parameters; there is only one with 2 parameters. Call it appropriately, by passing side to super() twice.
You'll also notice that the Perimeter and Surface methods no longer need to be overridden, because they will now use the proper values from the superclass.
Also, normal Java method naming conventions would have you name those methods starting with a lowercase character: perimeter and surface.
To fix your Square class you will need to use super(side, side) to call the constructor from Rectangle. You will no longer need the side class variable inside of Square, it can be simplified to just this:
Square:
class Square extends Rectangle {
Square (double side){
super(side,side);
}
}
Rectangle:
class Rectangle extends GeoObjects{
double width, height;
Rectangle (double width, double height){
this.width = width;
this.height= height;
}
public double Perimeter (){
return 2*(width+ height);
}
public double Surface(){
return width* height;
}
}
If you want to overload the methods in Rectangle or place methods that implement specific functions to square, you need to use the width and height variables instead of side.

Writing an XYRectangle Class in Java

I have the following class to write:
Write a class named XYRectangle_LastName, where LastName is replaced with your last name.. The XYRectangle_LastName class should have the following fields:
An XYPoint named TopLeft. This stores the location of the topleft corner of a Rectangle.
A double named Length. This stores the length of the rectangle.
A double named Width. This stores the width of the rectangle.
The XYRectangle class should have the following methods:
A no-argument constructor that randomly determines the top left corner of the rectangle. The values for x and y should be between -10 and 10. Also, it chooses a random width and length for the rectangle with values between 5 and 10.
A 3 argument constructor that takes an XYPoint for the top left corner, a length, and a width.
A get method for length, width, topLeft, topRight, bottomLeft, and bottomRight
A set method for length, width, and topLeft
A boolean method named isInside that takes an XYPoint and determines if it is inside this rectangle.
A method named reflectX that returns a rectangle that has been reflected over the x-axis.
A method named reflectY that returns a rectangle that has been reflected over the y-axis.
This is the code I have so far:
public class XYRectangle {
private XYPoint topLeft;
private double length;
private double width;
public XYRectangle() {
Random rnd = new Random();
int x = (rnd.nextInt(21) - 10);
int y = (rnd.nextInt(21) -10);
XYPoint topLeft = new XYPoint(x, y);
int width = (rnd.nextInt(5) + 5);
int height = (rnd.nextInt(5) + 5);
}
public XYRectangle(XYPoint topLeft, double length, double width) {
this.topLeft = topLeft;
this.length = length;
this.width = width;
}
public double getLength() { return this.length; }
public void setLength(double length) { this.length = length; }
public double getWidth() { return this.width; }
public void setWidth(double width) { this.width = width; }
public XYPoint getTopLeft() { return this.topLeft; }
public void setTopLeft(XYPoint topLeft) { this.topLeft = topLeft; }
I'm having trouble with the topRight, bottomLeft, and bottomRight get methods and the reflect methods. I'm not even sure if the code I've written so far is write. Could anyone help and tell me how to proceed and if I've been doing something wrong?
You don't have the information about topRight, bottomLeft, and bottomRight, but having the topLeft corner and the width, length, it totally defines the other points:
topRight = new XYPoint(topLeft.getX() + length, topLeft.getY());
bottomRight = new XYPoint(topLeft.getX() + length, topLeft.getY() + width);
bottomLeft = new XYPoint(topLeft.getX(), topLeft.getY() + width);
You can decide to store this information when you construct your object or to calculate it each time the get method is called.
About the empty constructor, you are calling it "corner" when it should be called:
public XYRectangle(){
//code here
}
Usually when we override constructors we call the base constructor like this:
public XYRectangle(){
Random rnd = new Random();
int x = (rnd.nextInt(21) - 10);
int y = (rnd.nextInt(21) -10);
XYPoint topLeft = new XYPoint(x, y);
int width = (rnd.nextInt(5) + 5);
int height = (rnd.nextInt(5) + 5);
this(topLeft, width, height)
}
I hope you can figure out the reflection methods yourself. ;)

Java: No compile errors, but my output is wrong

My assignment was to create a class named MyRectangle to represent rectangles.
The required data fields are width, height, and color. Use double data type for width and height, and a String for color. Then Write a program to test the class MyRectangle. In the client program, create two MyRectangle objects. Assign a width and height to each of the two objects. Assign the first object the color red, and the second, yellow. Display all properties of both objects including their area.
I've written everything out and am getting no errors, but my output stays the same no matter what values I put in for the rectangles.
package MyRectangle;
public class MyRectangle{
private double width = 1.0;
private double height = 1.0;
private static String color = "black";
public MyRectangle(double par, double par1){
width ++;
height ++;
}
//Parameters for width, height, and color //
public MyRectangle(double widthParam, double heightParam, String colorParam){
width = widthParam;
height = heightParam;
color = colorParam;
width ++;
height ++;
}
// Accessor width //
public double getWidth(){
return width;
}
public void setWidth(double widthParam){
width = (widthParam >= 0) ? widthParam: 0;
}
// Accessor height //
public double getHeight(){
return height;
}
public void setHeight(double heightParam){
height = (heightParam >= 0) ? heightParam: 0;
}
// Accessor color //
public static String getColor(){
return color;
}
public static void setColor(String colorParam){
color = colorParam;
}
// Accessor area //
public double findArea(){
return width * height;
}
}
class MyRectangleTest {
#SuppressWarnings("static-access")
public static void main(String args[]) {
// Create triangle and set color value to red //
MyRectangle r1 = new MyRectangle(5.0, 25.0);
r1.setColor("Red");
System.out.println(r1);
System.out.println("The area of rectangle one is: " + r1.findArea());
// Create triangle and set color value to yellow //
MyRectangle r2 = new MyRectangle(3.0, 9.0);
r2.setColor("Yellow");
System.out.println(r2);
System.out.println("The area of rectangle one is: " + r2.findArea());
}
}
The constructor you are using makes no sense.
You ignore the passed rectangle dimensions, so you'll always get a 2 by 2 rectangle:
private double width = 1.0;
private double height = 1.0;
...
public MyRectangle(double par, double par1){
width ++;
height ++;
}
It should be something like :
public MyRectangle(double width, double height){
this.width = width;
this.height = height;
}
In addition, the color member shouldn't be static, unless you want all your rectangles to have the same color.
One last thing - in order for System.out.println(r1); and System.out.println(r2); to Display all properties of both objects, you must override toString():
#Override
public String toString()
{
return "width = " + width + " height = " + height + " color = " + color;
}
There are a couple of things wrong here:
The color member is static, which means in belongs to the class, instead of each instance having its own.
The (double, double) constructor doesn't store the height and the width.
Both constructors increment the height and the width, for no good reason.
Since you don't have a default constructor, the default values for the members are redundant - there's no flow where they won't be overwritten.
To sum it up, your class should be declared more or less like this:
public class MyRectangle {
private double width;
private double height;
private String color;
private static final String DEFAULT_COLOR = "black";
public MyRectangle(double width, double height) {
this (width, height, DEFAULT_COLOR);
}
public MyRectangle(double width, double height, String color) {
this.width = width;
this.height = height;
this.color = color;
}
// Rest of the required methods
}

Error using Java Classes/Inheritence

I'm having trouble with fixing this error. Can someone please help? My prompt and the code is posted below.
Write a super class encapsulating a rectangle. A rectangle has two attributes representing the width and the height of the rectangle. It has methods returning the perimeter and the area of the rectangle. This class has a subclass, encapsulating a parallelepiped, or box. A parallelepiped has a rectangle as its base, and another attribute, its length. It has two methods that calculate and return its area and volume. You also need to include a client class to test these two classes.
public class Rectangle1
{
protected double width;
protected double height;
public Rectangle1(double width, double height){
this.width = width;
this.height = height;
}
public double getWidth(){
return width;
}
public void setWidth(double width) {
this.width = width;
}
public double getHeight(){
return height;
}
public void setHeight(double height){
this.height = height;
}
public double getArea(){
return width * height;
}
public double getPerimeter(){
return 2 * (width + height);
}
}
public class Box extends Rectangle1 {
protected double length;
public Box(double length){
this.length = length;
}
public double getLength(){
return length;
}
public void setLength(double length){
this.length = length;
}
public double getVolume(){
return width * height * length;
}
}
public class TestRectangle {
public static void main(String[] args) {
Rectangle1 rectangle = new Rectangle1(2,4);
Box box = new Box(5);
System.out.println("\nA rectangle " + rectangle.toString());
System.out.println("The area is " + rectangle.getArea());
System.out.println("The perimeter is " +rectangle.getPerimeter());
System.out.println("The volume is " + box.getVolume());
}
}
The error is at
public Box(double length){
this.length = length;
}
The error message in Eclipse IDE is as follows:
Implicit super constructor Rectangle1() is undefined. Must explicitly invoke another constructor.
And when I try to run it, it gives me:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Implicit super constructor Rectangle1() is undefined. Must explicitly invoke another constructor
at Box.<init>(Box.java:4)
at TestRectangle.main(TestRectangle.java:7)
Can someone please advise me on how to fix this error?
Your base class Rectangle1 has a constructor:
public Rectangle1(double width, double height) {
this.width = width;
this.height = height;
}
Because you wrote a constructor, the default no aruments constructor will not exist, so super() will not find the right constructor. You should write: super(0, 0) in your Box constructor, which will match Rectangle1 constructor.
Firstly, every subclass must call super(...) as the first statement in every constructor. This is a bit of a pain, so Java adds a call to super() at the start of any constructor that doesn't have a call to super(...). Since Rectangle1 doesn't have a constructor with no arguments, Java's attempt to call super() doesn't work and you need to add your own. Peter and Maroun covered this.
A bigger problem is that you haven't thought about what a Box is. What is a Box(5)? A Rectangle1 has a width and a height, while a Box has a width, a height and a depth. What is shape is a Box(5)? Your Box constructor should be something like
public Box (double width, double height, double depth)
{
super (width, height);
this.depth = depth;
}
In this constructor you can see that the arguments tell you everything you need to know about the Box and the call to super(height, width) takes care of delegating all the rectangle stuff to the base class.
You have to call the super class constructor which you define. The default constructor only exists when you haven't defined one.
Also you should not attempt to initialise fields which are initialised by the parent as this breaks encapsulation. I suggest you do this.
public Box(double length){
super(length, length);
}
This way you are calling a constructor in the super class you have defined and you let it set the fields it is responsible for.

Java - making Triangle class

I need to make a Class named "TriangleShape" which impliments java.awt.Shape.
Now another Class "TriangleComponent" should have an object of TriangleShape class and it should draw a triangle, with the given length of sides.
I managed to create it, but i've read that the triangle should be drawn in the following way:
TriangleShape t = new TriangleShape(30,40,50);
g2.draw(t); //This is the Graphics2D object that I use in paintComponent
The following is the code that I created, but it uses Line2D to create a triangle.
It is the TriangleShape class, assume that I have implimented all the methods of the Shape Class.
public class TriangleShape implements java.awt.Shape{
private double a, b, c;
private int x,y;
private Point2D loc;
public TriangleShape() {
this.a=0;
this.b=0;
this.c=0;
}
public TriangleShape(double a, double b, double c) {
//if supplied dimensions form a valid Triangle
if ( this.isValid(a,b,c) ) {
this.a = a;
this.b = b;
this.c = c;
}
//Otherwise make it zero sized triangle
else{
this.a=0;
this.b=0;
this.c=0;
}
}
public void resize(double a, double b, double c) {
if ( this.isValid(a,b,c) ) {
this.a = a;
this.b = b;
this.c = c;
}
//else let size remain unchanged
}
public TriangleShape getRandomTriangle() {
TriangleShape t = new TriangleShape(5,8,9);
return t;
}
public double area(){
double area, s;
s = (a+b+c)/2;
area = Math.sqrt(s *(s-a) * (s-b) * (s-c));
return area;
}
private boolean isValid(double a, double b, double c) {
double s = (a+b+c)/2;
if ( ((s-a) * (s-b) * (s-c)) <= 0 )
return false;
else
return true;
}
public double perimeter() {
double p;
p = a+b+c;
return p;
}
public double getA(){
return a;
}
public double getB(){
return b;
}
public double getC(){
return c;
}
public void setLocation(Point2D location){
loc = location;
}
public Point2D getLocation(){
return loc;
}
public double getX(){
return loc.getX();
}
public double getY(){
return loc.getY();
}
And the TriangleComponent class:
public class TriangleComponent extends JComponent{
TriangleShape t;
double alpha, beta, gamma;
double a,b,c;
double X,Y;
#Override
protected void paintComponent(Graphics g) {
//super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
t = new TriangleShape(100,100,190);
t.setLocation(new Point2D.Double(100,500));
a = t.getA();
b = t.getB();
c = t.getC();
X = t.getX();
Y = t.getY();
///////////////Drawing Base line.....
g2.draw(new Line2D.Double(X,Y,(X+c),Y)); //line c...
g2.draw(new Line2D.Double((X+c), Y, ((X+c)+a*Math.cos(Math.PI+getBeta())), (Y+a*Math.sin(Math.PI+getBeta())))); //line a...
//JOIning the last end points
g2.draw(new Line2D.Double(X, Y, ((X+c)+a*Math.cos(Math.PI+getBeta())), (Y+a*Math.sin(Math.PI+getBeta()))));
System.out.println("X1 = "+X+" Y1 = "+Y);
System.out.println("X2 = "+(X+c)+" Y2 = "+Y);
System.out.println("X3 = "+((X+c)+a*Math.cos(Math.PI+getBeta()))+" Y3 = "+ (Y+a*Math.sin(Math.PI+getBeta())));
//System.out.println("Alpha = "+getAlpha());
System.out.println("Gamma = "+(getGamma()*180)/Math.PI);
}
public double getAlpha(){
double temp = Math.acos(((Math.pow(c, 2)+Math.pow(b, 2))-Math.pow(a, 2))/(2*b*c));
System.out.println("Alpha = "+temp+" Degrees");
return temp;
}
public double getBeta(){
double temp = Math.acos(((Math.pow(c, 2)+Math.pow(a, 2))-Math.pow(b, 2))/(2*a*c));
System.out.println("Beta = "+temp+" Degrees");
return (temp);// * Math.PI)/180;
}
public double getGamma(){
double temp = Math.acos(((Math.pow(a, 2)+Math.pow(b, 2))-Math.pow(c, 2))/(2*b*a));
System.out.println("Gamma = "+temp+" Degrees");
return (temp);// * Math.PI)/180;
}
}
This works, but I need a way to draw the triangle without relying on Graphics2D or drawing it directly with the paintComponent method. Is there a way to do this?
According to the JavaDoc of the Graphics2D class Shapes are rendered according to the following principle:
Shape operations
If the operation is a draw(Shape) operation, then the createStrokedShape method on the current Stroke attribute in the Graphics2D context is used to construct a new Shape object that contains the outline of the specified Shape.
The Shape is transformed from user space to device space using the current Transform in the Graphics2D context.
The outline of the Shape is extracted using the getPathIterator method of Shape, which returns a PathIterator object that iterates along the boundary of the Shape.
If the Graphics2D object cannot handle the curved segments that the PathIterator object returns then it can call the alternate getPathIterator method of Shape, which flattens the Shape.
The current Paint in the Graphics2D context is queried for a PaintContext, which specifies the colors to render in device space.
In short, this means that the Graphics2D.draw(Shape) method will call your TraingleShape.getPathIterator(AffineTransform) method and use the returned PathIterator object in order to find which points to draw lines between.
As such, you will likely be required to implement your own PathIterator implementation that corresponds to your TriangleShape implementation.
The above solution may however be more complex then it needs to be. An alternative would be to look into the Path2D class which allows you to easily specify arbitrary shapes using simple operations such as lineTo(x,y). Since this class implements the Shape interface you could allow your TriangleShape class to extend this class, or just delegate to it. Here is an example of using the GeneralPath class, which works in a similar way to Path2D:
http://www.roseindia.net/java/example/java/swing/graphics2D/general-path.shtml
It does however depend on your particular assignment whether this would be an acceptable solution or not.

Categories

Resources