I have one interface
public interface GeometricObject {
public String getInfo();
}
And I have 2 classes, which implement the above interface.
public class Circle implements GeometricObject {
#Override
public String getInfo() {
return "Circle[center,radius]";
}
}
public class Triangle implements GeometricObject {
#Override
public String getInfo() {
return "Triangle[p1,p2,p3]";
}
}
And now I have this class to show all info that:
public class shapeUtils{
public String printInfo(List<GeometricObject> shapes) {
//code here
}
}
How can I call that method in all implements to that list
e.g.
Circle:
Circle[(1,2),r=3]
Circle[(5,6),r=2]
Triangle:
Triangle[(1,2),(2,3),(3,0)]
Triangle[(-1,-3),(-5,3),(0,0)]
Just call it
for (GeometricObject shp : shapes) {
System.out.println (shp.getInfo());
}
I you want more simplicity.
shapes.forEach(shape -> System.out.println(shape.getInfo()));
First you have to add the fields that you need to your shapes. For example in the triangle you need p1, p2, p3. They must be part of the class if you want to get the right values printed.
E.g:
public class Circle implements GeometricObject {
private double center;
private double radius;
#Override
public String getInfo() {
return "Circle[ " + this.center + ", " + this.radius + " ]";
}
// Getters and setters
}
You do the same for all the shapes.
You can fill a list with objects like this:
java.util.List<GeometricObject> shapes = new ArrayList<>();
Circle circle = new Circle(); // Initialize it
circle.setCenter(2); // Set the values
circle.setRadius(2);
shapes.add(circle); // Add it to the list
// Add some more objects into the list...
// Print them:
for (GeometricObject shape : shapes) {
System.out.println(shape.getInfo());
}
Related
I have two objects - RightTriangle and Rectangle. Both classes implement "Shape" interface which has 2 abstract methods for area and perimeter. In RightTriangle class I implement comparable and my compareTo returns area:perimeter ratio. I do the same thing in Rectangle class. In the demo I want to sort an array of RightTriangle objects and Rectangle Object using Collections.sort().
Shape Interface Code:
public interface Shape
{
public double getArea();
public double getPerimeter();
}
RightTriangle Code:
public class RightTriangle implements Shape, Comparable<Shape>
{
private int leg1, leg2;
public RightTriangle(int lg1, int lg2)
{
leg1 = lg1;
leg2 = lg2;
}
public double getArea()
{
return (.5*leg1*leg2);
}
public double getPerimeter()
{
return (leg1+leg2 + getHypotenuse());
}
private double getHypotenuse()
{
return (Math.sqrt(Math.pow(leg1,2)+Math.pow(leg2,2)));
}
public int compareTo(Shape obj)
{
return (int)(getArea()/getPerimeter());
}
}
Rectangle Code:
public class Rectangle implements Shape, Comparable<Shape>
{
private int length, width;
public Rectangle(int l, int w)
{
length = l;
width = w;
}
public double getArea()
{
return (width*length);
}
public double getPerimeter()
{
return (2*width + 2*length);
}
public int compareTo(Shape obj)
{
return (int)(getArea()/getPerimeter());
}
}
Demo:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
public class Demo
{
public static void main (String[] args)
{
RightTriangle right = new RightTriangle(12,14);
Rectangle rect = new Rectangle(7,10);
ArrayList<Shape> al = new ArrayList<Shape>();
al.add(right);
al.add(rect);
Collections.sort(al);
for (int i = 0; i < al.size(); i++)
{
System.out.println (al.get(i));
}
}
}
I am getting an error - "error: no suitable method found for sort(ArrayList). How do I fix this?
Thanks.
1. You need to extend Comparable interface to Shape interface and not traingle and rectangle class as below
public interface Shape extends Comparable<Shape>
{
public double getArea();
public double getPerimeter();
public int compareTo(Shape obj);
}
2. RightTriangle and Rectangle class will only implement Shape interface as
public class RightTriangle implements Shape
public class Rectangle implements Shape
**3. Implement toString method in both RightTriangle and Rectangle class by right click on code ..select source-> generate toString()
#Override
public String toString() {
return "RightTriangle [leg1=" + leg1 + ", leg2=" + leg2 + "]";
}
#Override
public String toString() {
return "Rectangle [length=" + length + ", width=" + width + "]";
}
** See the result i got after correcting your code
I have a base class called Geometry from which there exists a subclass Sphere:
public class Geometry
{
String shape_name;
String material;
public Geometry()
{
System.out.println("New geometric object created.");
}
}
and a subclass:
public class Sphere extends Geometry
{
Vector3d center;
double radius;
public Sphere(Vector3d coords, double radius, String sphere_name, String material)
{
this.center = coords;
this.radius = radius;
super.shape_name = sphere_name;
super.material = material;
}
}
I have an ArrayList that contains all Geometry objects and I want to iterate over it to check whether the data from a text file is read in correctly. Here is my iterator method so far:
public static void check()
{
Iterator<Geometry> e = objects.iterator();
while (e.hasNext())
{
Geometry g = (Geometry) e.next();
if (g instanceof Sphere)
{
System.out.println(g.shape_name);
System.out.println(g.material);
}
}
}
How do I access and print out the Sphere's radius and center fields?
Thanks in advance :)
If you want to access properties of a subclass, you're going to have to cast to the subclass.
if (g instanceof Sphere)
{
Sphere s = (Sphere) g;
System.out.println(s.radius);
....
}
This isn't the most OO way to do things, though: once you have more subclasses of Geometry you're going to need to start casting to each of those types, which quickly becomes a big mess. If you want to print the properties of an object, you should have a method on your Geometry object called print() or something along those lines, that will print each of the properties in the object. Something like this:
class Geometry {
...
public void print() {
System.out.println(shape_name);
System.out.println(material);
}
}
class Shape extends Geometry {
...
public void print() {
System.out.println(radius);
System.out.println(center);
super.print();
}
}
This way, you don't need to do the casting and you can just call g.print() inside your while loop.
You have to cast (specifically, downcast):
((Sphere) g).radius
I agree with rwhat, but instead of implementing your own print() function, it might benefit you (and be more Object Oriented) to avoid the downcasts by overriding the toString() function.
public class Geometry
{
String shape_name;
String material;
public Geometry()
{
System.out.println("New geometric object created.");
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append("Shape name: " + shape_name + "\t");
result.append("Material: " + material + "\t");
return result.toString();
}
public static void check (Geometry[] gList) {
for (Geometry g: gList) {
System.out.println(g.toString());
}
}
Note the check() doesn't care whether g is a Sphere or a Cube. This will help minimize the calls to instanceof.
Over in Sphere...
public class Sphere extends Geometry
{
Vector3d center;
double radius;
public Sphere(Vector3d coords, double radius, String sphere_name, String material)
{
this.center = coords;
this.radius = radius;
shape_name = sphere_name;
super.material = material;
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append("Radius: " + radius + "\t");
result.append("Center: " + center.toString() + "\t");
result.append(super.toString());
return result.toString();
}
}
Any new shape (e.g., Cone) would benefit by having the toString() function, but lacking it would just print out Geometry's version.
use instanceof and Cast to the desired subclass. You might want to make those fields public or the standard idiom of private fields with getters and setters too.
Though the GeometricObject is without errors, the GeoCircle shows an error saying GeoCircle is not abstract and does not override the abstract method compareTo(GeometricObject) though the compareTo method is not written as an abstract class
//abstract class GeometricObject that implements the comparable interface
public abstract class GeometricObject implements Comparable<GeometricObject>
{
public String name;
//sample abstract class of getting area of various shapes
public abstract double getArea();
//sample abstract class for getting perimeter/circumference of various shapes
public abstract double getPerimeter();
//pass in and return name of the object selected in a system out line
public void name(String n)
{
System.out.println("This is a " + n);
}
/** A method for comparing the areas of two geometric objects and returning a boolean for their equals */
public static boolean equalArea(GeometricObject object1,GeometricObject object2)
{
//comparing double to another double
return object1.getArea()==object2.getArea();
}
// a method to find the bigger between two GeometricObjects and returning a String statement
public static void max(GeometricObject g1, GeometricObject g2)
{
if(g1.compareTo(g2)>0)
System.out.println("Object 1 is larger ");
else if (g1.compareTo(g2)<0)
System.out.println("Object 2 is larger ");
else
System.out.println("Objects are the same ");
}
// an override of the compareTo method from the implemented comparable interface
public int compareTo(GeometricObject g1, GeometricObject g2)
{
if(g1.getArea()>g2.getArea())
return 1;
else if (g1.getArea()<g2.getArea())
return -1;
else
return 0;
}
}
//a class for calculating circumference and area of a circle extended from GeometricObject
public class GeoCircle extends GeometricObject implements Comparable<GeoCircle>
{
public String name;
public double radius;
//constructor for only inputting radius of the circle
public GeoCircle(double r)
{
radius = r;
}
// 2ndconstructor taking a name for the shape and radius of the circle
public GeoCircle(String n, double r)
{
name = n;
radius = r;
}
//method to get area of the shape with previously passed in radius
public double getArea()
{
return Math.PI*Math.pow(radius,2);
}
//method to get circumference of the circle with radius previously given
public double getPerimeter()
{
return 2*Math.PI*radius;
}
//a compareTo method
public int compareTo(GeoCircle obj)
{
if (this.getArea() > obj.getArea())
return 1;
else if (this.getArea() < obj.getArea())
return -1;
else
return 0;
}
}
public int compareTo(GeometricObject g1, GeometricObject g2)
{
if(g1.getArea()>g2.getArea())
return 1;
else if (g1.getArea()<g2.getArea())
return -1;
else
return 0;
}
does not correctly override compareTo. compareTo is expected to take one argument and compare this to that argument. This could be implemented as
#Override public int compareTo(GeometricObject g) {
return Double.compare(getArea(), g.getArea());
}
For reference, adding the #Override annotation verifies that a method correctly overrides a superclass method, which would have been caught.
You should use generics in base class:
public abstract class GeometricObject<T extends GeometricObject> implements Comparable<T> {
...
// an override of the compareTo method from the implemented comparable interface
public int compareTo(T that) {
if(this.getArea()>that.getArea())
return 1;
else if (this.getArea()<that.getArea())
return -1;
else
return 0;
}
}
//a class for calculating circumference and area of a circle extended from GeometricObject
public class GeoCircle extends GeometricObject<GeoCircle> {
...
#Override // Remove this method if it doesn't differ from parent implementation
public int compareTo(GeoCircle that) {
...
}
}
Comparable interface is extremely strict. Much better solution would be implementing separate comparator and remove Comparable declaration from the base class:
class GeometricObjectAreaComparator implements Comparator<GeometricObject> {
#Override
public int compare(GeometricObject o1, GeometricObject o2) {
...
}
}
I have a problem with my program and I can't find the reason why thought. It points at the public static void main(String[] args) line nowhere else, can't figure it out :(
Tried checking for the braces, if by accident I missed one or two but still no, it is not an interface implementation so I don't have to set each method of the abstract class to public in the implementation...
abstract class Shape {
private String name;
Shape(String name0) {name = name0;}
abstract double area();
abstract double perim();
void put() {
System.out.println(name + " with area " + area()+ " and perimeter " + perim());
}
}
class Circle extends Shape{
private double r;
Circle(String name0, double inR) {
super(name0);
r = inR;
}
double area() {
return (Math.sqrt(r)*Math.PI);
}
double perim() {
return 2*(Math.PI * r);
}
}
class Rectangle extends Shape{
private double a,b;
Rectangle(String name0, double a0, double b0) {
super(name0);
a=a0; b=b0;
}
double area() {
return (a*b);
}
double perim() {
return 2*(a+b);
}
}
}
class TestClass {
public static void main(String args[]) {
Shape[] figures = {new Rectangle("Rectangle", 2.0, 3.0), new Rectangle("Square", 4.0, 4.0), new Circle("Circle", 2.0)};
for (Shape s: figures)
s.put();
}
}
You have an extra closing brace } before the main method. Just remove that.
Suggestion: It is really wise to use an IDE to do coding because you can get away from these compilation errors easily and quickly.
I have a base class called Geometry from which there exists a subclass Sphere:
public class Geometry
{
String shape_name;
String material;
public Geometry()
{
System.out.println("New geometric object created.");
}
}
and a subclass:
public class Sphere extends Geometry
{
Vector3d center;
double radius;
public Sphere(Vector3d coords, double radius, String sphere_name, String material)
{
this.center = coords;
this.radius = radius;
super.shape_name = sphere_name;
super.material = material;
}
}
I have an ArrayList that contains all Geometry objects and I want to iterate over it to check whether the data from a text file is read in correctly. Here is my iterator method so far:
public static void check()
{
Iterator<Geometry> e = objects.iterator();
while (e.hasNext())
{
Geometry g = (Geometry) e.next();
if (g instanceof Sphere)
{
System.out.println(g.shape_name);
System.out.println(g.material);
}
}
}
How do I access and print out the Sphere's radius and center fields?
Thanks in advance :)
If you want to access properties of a subclass, you're going to have to cast to the subclass.
if (g instanceof Sphere)
{
Sphere s = (Sphere) g;
System.out.println(s.radius);
....
}
This isn't the most OO way to do things, though: once you have more subclasses of Geometry you're going to need to start casting to each of those types, which quickly becomes a big mess. If you want to print the properties of an object, you should have a method on your Geometry object called print() or something along those lines, that will print each of the properties in the object. Something like this:
class Geometry {
...
public void print() {
System.out.println(shape_name);
System.out.println(material);
}
}
class Shape extends Geometry {
...
public void print() {
System.out.println(radius);
System.out.println(center);
super.print();
}
}
This way, you don't need to do the casting and you can just call g.print() inside your while loop.
You have to cast (specifically, downcast):
((Sphere) g).radius
I agree with rwhat, but instead of implementing your own print() function, it might benefit you (and be more Object Oriented) to avoid the downcasts by overriding the toString() function.
public class Geometry
{
String shape_name;
String material;
public Geometry()
{
System.out.println("New geometric object created.");
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append("Shape name: " + shape_name + "\t");
result.append("Material: " + material + "\t");
return result.toString();
}
public static void check (Geometry[] gList) {
for (Geometry g: gList) {
System.out.println(g.toString());
}
}
Note the check() doesn't care whether g is a Sphere or a Cube. This will help minimize the calls to instanceof.
Over in Sphere...
public class Sphere extends Geometry
{
Vector3d center;
double radius;
public Sphere(Vector3d coords, double radius, String sphere_name, String material)
{
this.center = coords;
this.radius = radius;
shape_name = sphere_name;
super.material = material;
}
public String toString() {
StringBuilder result = new StringBuilder();
result.append("Radius: " + radius + "\t");
result.append("Center: " + center.toString() + "\t");
result.append(super.toString());
return result.toString();
}
}
Any new shape (e.g., Cone) would benefit by having the toString() function, but lacking it would just print out Geometry's version.
use instanceof and Cast to the desired subclass. You might want to make those fields public or the standard idiom of private fields with getters and setters too.