How to call both abstract methods AND interface methods in an array? - java

I created an array to hold different shapes. Circle and Square are abstract classes extended from Class Shape. Cube and Sphere are from the interface called ThreeDShape. I need to find the area for all shapes and the area and volume for the 3D shapes and call them using an array. I got the Test class to be able to use the abstract methods. How do I get the test class to use the interface methods? How do I print the abstract methods AND the interface methods in a single array?
I also need to call the details of each class from within the array using the getClass() method.
public class Test {
public static void main(String[] args) {
Shape [] shape = new Shape[4];
Circle circle = new Circle();
shape[0] = circle;
Shape sphere = new Sphere();
shape[1] = sphere;
Shape cube = new Cube();
shape[2] = cube;
Square square = new Square();
shape[3] = square;
for(Shape shape1 : shape) {
System.out.println("The area of " + shape1.getClass() +" is " + shape1.area());
System.out.println("The volume of " + shape1.getClass() +" is " + shape1.volume());
System.out.println("Found in " + shape1.getClass());
System.out.println(" ");
}
}
}
public interface ThreeDShape {
public abstract double volume();
}
public class Cube implements ThreeDShape{
double a = 5;
public double volume() {
return a*a*a;
}
public double area() {
return 6*a*a;
}
}
public class Square extends Shape {
double s = 5;
public double area() {
return s*s;
}
}
public class Circle extends Shape {
double r = 9;
public double area() {
return r*r*3.14;
}
}
public class Sphere implements ThreeDShape {
double r1 = 5;
public double volume() {
return ( 4.0 / 3.0 ) * Math.PI * Math.pow( r1, 3 );
}
public double area() {
return 4*3.14*r1*r1;
}
}
public abstract class Shape {
public abstract double area();
protected abstract double volume();
}
```

Your design is wrong.
Everything should be a subclass of Shape. If you want some specialization then Sphere and Cube should be subclasses of ThreeDShape that is subclass of Shape. So to do what you do you just call a super method of Shape that has different implementation (aka is overwritten) on every subclass.
The loops becomes just this:
for (Shape s: shapes){
s.myBeautifulMethod();
}
If you want to keep ThreeDShape as an interface then Sphere and Cube should be both Shape and ThreeDShape:
public class Sphere extends Shape implements ThreeDShape { [...] }
public class Cube extends Shape implements ThreeDShape { [...]}
but I would stick with a single hierarchy, since otherwiese you are moving forward to multiple inheritance, and this is not very Java.
You are asking for a reflective logic where is not needed at all.
Hope I helped.

If you want to do this, you need to check the type of each shape and cast as you loop through the array. Something like:
for(Shape shape1: shape) {
System.out.println("Area: " + shape1.area());
if(shape1 instanceof ThreeDShape) {
System.out.println("Volume: " + ((ThreeDShape) shape1).volume());
}
}
Generally, type checking and casting like this should be avoided - it probably indicates bad program design. Interfaces and abstract classes are designed for situations where you have multiple types that support the same API. Here, though, you have 2 different APIs: Shape and ThreeDShape.

What I prefer is to avoid instanceOf, getClass and so on
public interface OperationalShape {
double getVolume();
double getArea();
String getName();
boolean supportsVolume();
}
public class Circle implements OperationalShape {
public double getVolume() {
throw new CustomUnsupportedException();
{
public boolean getArea() {
return ...
}
public String getName() {
return "Circle";
}
public boolean supportsVolume() {
return false;
}
}
After that you can iterate on your collection of OperationalShapes, checking with an if(supportsVolume()) if you should call getVolume() or not. You can get the name via getName().

For this code to compile ,
1)You need to change the Shape class to Shape interface. because interface can only implement an interface and not class.
or
2)Change ThreeDShape to class and extends to Shape class
ThreeDShape sphere = new Sphere();
shape[1] = sphere;
1 type implementation
public class Test {
public static void main(String[] args) {
Shape [] shape = new Shape[4];
Circle circle = new Circle();
shape[0] = circle;
ThreeDShape sphere = new Sphere();
shape[1] = sphere;
ThreeDShape cube = new Cube();
cube.volume();
shape[2] = (Shape) cube;
Square square = new Square();
shape[3] = square;
int x = 3;
int z = 1;
for(Shape shape1 : shape) {
System.out.println("The area of the circle is " + shape1.area());
System.out.println("The volume of the circle is " + shape1.volume());
x++;
z++;
System.out.println("Found in " + shape1.getClass());
System.out.println(" ");
}
}
}
interface ThreeDShape extends Shape{
public abstract double volume();
}
class Cube implements ThreeDShape{
double a = 5;
public double volume() {
return a*a*a;
}
public double area() {
return 6*a*a;
}
}
class Square implements Shape {
double s = 5;
public double area() {
return s*s;
}
#Override
public double volume() {
// TODO Auto-generated method stub
return 0;
}
}
class Circle implements Shape {
double r = 9;
public double area() {
return r*r*3.14;
}
#Override
public double volume() {
// TODO Auto-generated method stub
return 0;
}
}
class Sphere implements ThreeDShape {
double r1 = 5;
public double volume() {
return ( 4.0 / 3.0 ) * Math.PI * Math.pow( r1, 3 );
}
public double area() {
return 4*3.14*r1*r1;
}
}
interface Shape{
double area();
double volume();
}

As the other answers mentioned, the design is wrong. This is how I would do it.
If you have to use interface and abstract class in one project, you need to think which of them is more generic. In this class, is Shape or ThreeDShape more generic? Ofcourse, ThreeDShape is a kind of Shape.
Hence, Shape should be an interface and ThreeDShape an abstract class that implements the Shape interface, and not the other way around. An abstract class can implement an interface without actually implementing its methods, but an interface cannot extend an abstract class.
public interface Shape {...}
public abstract class ThreeDShape implements Shape {...}
public class Circle implements Shape {...} // Same for Square
public class Cube extends ThreeDShape {...} // Same for Sphere

Related

calling methods of subclass

I'm trying to learn inheritance. I have a superclass called Shape with getColor and getFilled methods. I then have 3 subclasses called Triangle, Rectangle and Circle. In each of the subclasses I have methods getPerimeter and getArea. Each shape has a subclass that extends the superclass. I then create an ArrayList and add a Triangle, Rectangle and Circle. I can call the getColor and getFilled superclass methods but run into a problem when trying to call the getPerimeter and getArea method that are created in the subclass. I think I have a misunderstanding of subclass and superclass. Here is my code:
Shape superclass
public class Shape
{
// instance variables
public String color; // color of shape
public boolean filled; // shape fill status
public Shape()
{
// initialize instance variables
color = "";
filled = false;
}
public String getColor()
{
return color;
}
public boolean getFilled()
{
return filled;
}
public String toString()
{
return getClass().getName();
}
}
Triangle (did not include here the Circle/Rectangle because they are basically the same as triangle)
public class Triangle extends Shape
{
// instance variables
private double side1;
private double side2;
private double side3;
public Triangle(String color, boolean filled, double side1, double side2, double side3)
{
// initialize instance variables
super.color = color;
super.filled = filled;
this.side1 = side1;
this.side2 = side2;
this.side3 = side3;
}
public double getPerimeter() {
return this.side1 + this.side2 + this.side3;
}
public double getArea() {
return (this.side2 / 2.0) * this.side1;
}
}
Tester:
import java.util.ArrayList;
public class Tester
{
public static void main(String arg[])
{
ArrayList<Shape> shapes = new ArrayList<>(); // create new array list of shapes
shapes.add(new Triangle("white", true, 3.0, 2.5, 2.0)); // Add new triangle to shapes list
shapes.add(new Rectangle("red", true, 2.0, 4.0)); // Add new rectangle to shapes list
shapes.add(new Circle("yellow", false, 1.0)); // Add new circle to shapes list
System.out.println("Starting shapes\n");
for (Shape shape: shapes) // loop through shapes
{
System.out.println(shape.toString()
+"[color="+shape.getColor()+", filled="+shape.getFilled()+"]"
); // print out string of shape/color/fill
System.out.println("Perimeter: "+shape.getPerimeter()); // print out perimeter
System.out.println("Area: "+shape.getArea()); // print out perimeter
System.out.println();
}
}
}
I expected to be able to call shape.getPerimeter() and shape.getArea() from the subclasses.
Added getPerimeter() and getArea() to parent Shape class, then added #Override in front of public class getPerimeter( and public class getArea( in all of the subclasses. Solved

Swift Multiple Inheritance. I am trying to recreate this Java Code in Swift related to Multiple Inheritance

public class Shape {
public static void main (String[] args) {
Circle c = new Circle(5);
System.out.println (c.getArea());
c.setColour("Green");
System.out.println (c.getColour());
}
}
interface Colour {
String getColour();
void setColour (String colour);
}
abstract class Shapes implements Colour {
abstract double getArea();
private String colour = "Red";
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
}
class Circle extends Shapes {
private int radius;
public Circle(int radius) {
this.radius = radius;
}
public double getArea() {
return Math.PI * radius * radius;
}
}
I have attempted a Swift Solution the code is below
import Cocoa
protocol Colour {
var colour: String { get set }
func getColour() -> (String)
func setColour(colour: String)
}
class Shape: Colour {
var colour: String = "Red"
init(colour: String) {
self.colour = colour
}
func getColour() -> (String) {
return colour
}
func setColour(colour: String) {
self.colour = colour
}
func getArea() -> Double {
return 0.0
}
}
class Circle: Shape {
let radius: Double
init(radius: Double) {
self.radius = radius
}
override func getArea() -> Double {
return radius * radius * Double.pi
}
}
I have written code to create an interface 'colour', a super class 'shape' and a subclass 'Circle'. The aim is to learn more about inheritance and multiple inheritance as a new programmer. The java code works as intended.
But i am getting an error " 'super.init' isn't called on all paths before returning from initializer" with the above Swift code. As I am newer to swift and multiple inheritance I am not sure how to correct this error.
How I can correct this?
Neither Swift nor Java support multiple inheritance.
C++ does, and a few others.
In Swift you can use protocols to accomplish very similar things, but conforming to a protcol is not the same thing as inheriting from a parent class.
Your problem is that your initializer needs to call its parent class' initializer:
init(radius: Double, color: String) {
self.radius = radius
super.init(color: color)
}
(Circle needs to call super.init, or in this case, init(colour:) from its shape superclass.)
Note that your circle shape's initializer should probably take a color as well as a radius:
Your error is related to the initialization of superclasses. Whenever you inherit the superclass, to initialize it you must write super.init() on the first line of the Circle class's initializer.
//Inside of Circle class
init(radius: Double) {
//I've initialized shape using the color Red, but you can use any string.
super.init(color: "Red")
self.radius = radius
}

How to extend a class with a constructor

I am having difficulty extending the calCir class to the main class
I have a constructor that gives
class calCir {
double radius;
calCir(double r) {
radius = r;
}
double AreaCircle() {
return Math.PI * (radius * radius);
}
double CircumferenceCircle() {
return 2 * Math.PI * radius;
}
}
I would like to use Main extends calCir but get an error due to the constructor
class Main{
public static void main(String args[]) {
error: constructor calCir in class calCir cannot be applied to given types;
class Main extends calCir
Im fairly new to Java so im still confused as to how I would use inheritance
Here is the full code if needed
https://repl.it/NA5S/8
This error is due to following reason:
when you create a constructor for a class, there won't be any default constructor created for that class. so if you extend that class and if the subclass tries to call the no-arg constructor of its super class then there will be an compile-time error.
As stated here: Constructor in class cannot be applied to given types
You have created an explicit constructor for your class. Any explicitly defined constructor will eliminate the default no-args constructor that Java will use implicitly.
Here is the constructor you have created:
CalCir(double r) {
radius = r;}
In order to use inheritance as requested, you can do any of the following.
Remove the explicit constructor from the parent class.
Insert a second construction with no parameters into the parent class:
CalCir()
{
// Set the radius to default of zero
this(0);
}
Override the default constructor in the child class:
public class MainSubClass extends CalCir
{
public MainSubClass()
{
// Set the radius to default of zero
super(0);
}
public static void main(final String args[])
{
// Insert program here
}
}
First, it is meaningless to have Main extend CalCir in this case.
Second, go back to the specific question you asked.
When you have a class (e.g. Child) extend from another (e.g. Parent), in the ctor of Child, it ALWAYS needs to invoke constructor of its parent. If you are not EXPLICITLY invoking any, compiler will automatically assume you are invoking the no-arg constructor of parent.
e.g.
class Child extends Parent {
Child() {
// do something
}
}
is equivalent to
class Child extends Parent {
Child() {
super();
// do something
}
}
If in Parent, a constructor with arguments is declared, but there is no-arg ctor declared:
class Parent {
Parent(int foo) {...}
}
it is illegal for Child to invoke the no-arg ctor of Parent, because it simply does not exists.
So you need to explicitly tell the compiler which ctor you want to invoke:
class Child extends Parent {
Child() {
super(123);
// do something
}
}
Any particular reason why you need to extend CalcCir? Your CalCir has a constructor which requires 2 args, if you are to extend it to your main class, then you would have create a constructor in main like:
public Main(double radius) {
// define your params to parent here or have it passed in constructor...
super(param1, param2); // matching your super class
}
Based on the link you provided though, it seems to be more appropriate this way:
Your main class which contains your starting point:
public class Main {
public static void main(String[] args) {
Scanner b = new Scanner(System.in);
while (true) {
try {
System.out.println("Determining the area/perimeter of a 2D shape.");
System.out.println("Choose a shape:\n\nRectangle --> (Type a or rectangle)\nCircle --> (Type b or circle)");
String shape = b.nextLine();
if ((shape.equalsIgnoreCase("Rectangle")) || (shape.equalsIgnoreCase("a"))) {
System.out.println("Input Length");
double length = b.nextDouble();
System.out.println("Input width");
double width = b.nextDouble();
Shape rectangle = new Rectangle(length, width);
System.out.println("Area of rectangle is " + rectangle.getArea());
System.out.println("The perimeter is " + rectangle.getPerimeter());
if (length == width){
System.out.println("This is a special type of reactangle, a square!");
}
break;
} else if ((shape.equalsIgnoreCase("circle")) || (shape.equalsIgnoreCase("b"))) {
System.out.println("Input Radius");
double radius = b.nextDouble();
Shape circle = new Circle(radius);
System.out.println("Area of circle is " + circle.getArea());
System.out.println("The circumference is " + circle.getPerimeter());
break;
} else {
System.out.println("Not valid choice\n");
}
} catch (Exception e) {
System.out.println("Not valid choice\n");
}
}
}
}
Then your Circle and Rectangle classes:
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
#Override
double getArea() {
return Math.PI * (radius * radius);
}
#Override
double getPerimeter() {
return 2 * Math.PI * radius;
}
}
public class Rectangle extends Shape {
private double length;
private double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
#Override
double getArea() {
return length * width;
}
#Override
double getPerimeter() {
return 2 * (length + width);
}
}
Of which both inherited from shape
public abstract class Shape {
abstract double getArea();
abstract double getPerimeter();
}

How to interpret and use a class given an interface object?

I have an interface. One of my methods takes as argument an object of this interface. Depending on the concrete class, I want to build a different object.
public interface Shape {
public void draw();
}
public class Circle implements Shape {
private int radius;
//constructor etc.
public void draw() {
System.out.println("CIRCLE!");
}
public int getRadius() {
return radius;
}
}
public class Square implements Shape {
private int side;
//constructor etc.
public void draw() {
System.out.println("SQUARE!");
}
public int getSide() {
return side;
}
}
public class MyClass {
public void myJob(Shape shape) {
if (shape.getClass().toString().equals("Circle")) {
// some missing code...what to do here? type cast? transform?
int radius = shape.getRadius();
}
}
}
How do I take the Shape interface and then get the radius or side out of it depending on the type of class?
First, there is no need to use reflection for this, you can use the keyword instanceof
public void myJob(Shape shape) {
if (shape instanceof Circle) {
// some missing code...what to do here? type cast? transform?
int radius = shape.getRadius();
}
}
Then, what you want to do is to cast your shape into a circle, so you can treat it like a circle:
public void myJob(Shape shape) {
if (shape instanceof Circle) {
Circle circle = (Circle) shape;
// Some Circle job
int radius = circle.getRadius();
}
}
Finally, if as you said you want to apply different treatments to different implementations of Shape, you can explicitly type the parameter:
public void myJob(Circle circle) {
// Some Circle job
}
public void myJob(Square square) {
// Some Square job
}
However, a better way to do that would be to use the Shape interface:
public interface Shape {
void draw();
void myJob();
}
public class MyClass {
public void myJob(Shape shape) {
shape.myJob();
}
}
}
All of the code that is Shape specific should be located in the methods overridden by each subclass.
public interface Shape {
public void draw();
public int getMeasure();
}
public class Circle implements Shape { ... } // The code for the methods in Shape should be written here.
public class Square implements Shape { ... }
public class MyClass {
public void doWork(Shape shape) {
int measure = shape.getMeasure();
}
}
Typically, looking up the class by name at runtime is an unnecessary hassle that can be avoided.
Edited for the question.
You can check if it's an instance of Circle by using instanceof and then cast it to a Circle if so.
if (shape instanceof Circle) {
Circle circle = (Circle)shape;
int radius = circle.getRadius();
}

Using classes with inheritance in Main class Java

My super class called Polygon:
public class Polygon
{
private double area;
/**
* Constructor for objects of class Rectangle
*/
public Polygon(double area)
{
this.area = area;
}
/**
* Mutator method that sets the area
*/
public void setArea(double area)
{
this.area = area;
}
/**
* Accessor method that returns the area
*/
public double getArea()
{
return area;
}
}
My Square class that extends Polgyon:
public class Square extends Polygon
{
private double perimeter;
/**
* Constructor for objects of class Square
*/
public Square(double area)
{
super(area);
}
/**
* calculates the perimeter of the square using area inherited from Polygon
*/
public void calcPerimeter()
{
perimeter = Math.sqrt(getArea()) * 4; //in a square, area is the square root
}
/**
* Accessor method that returns the perimeter
*/
public double getPerimeter()
{
calcPerimeter();
return perimeter;
}
}
I have a circle and rectangle class pretty much the same thing except with length and width, and circumference.
In the main class, I want to allow the user to put in an area and then receive the perimeter of a square with that area, circumference of a circle with that area, etc. I don't know if I did it correctly though...I created each object and put in the same input.
Here is my main class:
public class PolygonMain
{
public static void main(String[] args)
{
double input = Double.parseDouble(args[0]);
Polygon polygon = new Polygon(input);
Square square = new Square(input);
Circle circle = new Circle(input);
Rectangle rectangle = new Rectangle(input);
System.out.println("Area:" + " " + polygon.getArea() + ".");
System.out.println("Perimeter:" + " " + square.getPerimeter() + ".");
System.out.println("Circumference:" + " " + circle.getCircumference() + ".");
System.out.println("Length:" + " " + rectangle.getLength() + ".");
System.out.println("Width:" + " " + rectangle.getWidth() + ".");
}
}
As you can see in my main class, I put in the user input (args[0]) into each constructor's parameter.....which kind of makes the inheritance part of constructors i.e. super(area)....useless. Is it necessary to have to create every new shape? Also, what if I was to implement the Scanner class into the main class? Let's say, the user can type in area values and command back information on subclass shapes and then do this with multiple values of area? How would I go about doing that, as I have no idea how with having to create objects in the main class. We just started using the Main method; our IDE for the class is BlueJ, which doesn't require it. I hope my question isn't too confusing with it's wording and I apologize if I formatted this post wrong, as this is my first post. Thank you.
PS: I forgot to mention to ignore that square is a rectangle. My professor made a mistake and by accidentally instructed us to extend rectangle from square.
PS: besides in the main class, where you guys suggested adding each different shape to a collection and then iterating over each and printing out attributes, do you guys have any other alternatives? How would I do it with the Scanner class? Because in the above situation, I have tl create all the objects. I'm trying to get as much practice as possible with main class because I'm severely lacking in it due to BlueJ.
As far as I can see, it would be best to make Polygon abstract, and have it define an abstract method getPerimiter():
public abstract double getPerimiter();
That way, all your subclasses would need their own implementation of that method. That's reasonable because they all use different calculations.
So you class Polygon would look like this:
public abstract class Polygon {
protected double area; //not private, we want sub-classes to see this field
public Polygon(double area) {
this.area = area;
}
public abstract double getPerimiter();
}
And your square, for example, would look like this:
public class Square extends Polygon {
public Square(double area) {
super(area);
}
public double getPerimiter() {
return Math.sqrt(area) * 4;
}
}
All your subclasses must call the constructor defined in Polygon because there's no default constructor, hence the super(area) call in Square. Alternatively, you could do away with all the constructors and instead have a setArea(double area) method in Polygon.
Calling super(area) in the constructor is necessary because Polygon doesn't have a constructor with no-args.
Yes it is necessary to create every new shape because you work with objects and you need to create them before you can use them.
If you want to practice inheritance with this example you probably want to do something like this in your main:
Polygon[] shapes=new Polygon[4];
shapes[0]=new Polygon(input);
shapes[1] = new Square(input);
shapes[2] = new Circle(input);
shapes[3] = new Rectangle(input);
for(Polygon p:shapes){
System.out.println(p.getArea());
}
And see that all the different objects in the array inherit the getArea() method from Polygon. On the other hand if you want to call a specific method that's been provided in the subclass - say getPerimeter() - you have to cast the reference to subclass or you will not be able to use it:
Polygon mySquare=new Square(100);
System.out.println(((Square)mySquare).getPerimeter());
what you might want, is using a method shared by all your inheritance classes.
Polygon could have a method, which gives you the area - public double calculateArea()
but, you don't know, how the classes will calculate their area, so make it abstract
public abstract double calculateArea()
in Square:
public class Square extends Polygon
{
private double side;
public Square(double side)
{
this.side= side;
}
#Override
public double calcArea()
{
return side * side;
}
public double getSide()
{
return side;
}
}
you can now do the same with circle:
public class Circle extends Polygon
{
private double radius;
public Square(double radius)
{
this.radius= radius;
}
#Override
public double calcArea()
{
return radius * radius * Math.PI;
}
public double getRadius()
{
return radius;
}
}
in your Main Method, you set the Radius and the side length of circle and square:
Circle c = new Circle(5);
Square s = new Square(5);
and then you can make a List of Polygons, iterate over it, and get the area:
ArrayList<Polygon> list = new ArrayList<>();
list.add(c);
list.add(s);
for (Polygon element: list){
System.out.println(list.calcArea());
}

Categories