How to call on methods held inside an array? [closed] - java

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
public class Main {
public static void main(String[] args) {
shape[] myShapes = new shape[3];
myShapes[0] = new cube(3);
myShapes[1] = new Sphere(2);
myShapes[2] = new Cylinder(3, 4);
for (shape: myShapes)
System.out.println()
}
}
class cube extends shape {
public double side;
public double newSide;
public double volume;
public double surface;
public cube(double side) {
this.side = side;
}
public void cubeVolume(){
volume = Math.pow(side,3);
System.out.println (volume);
}
public void cubeSurface(){
surface = Math.pow(side,2) * 6;
System.out.println (surface);
}
}
abstract class shape{
protected double volume;
protected double surface;
}
public class Sphere extends shape {
public double radius;
public double volume;
public double area;
public double i = 4;
public double j = 3;
public Sphere(double radius) {
this.radius = radius;
}
public void sphereVolume(){
volume = i/j * Math.PI * Math.pow(radius,3);
System.out.println(volume);
}
public void surfaceArea(){
area = 4 * Math.PI * Math.pow(radius,2);
System.out.println(area);
}
}
public class Cylinder extends shape{
public double radius;
public double height;
public double cylinderVolume;
public double cylinderArea;
public Cylinder(double radius, double height) {
this.radius = radius;
this.height = height;
}
public void surface(){
cylinderArea = 2 * Math.PI * radius * height;
System.out.println(cylinderArea);
}
public void volume(){
cylinderVolume = Math.PI * Math.pow(radius, 2) * height;
System.out.println(cylinderVolume);
}
}
I do not think the title encompasses my question well. I am instantiating a new object and storing that object within the array myShapes. The class for each object has a method to calculate the surface area and volume. I need to call on all these methods, and I believe this can be done with a for loop, but I am not sure how. I am completely stumped.

Add abstract methods to your superclass:
abstract class Shape {
// Note: No fields
public abstract double surfaceArea();
public abstract double volume();
}
Implement them in your subclasses, eg for Cylinder:
public class Cylinder extends Shape {
// radius and height fields and constructor not shown
public double surfaceArea() {
return 2 * Math.PI * radius * height;
}
public double volume() {
return Math.PI * Math.pow(radius, 2) * height;
}
}
Then print them in your loop:
for (shape : myShapes) {
System.out.println("Surface area = " + shape.surfaceArea + ", volume = " + shape.volume());
}
Note that you don't want to print inside the methods - that's a rendering issue and should be done by the caller if appropriate. For example, you wouldn't want lots of output if you were just doing calculations and comparisons of shapes.
Also, it greatly helps readability if you follow Java Naming Conventions, especially classes should be SentenceCase and variables/parameters camelCase, so call your classes Shape instead of shape, Cube instead of cube etc.
If you don't have common fields, prefer an interface over an abstract class for the supertype.

If your storing your objects inside a shape[] array then, you need to make sure to define
volume() & surfaceArea() as abstract methods in your shape class so, that each of your shapes (Cylinder, Sphere, etc.) will then be able to override and implement. They need to be named the same as well.

Related

How can I access a method of a class from a generic method

I'm working on a tiny exercise java program that calculates circle and square (classes) area, that implements surface (interface) which has a method called area(). A requirement is that I have to implement a class called SumArea that has a generic method called calcArea() that receives Circle circ[] and Square square[] arrays and executes area calculation.
Program structure:
-> UseSumArea.java (main method)
-> Surface.java (interface)
-> Square.java (class that implements Surface.java)
-> Circle.java (class that implements Surface.java)
-> SumArea.java (class that executes calcArea() method)
UseSumArea.java
public class UseSumArea {
public static void main(String[] args) {
Square square[] = { new Square(2.0), new Square(5.0) };
Circle circ[] = { new Circle(3.0), new Circle(2.0) };
Surface surf[] = new Surface[square.length + circ.length];
surf[0] = square[0];
surf[1] = square[1];
surf[2] = circ[0];
surf[3] = circ[1];
SumArea sum = new SumArea();
System.out.println("Square's sum area = " + sum.calcArea(square));
System.out.println("Circle's sum area = " + sum.calcArea(circ));
System.out.println("Surface's sum area = " + sum.calcArea(surf));
}
}
Surface.java
public interface Surface {
public double area();
}
Square.java
public class Square implements Surface {
private double area;
private double side;
public Square(double l) {
this.side = l;
area();
}
#Override
public double area() {
return this.area = (this.side)*(this.side);
}
public double getArea() {
return area;
}
public void setArea(double area) {
this.area = area;
}
public double getSide() {
return side;
}
public void setSide(double side) {
this.side = side;
}
}
Circle.java
public class Circle implements Surface {
private double area;
private double radius;
public Circle (double r) {
this.radius = r;
area();
}
#Override
public double area() {
return area = (((this.radius)*(this.radius))*(Math.PI));
}
public double getRadius() {
return radius;
}
public void setRadius(double raio) {
this.raio = raio;
}
public double getArea() {
return area;
}
public void setArea(double area) {
this.area = area;
}
}
SumArea.java
public class SumArea {
private double area;
public <T> double calcArea(T[] t) { //generic method that receives Square and Circle arrays
double arrayArea = 0;
for (T a : t) {
arrayArea = arrayArea+(a.area());
}
return this.area = arrayArea;
}
}
My doubt is over this SumArea's code snippet:
arrayArea= arrayArea+(a.area());
How can I access the area() method of each Circle and Square objects inside this generic method?
You need to bound the type variable:
public <T extends Surface> double calcArea(T[] t) {
or just declare the parameter as an array of Surfaces:
public double calcArea(Surface[] t) {
Note that the latter is preferable because generics and arrays don't play very nicely together. If you were to need to have a type variable for other reasons, it would be advisable to change to a Collection, or similar:
public <T extends Surface> double calcArea(Collection<T> t) {
(And, as a minor matter of preference, I would use S rather than T to name a type variable which extends Surface)
Since the problem in regard to generic types is already addressed by Andy Turner, I just want to add a suggestion related to the class design.
I think there is a bit of redundancy in how these classes were designed. You need to create an instance of SumArea in order to do the calculation. And the result of the last of the last calcArea() method call will be stored in this object (let's assume that this calculation is far more complex and CPU-consuming).
But do we really need to store somewhere else the value is already returned by the method? In this case, the idea to cash the history of calculations (as a single variable or as a collection of values) doesn't seem to be useful because it can't be reused without knowing which objects were involved in the calculation.
And without storing the result this method will not be bound to a state, i.e. it has to be static. And since interfaces can have static methods, instead of creating a utility class for that purpose it could be placed in the Surface interface. Like that.
public interface Surface {
public double area();
public static <T extends Surface> double calcArea(T[] t) { // generic method that receives Square and Circle arrays
double arrayArea = 0;
for (T a : t) {
arrayArea += a.area();
}
return arrayArea;
}
}
Note that static behavior declared in interfaces in contrast to classes could be invoked only by using the name of an interface:
System.out.println("Circle's sum area = " + Surface.calcArea(circ));
Also note that it makes sense for both classes to have a field area inside the classes Circle and Square only if other fields will be declared as final, i.e. they must be initialed only one during the object construction and setters become unnecessary.
In this case (assuming that radius has been declared as final and is being validated when assigned so that reduce > 0) method area() will look like this:
#Override
public double area() {
if (area > 0) { // `0` is a default value for instance variables
return area; // reusing already calculated value
}
return area = radius * radius * Math.PI;
}
And there mustn't be two methods area() and getArea() leave either one or another.

Can interfaces be used as datatypes just like String,int etc [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I was searching the AdapterView.java class. And then I ran into this problem.I have uploaded the java file to the below link
https://www.codepile.net/pile/7J7xq0LY
Here OnItemClickListener is an interface(written on line 278). On line 146 it's given as OnItemClickListener mOnItemClickListener;. How's is that possible .mOnItemClickListener is a member variable. Giving it next to an interface name does'nt make sense for me. When we declare a variable,we first write the variable type followed by the name. But here it doesn't make a logic. Can anyone please explain this to me. I have just learned about interfaces so not much confident with its basics. Thanks in advance
Can interfaces be used as datatypes just like String,int etc.
Yes, an interface is also a type like a class. An interface reference is used in Java to achieve polymorphism.
Check this for more information.
Given below is a sample code to demonstrate this concept:
interface Polygon {
double getArea();
}
class Triangle implements Polygon {
private double base, height;
public Triangle(double base, double height) {
this.base = base;
this.height = height;
}
public double getBase() {
return base;
}
public void setBase(double base) {
this.base = base;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
#Override
public double getArea() {
return 0.5 * base * height;
}
}
class Rectangle implements Polygon {
private double length, breadth;
public Rectangle(double length, double breadth) {
this.length = length;
this.breadth = breadth;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getBreadth() {
return breadth;
}
public void setBreadth(double breadth) {
this.breadth = breadth;
}
#Override
public double getArea() {
return length * breadth;
}
}
public class Main {
public static void main(String[] args) {
Polygon shape1 = new Triangle(10, 20);
Polygon shape2 = new Rectangle(10, 20);
System.out.println(shape1.getArea());
System.out.println(shape2.getArea());
}
}
Output:
100.0
200.0
Feel free to comment in case of any doubt/issue.

Instantiating a class does not work, constructor parameter did not pass

I tried to initialize an circle object from my test class, but the parameter(5.5) did not pass. The result is wrong. I tried to debug and find out the radius is 0.00 in circle class, 5.5 did not pass into the Circle class.
Anyone can help me with that?
This is my output:
The area of circle is: 3.14
This is my test class:
public class ShapeTest {
public static void main(String[] args){
Circle circle = new Circle(5.5);
System.out.println(circle);
}
}
}
This is my circle class:
public class Circle extends TwoDimensionalshape {
private double radius;
public Circle(double radius){
super(radius);
}
public void setRadius(double radius){
this.radius = radius;
}
public double getRadius(){
return radius;
}
#Override
public double getArea(){
return 3.14+getRadius()+getRadius();
}
#Override
public String toString(){
return String.format("%s %,.2f%n ","The area of circle is: ",getArea());
}
}
This is my super class:
public class TwoDimensionalshape implements Area{
private double radius;
private double base;
private double height;
public TwoDimensionalshape(double radius){
this.radius = radius;
}
public TwoDimensionalshape(double base, double height){
this.base = base;
this.height = height;
}
public double getRadius() {
return radius;
}
public double getBase() {
return base;
}
public double getHeight() {
return height;
}
#Override
public double getArea(){
return 1;
}
public String toString(){
return "The area is: "+getArea();
}
}
Your radius variable in Circle hides the radius variable in TwoDimensionalshape. They are 2 different variables. Your constructor sets the one in TwoDimensionalShape, but getArea is using the one in Circle.
Remove the radius variable in Circle. Let Circle inherit getRadius by removing that method from Circle. Also in Circle, move setRadius to TwoDimensionalShape.
Also, in getArea, multiply the radius twice instead of adding it twice. You can also use Math.PI instead of 3.14.
return Math.PI * getRadius() * getRadius();
Remove private double radius; from Circle class and it should work. Also change getRadius() method body in Circle class to:
return super.getRadius();
You are missing the following line in Circle constructor:
public Circle(double radius){
super(radius);
this.radius = radius; // add this line
}
As radius is private in TwoDimensionalshape, you don't have an access to it from the subclass (from Circle in that case). You need to set value of radius of Circle class in constructor of Circle, as in your code, it calculated getArea() with the radius value of 0.
Another issue - to calculate area properly, you should change:
return 3.14 + getRadius() + getRadius();
to:
return 3.14 * getRadius() * getRadius();

Pass variables into other classes or have variables be used by different classes

Image of Description
The aim is to have the user select a shape (Square, Triangle or Circle) and then enter a boundary length. Once this information has been input I can then calculate the perimeter and area of their choice.
The problem is I don't want to create new variables for the length and area in each class if I don't have to and would rather have the variables declared and then passed into the classes if I can.
Basically I don't want to do it like this,
class square {
double bLength;
double area;
}
class triangle {
double bLength;
double area;
}
class circle {
double bLength;
double area;
}
Can I declare them outside of the classes and then have the classes use/inherit them or anything?
I must apologise for such a basic question, I am quite new to Java and I can't really think around this one.
The classic solution is to use inheritance:
class Shape {
double bLength;
double area;
Shape(double bLength, double area) {
this.bLength = bLength;
this.area = area;
}
}
class Square extends Shape {
Square(double bLength, double area) {
super(bLength, area);
}
// additional field, methods...
}
// same for the other shapes
You can use inheritance for this problem in following way :
Declare a class called Shape from which all other classes would inherit
public class Shape {
public double length = 0;
public abstract double GetPerimeter();
public abstract double GetArea();
public Shape(double length) {
this.length = length;
}
}
Then have your specialized classes. E.g. :
public class Circle extends Shape {
public Circle(double length) {
super(length);
}
public double GetPerimeter() {
// Implement the perimeter logic here
}
public double GetArea() {
// Implement the area logic here
}
}
Do this for all classes. This way you have the variable in only one class, and all others inherit from it.
EDIT
If you want even further optimization (for instance, you don't want function call overhead), something like perhaps
public class Shape {
public double length = 0;
public double perimeter= 0;
public double area= 0;
public Shape(double length, double perimeter, double area) {
this.length = length;
this.perimeter= perimeter;
this.area = area;
}
}
public class Circle extends Shape {
public Circle(double length) {
super(length, 2 * Math.PI * length, Math.PI * length * length);
}
}

Java superclass inheritance

I have a superclass (SimpleGeometricObject) which is extended to two subclasses (CircleFromSimpleGeometricObject and RectangleFromSimpleGeometricObject), and a class that invokes CircleFromSimpleGeometricObject and RectangleFromSimpleGeometricObject called TestCircleRectangle. Following the debugger, for subclass CircleFromSumpleGeometricObject,
this line of code:
public CircleFromSimpleGeometricObject(double radius){
this.radius = radius;
}
somehow invokes the superclass SimpleGeometricObject:
/** Construct a default geometric object */
public SimpleGeometricObject() {
dateCreated = new java.util.Date();
}
I am a bit confused about how this happens and why, can someone help me understand why this happens? Below are the codes to all the classes.
public class SimpleGeometricObject {
private String color = "white";
private boolean filled;
private java.util.Date dateCreated;
/** Construct a default geometric object */
public SimpleGeometricObject() {
dateCreated = new java.util.Date();
}
/** Construct a geometric object with the specified color
* and filled value */
public SimpleGeometricObject(String color, boolean filled) {
dateCreated = new java.util.Date();
this.color = color;
this.filled = filled;
}
/** Return color */
public String getColor() {
return color;
}
/** Set a new color */
public void setColor(String color) {
this.color = color;
}
/** Return filled. Since filled is boolean,
its get method is named isFilled */
public boolean isFilled() {
return filled;
}
/** Set a new filled */
public void setFilled(boolean filled) {
this.filled = filled;
}
/** Get dateCreated */
public java.util.Date getDateCreated() {
return dateCreated;
}
/** Return a string representation of this object */
public String toString() {
return "created on " + dateCreated + "\ncolor: " + color +
" and filled: " + filled;
}
}
public class CircleFromSimpleGeometricObject
extends SimpleGeometricObject {
private double radius;
public CircleFromSimpleGeometricObject() {
}
public CircleFromSimpleGeometricObject(double radius){
this.radius = radius;
}
public CircleFromSimpleGeometricObject(double radius,
String color, boolean filled) {
this.radius = radius;
setColor(color);
setFilled(filled);
}
/** Return radius */
public double getRadius() {
return radius;
}
/** Set a new radius */
public void setRadius(double radius) {
this.radius = radius;
}
/** Return area */
public double getArea() {
return radius * radius * Math.PI;
}
/** Return diameter */
public double getDiameter() {
return 2 * radius;
}
/** Return perimeter */
public double getPerimeter() {
return 2 * radius * Math.PI;
}
/** Print the circle info */
public void printCircle() {
System.out.println("The circle is created " + getDateCreated() +
" and the radius is " + radius);
}
}
public class RectangleFromSimpleGeometricObject
extends SimpleGeometricObject {
private double width;
private double height;
public RectangleFromSimpleGeometricObject() {
}
public RectangleFromSimpleGeometricObject(
double width, double height) {
this.width = width;
this.height = height;
}
public RectangleFromSimpleGeometricObject(
double width, double height, String color, boolean filled) {
this.width = width;
this.height = height;
setColor(color);
setFilled(filled);
}
/** Return width */
public double getWidth() {
return width;
}
/** Set a new width */
public void setWidth(double width) {
this.width = width;
}
/** Return height */
public double getHeight() {
return height;
}
/** Set a new height */
public void setHeight(double height) {
this.height = height;
}
/** Return area */
public double getArea() {
return width * height;
}
/** Return perimeter */
public double getPerimeter() {
return 2 * (width * height);
}
}
public class TestCircleRectangle {
public static void main(String[] args) {
CircleFromSimpleGeometricObject circle =
new CircleFromSimpleGeometricObject(1);
System.out.println("A circle " + circle.toString());
System.out.println("The color is " + circle.getColor());
System.out.println("The radius is " + circle.getRadius());
System.out.println("The area is " + circle.getArea());
System.out.println("The diamter is " + circle.getDiameter());
RectangleFromSimpleGeometricObject rectangle =
new RectangleFromSimpleGeometricObject(2, 4);
System.out.println("\nA rectangle " + rectangle.toString());
System.out.println("The area is " + rectangle.getArea());
System.out.println("The perimeter is " +
rectangle.getPerimeter());
}
}
A constructor like public CircleFromSimpleGeometricObject(double radius) always must include a call to its superclass's constructor as the first line; if you don't do it explicitly, the compiler will invisibly insert a call to the superclass's no-argument constructor, if it has one. That's what has happened here; the constructor is automatically calling public SimpleGeometricObject().
A constructor can call a superclass constructor like this:
super();
You could include arguments, if any are required.
P.S. As a commenter mentioned, your class names are really odd and unnecessary; Circle and Rectangle would be sufficient.
Any constructor invokes the super-class constructor (and so on, until the Object constructor is invoked). If you do not explicitly call super(), the compiler inserts it for you.
The most obvious way to see this is to have no default constructor in your superclass (no constructor without any arguments). In this case, you subclass will not compile until you insert an explicit call to the super constructor you want.
According to the java specification, all object constructors implicitly call their super class's constructors. Imagine if it didn't: your dateCreated object would not be initialized.
Here is the blog I found that points to the java specification:
http://www.dribin.org/dave/blog/archives/2004/11/23/java_constructor/
Since CircleFormSimpleGeometricObject extends SimpleGeometricObject, the constructor SimpleGeometricObject() is automatically called when the constructor CircleFormSimpleGeometricObject() is invoked.
This is useful since any variables that a subclass needs from the superclass would be initialized, though if this is the case it is safer to call super(), which explicitly calls the superclass's constructor. To specify which constructor to use, the variables that the specific constructor calls for can be put into super(). For example, this line:
super(String, boolean);
would call the related constructor in SimpleGeometricObject.

Categories

Resources