Override inherited method with different amount of parameters - java

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.

Related

Accessing parent class's original method after overriding it in subclass #Solved

Edit: I was still sleepy from getting up and just didn't pay atttention as to how I called the methods in the main class. Everything actually works, thanks
I have a Circle Class with a getArea Method
public class Circle {
private double radius;
public Circle(double radius){
radius = (( radius < 0 )) ? 0 : radius;
this.radius=radius;
}
public double getRadius() {
return radius;
}
public double getArea() {
return (radius*radius*Math.PI);
}
}
Additionally, I have a Cylinder Class.
In the Cylinder Class, I would like to override the getArea method, while still being able to access the Circle Class's getArea method in order to calculate the volume.
public class Cylinder extends Circle{
private double height;
public Cylinder(double radius, double height){
super(radius);
height = (( height < 0 )) ? 0 : height;
this.height=height;
}
public double getHeight() {
return height;
}
public double getVolume() {
return (super.getArea()*height);
}
#Override
public double getArea() {
return (2*Math.PI*getRadius()*height);
}
}
Expected result:
Due to the 'super.' before the getArea method inside the getVolume method, the getVolume method would call the original getArea method (as if I had not overridden it)
Actual result:
It doesn't matter whether there is a 'super.' before the getArea method or not, the overridden method is always called, leading to a false volume calculation.
Is there a way to call the not overridden version of the getArea method after overriding it?

How to sort list of shapes by their area in Java

I have created a list of Objects and added elements such as Circle and Square in it. I have added a method in the sqaure and circle classes which checks the instance of the object and compares the area.
public class Circle extends Shape implements Comparable <Object>{
public int compareTo(Object otherObject) {
double difference=0.0;
int retValue= 3;
if(otherObject instanceof Circle){
Circle circle= (Circle)otherObject;
difference= this.area()- circle.area(); //calculate the difference of areas
}
if(otherObject instanceof Square){
Square square= (Square)otherObject; //Casting the object to Sqaure
difference= this.area()- square.area();//Calculate difference of Areaareas
}
if(difference == 0.0)retValue = 0; //return 0 if area is equal
if(difference < Shape.TOLERANCE)retValue = -1; //return -1 if area of the circle is less than the otherObject
if(difference > Shape.TOLERANCE)retValue = 1; //return 1 if area of the circle is more than the otherObject
return retValue;
}
}
My class where I want to sort this looks like this:-
List<Object> objectList = new ArrayList<Object>();
when, I am trying Collections.sort(objectList), it is giving me an me error
no suitable method found for sort(List<Object>)
Any suggestions. Also I have declared my class like
Apples vs. Oranges, or in your case Circles vs. Squares.
You need to make them share a common aspect, which means that you need to make them implement a Shape2D interface with a double getArea() method.
You can then write a Comparator<Shape2D> and call sort(myShapeList, myAreaComparator).
Update
Given the extra code now shown in question, you already have the common base class Shape, which appears to have an abstract double area() method, implemented by both Circle and Square.
You then change Shape to be Comparable<Shape> (not Object), and the compareTo() method, which now takes a Shape as parameter, can call area() without any casting.
It doesn't make sense for a Circle to be comparable to Object.
If you want to sort circles and squares by their area,
use a Comparator instead.
It will also make sense to:
Use a List<Shape> rather than a List<Object>
A Comparator<Shape> can do the job, using Shape.area for the ordering
Use Double.compare to compare the areas, instead of manual if-else
Something like this:
public void demo() {
List<Shape> shapes = new ArrayList<>();
shapes.add(new Circle(2));
shapes.add(new Square(2));
shapes.add(new Square(1));
shapes.add(new Circle(1));
Collections.sort(shapes, new Comparator<Shape>() {
#Override
public int compare(Shape o1, Shape o2) {
return Double.compare(o1.area(), o2.area());
}
});
System.out.println(shapes);
}
Where the implementation of Shape, Circle, Square can be simple like this:
abstract class Shape {
abstract double area();
}
class Circle extends Shape {
private final double radius;
Circle(double radius) {
this.radius = radius;
}
#Override
double area() {
return radius * radius * Math.PI;
}
#Override
public String toString() {
return "Circle(" + radius + ")";
}
}
class Square extends Shape {
private final double side;
Square(double side) {
this.side = side;
}
#Override
double area() {
return side * side;
}
#Override
public String toString() {
return "Square(" + side + ")";
}
}

New to Java: SuperClass and SubClass

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()".

Problems with setters and getters in java program dealing with circles

I have been assigned the following task for an introductory java course:
You should write a class that represents a circle object and includes the following:
Private class variables that store the radius and centre coordinates of the object.
Constructors to create circle objects with nothing supplied, with just a radius value supplied and with a radius and centre coordinates supplied.
Public instance methods that allow the radius and centre coordinates to be set and retrieved (often known as set/get methods).
Public instance methods that return the circumference and area of the circle.
A public class method that tests if two circle objects overlap or not
Here is my code:
import java.lang.Math;
public class Circle {
private double xCentre, yCentre, Radius;
// constructors
public Circle() {
xCentre = 0.0;
yCentre = 0.0;
Radius = 1.0;
}
public Circle(double R) {
xCentre = 0.0;
yCentre = 0.0;
Radius = R;
}
public Circle(double x, double y, double R) {
xCentre = x;
yCentre = y;
Radius = R;
}
//getters
public double getX() {
return xCentre;
}
public double getY() {
return yCentre;
}
public double getRadius() {
return Radius;
}
//setters
public void setX(double NewX) {
xCentre = NewX;
}
public void setY(double NewY) {
yCentre = NewY;
}
public void setRadius(double NewR) {
Radius = NewR;
}
//calculate circumference and area
public double Circumference() {
return 2*Math.PI*Radius;
}
public double Area() {
return Math.PI*Radius*Radius;
}
//determine overlap
public static double Overlap(Circle c1, Circle c2) {
double xDelta = c1.getX() - c2.getX();
double yDelta = c1.getY() - c2.getY();
double separation = Math.sqrt(xDelta*xDelta + yDelta*yDelta);
double radii = c1.getRadius() + c2.getRadius();
return separation - radii;
}
}
}
and
import java.io.Console;
public class cp6 {
public static void main(String args[]){
//Set up the Console
Console myConsole = System.console();
//Declare cirlce
Circle first = new Circle(2.0,4.0,6.0);
myConsole.printf("Circumference of first circle is ", first.Circumference(), "\n");
myConsole.printf("Area of first circle is ", first.Circumference(), "/n");
first.setRadius(2);
first.setX(2);
first.setY(2);
myConsole.printf("New X of first circle is ", first.getX(), "/n");
myConsole.printf("New Y of first circle is ", first.getY(), "/n");
myConsole.printf("New Radius of first circle is ", first.getRadius(), "/n");
Circle second = new Circle(-1.0,3.0,5.0);
Circle third = new Circle(1,1,1);
if (Circle.Overlap(second, third) <= 0) {
myConsole.printf("Second and third circles overlap");
}
else {
myConsole.printf("Second and third circles do not overlap");
}
myConsole.printf("New Y of first circle is ", first.getY());
Calculate and print out distance between them using the class method
myConsole.printf("Distance between first and second is : %.5g\n", Circle.Overlap(first, second));
}
}
The second program just has to demonstrate each aspect addressed in the brief I pasted at the top and I've only a rough idea of how to do this so if what I'm doing seems stupid to any of you please offer suggestions of what else I can do.
Your problem is that you're using the Console.printf() method incorrectly.
The first parameter to this method should be a format, and it has to have placeholders inside it for the other parameters. Read up on it in The Java Platform documentation. In fact, you should familiarize yourself with the Java platform documentation. You need to use it often to make sure you're calling methods correctly or what methods are available in a given class.
So, your printout lines should actually have been:
myConsole.printf("Circumference of first circle is %.2f%n", first.Circumference());
myConsole.printf("Area of first circle is %.2f%n", first.Area());
...etc.
The format %.2f means "The corresponding parameter is a floating-point number. Display it with a precision of 2 digits after the decimal point". The %n replaces your "\n" - the whole "template" of the print should be just in the format string. And in this type of format, one should use %n instead of \n.
I'm not sure why you opted for using the system console rather than the usual System.out.println(). If you choose to go with System.out, there is also a printf() method there that works exactly as Console.printf() - the first parameter is a format, the others are embedded in it.
One last comment: there are conventions when writing Java code:
Indent your code properly
Class names' first letter is always uppercase.
Non-constant fields and local variable names' first letter is always lowercase.
Method names also start with a lowercase letter.

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.

Categories

Resources