sub-classes in Java - java

My friend gave me this task and I am struggling with the last to, it asks me to:
"implement a class called Square that represents a square. Class
Square must be derived from Rectangle. Make sure you override
toString()."
I don't even think I am even close to getting it but any help would be great
Rectangle.Java
public class Rectangle {
public double width;
public double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getArea() {
return width * height;
}
public double getPerimeter() {
return 2*width+2*height;
}
#Override
public String toString() {
return "Rectangle[width "+width+",height "+height+"]Area:"+getArea()+",Perimeter:"+getPerimeter();
}
public static void main(String[] args) {
double width = (10);
double height = (10);
Rectangle rectangle = new Rectangle(width, height);
System.out.println(rectangle);
}
}
Sqaure.java
public class Sqaure extends Rectangle {
private final double width, height, area, perimeter;
public Sqaure(double width, double height) {
this.width = width;
this.height= height;
}
public static void main(String[] args) {
double width = (10);
double height = (10);
Sqaure sqaure = new Sqaure(width, height);
System.out.println(square);
}
}

There is no need to overwrite more than the constructor and toString(). As a square is just a special rectangle with equal side lengths, you can just initialize them to the same value, and all other methods will work as expected:
public class Square extends Rectangle {
public Square(double width) {
super(width, width);
}
#Override
public String toString() {
return "Square[width:" + width + "]Area:" + getArea() +
",Perimeter:" + getPerimeter();
}
Note that in the real world, you probably wouldn't use inheritance in this case, as this introduces some ambiguity -- you can still create squares with the rectangle constructor, and people may get mislead to use instanceof checks to determine whether a given rectangle is a square. Instead, one would probably add a single parameter constructor and check for width/height equivalence in toString.

You should note that sub and super classes do not need a main-class. You should have a separate main class where you initialize these objects.
To override a method use #Override. You do this because you can initialize a subclass a super class, e.g., Rectangle square = new Square(...). When you call square.toString() the output should not be Rectangle[width...], but Square[width...].
#Override
public String toString() {
return return "Square[width "+size+",height "+size+"]Area:"+getArea()+",Perimeter:"+getPerimeter();
}
If you do not override a method the functionality will be the same as of the super class (which is just fine for getArea() and getPerimeter().
Please note: a Square usually only has one parameter instead of two, because that is what makes it a Square. ;)

What your "friend" probably wants you to do is to use a super constructor. As it was already explained by Peter Lawrey, you do not need to define width, height in your extended class. It is considered a bad practice to hide fields in such a way. Square class will inherit those fields from its superclass Rectangle on the account of the extends keyword:
public class Sqaure extends Rectangle
This is how you might use a super constructor in your case.
public Sqaure(double side) {
super(side, side);
}
This will call the super class's constructor:
public Rectangle(double width, double height)
and by doing so, it will assign the Square's inherited fields width and height to the same value, making it a square. The inherited methods getArea() and getPerimeter() will still work, so there is no need to override them.
You will need to override the toString() method, because it has the word Rectangle in it. I am sure you can figure that one out yourself.

Related

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
}

Inheritance in Java with array

I have a problem when I use inheritance and define an object of parent class then call the constructor from the child class which has its own properties. When i want to assign values to the child class using sets methods its gives me an error (cannot find symbol)
this is my code
public class Shape {
private final double PI =3.14;
public Shape() {
}
public double getPI() {
return PI;
}
}
public class Rectangle extends Shape {
private double length;
private double width;
public Rectangle() {
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
}
public class Circle extends Shape{
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
Shape s[] = new Shape[3];
int type;
for (int i = 0; i < s.length; i++) {
System.out.println("Enter the Shape:\n 1.Rectangle \n 2.Circle");
type = in.nextInt();
if(type==1){
s[i] = new Rectangle();
s[i].setLength(5.5);
}
}
}
Your problem lies here:
s[i] = new Rectangle();
s[i].setLength(5.5);
Yes. You know that this form is an instance of Rectangle, all the JVM knows is that it's a Shape. If you want to use it as a Rectangle, you have to declare it as one:
Rectangle r = new Rectangle();
r.setLength(5.5);
s[i] = r;
EDIT: The reason for this is, when you declare an instance as a Shape (parent class), the JVM will consider it to be this, even if your code suggests (to a human reader) that a specific type will be used, the JVM will not make any assumptions on which sub class will be instantiated.
You are limited to the possibilities of the class you declared it to be.
Since you now again save it as a Shape, in your array, if later on you'll want to get that value, you'll need to cast it.
Rectangle rNew = (Rectangle)s[index]; // of course after checking whether it is in fact a Rectangle
you setLength() method is present in your sub class Rectangle while s[i] points to an instance of type Shape which is a super class. thus, it doesn't recognize the instance method due to implicit upcasting.
you will have to explicitly downcast you object s[i] from shape to Rectangle.
This is how you can do it:
Rectangle r = (Rectangle)s[i];
r.setLength(5.5);
NOTE: Ofcourse the above statements gos after s[i] = new Rectangle();
an ideal way though (as explained by #Stultuske):
Rectangle r = new Rectangle();
r.setLength(5.5);
s[i] = r;

Should I be using Inner Classes? Example Code inside

I like consolidating my code/classes as much as possible without each class itself getting messy. So I looked into using NestedClasses, though InnerClasses in this case because the InnerClass needs access the OuterClass's members.
Example
Lets say I have a program that calculates various shape attributes to shapes. So given a Rectangle Shape, it would find the Area/Perimeter from inputs of length and width.
I would first create an abstract class Shape, which has abstract methods getArea() and getPerimeter(). I would then create my subclass RectangleShape, extend the shape class, #Override those methods with the necessary logic.
Now there's a shape Rectangular Prism (Cube). It has the same variables/methods as RectangleShape does, but with one extra, height. In the past I would create another subclass of RectangleShape and go from there.
Is it better/not worse to use an InnerClass instead and have an abstract class PrismShape? I ask this because Prisms share the same methods, no matter the shape. If you're at all confused by the above I'm posting code below of what I'm saying.
Example Code
Shape Class
public abstract class Shape {
public abstract double getArea();
public abstract double getPerimeter();
}
PrismShape Class
public abstract class PrismShape{
public abstract double getVolume();
public abstract double getSurfaceArea();
public abstract double getLateralArea();
}
RectangleShape Class
import Abstract.Shape;
import Abstract.ShapePrism;
public class RectangleShape extends Shape{
//Variables Declared
private double _length, _width;
//Constructor
public RectangleShape(double _length, double _width) {
setLength(_length);
setWidth(_width);
}
//Getters and Setters
#Override
public double getArea() {
return getLength() * getWidth();
}
#Override
public double getPerimeter() {
return (2 * getLength())+ (2 * getWidth());
}
public double getLength() {
return _length;
}
private void setLength(double _length) {
this._length = _length;
}
public double getWidth() {
return _width;
}
private void setWidth(double _width) {
this._width = _width;
}
//Inner Class Prism
public class RecPrismShape extends PrismShape{
//Variables Declared
private double _height;
//Constructor
public RecPrismShape(double _height) {
setHeight(_height);
}
//Getters and Setters
#Override
public double getSurfaceArea(){
return (getLateralArea() + (2 * getArea()));
}
#Override
public double getVolume(){
return getArea() * getHeight();
}
#Override
public double getLateralArea(){
return getPerimeter() * getHeight();
}
public double getHeight() {
return _height;
}
private void setHeight(double _height) {
this._height = _height;
}
}
}
I'm open to criticism, still fairly new to Java. My thought process during this was I have 2d Shape attributes and 3d (Prism) shape attributes. The 3d Shapes derive their attributes from 2d shapes, but not visa versa. So for me at least having InnerClasses makes sense.
My own take on this: A public inner class seems most useful when the rest of the program has an object of the outer class, and it wants to create an object of the inner class that "belongs" to the outer class object in some way; that is, it's tightly associated with it.
The way you've arranged things, however, it means that if the client wants to create a RecPrismShape object, it has to first create a RectangleShape object that the prism object will belong to. Most likely, this is not going to be useful. That is, the client creates a RectangleShape rect just because it has to, in order to create a RecPrismShape, and the rect object wouldn't be useful to it in any other way.
I think a better idea would be to have a RecPrismShape object have a private RectangleShape object as one of its fields, but this would be an "implementation detail". That way, you'd get to reuse the RectangleShape code, which it seems like you're trying to do.
public class RecPrismShape extends RectangleShape {
private RectangleShape rect;
private double height;
public RecPrismShape(double length, double width, double height) {
rect = new RectangleShape(length, width);
this.height = height;
}
// and just one example of how you could use it
public double getVolume() {
return rect.getArea() * getHeight();
}
}

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());
}

How to use circle.java to calculate getVolume of a cylinder. [2 classes]

edit2
Sorry never mind I just added
public double cylinderSurfaceArea() {
return 2 * base.circleArea() + base.circleCirumference() * 2 * height;
}
}
With no error codes. This would be correct?
edit:
Thank you to all those who have answered. I have since changed my previous Cylinder class to read. Now I want to take it a step further and add
public double cylinderSurfaceArea() {
return 2 * Math.PI * radius * radius + 2 * Math.PI * radius * h;
}
However it now says that radius (or even r) returns an error "cannot find symbol - variable radius). Shouldn't the symbol be found/declared from the Circle class?
What I am trying to do is calculate the volume of a cylinder using a separate Circle.java class.
So for instance, I have the following so far for my circle.java
public class Circle {
public double radius;
public Circle(double r) {
radius = r;
}
public double circleArea() {
return Math.PI * radius * radius;
}
public double circleCirumference() {
return Math.PI * 2 * radius;
}
}
Now here are where the questions start. When making the Cylinder class do I start with:
public class Cylinder extends Circle {
If so, overall I have:
public class Cylinder extends Circle {
public Circle base;
public double height;
public Cylinder(double r, double h) {
height = h;
base = new Circle(r);
}
public double getVolume() {
return base.circleArea * height;
}
}
However, I keep getting an error after:
public Cylinder(double r, double h) {
Stating that:
constructor Circle in class Circle cannot be applied to given types; required:double; found: noarguments; reason:actual and formal arguments lists differ in length."
Can someone push me in the right direction? What am I doing wrong?
That happens because the first call of you constructor is implicit super()
Quote from the Java Tutorials:
If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error.
You need to make a parameterless constructor in your Circle class or change your Cylinder constructor like this:
public Cylinder(double r, double h) {
super(r);
height = h;
}
You're implicitly calling the super constructor with no argument, but there's no such constructor.
But you have a design problem : You're trying to use both composition and inheritance. One would be enough.
Using inheritance :
public class Cylinder extends Circle {
public double height;
public Cylinder(double r, double h) {
super(r);
height = h;
}
public double getVolume() {
return circleArea() * height;
}
}
Using composition (almost always better) :
public class Cylinder {
public Circle base;
public double height;
public Cylinder(double r, double h) {
height = h;
base = new Circle(r);
}
public double getVolume() {
return base.circleArea * height;
}
}
You don't need an explicit base field in Java when using inheritance. To initialise the base class (or "superclass"), you need to use the super statement in your child class constructor:
class Circle {
public Circle(double radius) {
// …
}
}
class Cylinder extends Circle {
public Cylinder(double radius, double height) {
super(radius); // calls the parent class constructor
// …
}
}
Alternately, you could use composition instead of inheritance - probably a better design in this case:
class Circle {
public Circle(double radius) { /* … */ }
}
class Cylinder { // no `extends` here
public Cylinder(Circle base, double height) {
// …
}
public Cylinder(double radius, double height) {
this(new Circle(radius)); // calls the above constructor
// …
}
}
(I'm omitting trivial assignments and fields in the above code sample for brevity.)
Problem 1:
The problem in your program is no default constructor present in your Circle. While creating the Cylinder object its looking for the default constructor in Circle.
if you modify your Circle as below it will work
class Circle {
public Circle(){
}
}
problem 2
There is "base.circleArea" method only present in Circle, you have forgot "()"
base.circleArea need to change to base.circleArea().
public class Cylinder extends Circle {
public double getVolume() {
return base.circleArea() * height;
}
}
Problem 3
Your Cylinder should be like below. You are already extended circle so no need to create variable Circle base inside Cylinder.
class Cylinder extends Circle {
public double height;
public Cylinder(double r, double h) {
super(r);
height = h;
}
public double getVolume() {
return circleArea * height;
}
}

Categories