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.
Related
I want to handle this exception thrown from Circle.getArea() method using Aspectj.
Shape.java
package Shapes;
public class Circle {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getPerimeter(){
return 2 * Math.PI * this.radius;
}
public double getArea(){
return Math.PI * this.radius * this.radius;
}
}
Rectangle.java
package Shapes;
public class Rectangle {
private double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
public double getPerimeter() {
return 2 * (this.width + this.height);
}
public double getArea() {
return this.width * this.height;
}
}
Circle.java
package Shapes;
public class Circle {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
public double getPerimeter() {
return 2 * Math.PI * this.radius;
}
public double getArea() {
throw new RuntimeException("Oops, I don't know how to calculate this :(");
}
}
Main.java
package Shapes;
public class Main {
public static void main(String[] args) {
try {
Shape s;
s = (Shape) new Rectangle(2, 10);
System.out.println("The area of " + s + " is " + s.getArea());
s = (Shape) new Rectangle(-2, 10);
System.out.println("The perimeter of " + s +" is " + s.getPerimeter());
s = (Shape) new Circle(-2);
System.out.println("The perimeter of " + s +" is " + s.getPerimeter());
s = (Shape) new Circle(2);
System.out.println("The area of " + s + " is " + s.getArea());
}
catch(Exception e) {
System.out.println("Error: " + e.getMessage());
}
}
}
Resolve.aj
package Shapes;
privileged public aspect Resolve {
declare parents: Rectangle implements Shape;
declare parents: Circle implements Shape;
public String Rectangle.getName(){
return "Rectangle";
}
public String Circle.getName(){
return "Circle";
}
public String Rectangle.toString(){
return this.getName()+"("+this.width+","+this.height+")";
}
public String Circle.toString(){
return this.getName()+"("+this.radius+")";
}
after() throwing(RuntimeException e) : execution(* Circle.*()){
handleException();
}
protected void handleException()
{
System.out.println("Error detected");
}
}
The current output is:
The area of Rectangle(2.0,10.0) is 20.0
The perimeter of Rectangle(-2.0,10.0) is 16.0
The perimeter of Circle(-2.0) is -12.566370614359172
Error detected
Error: Oops, I don't know how to calculate this :(
I want to avoid printing "Error: Oops, I don't know how to calculate this :(", and I need to get the real area of the circle object at the end.
But, I cannot change any .java file. All changes should be using Resolve.aj file.
You need to use the around advice instead of the after:
Object around () : execution(* Circle.*()){
try {
return proceed();
}
catch(Exception e)
{
handleException();
}
return null;
}
Code output:
The area of Rectangle(2.0,10.0) is 20.0
The perimeter of Rectangle(-2.0,10.0) is 16.0
The perimeter of Circle(-2.0) is -12.566370614359172
Error detected
The area of Circle(2.0) is 0.0
Why are we using the around advice instead of the after?
Very informally, an around advice intercepts a given joinpoint, and can inject new behavior before, after, and instead of that joinpoint. The proceed is a special feature that allows the around advice to continue the execution of the joinpoint.
From the types of advice supported by AspectJ (i.e., before, after, and around), the around advice is the only one allowed to return a value and/or use the proceed. This makes it possible for an around advice to execute several times the same joinpoint, or not executed it at all. Furthermore, you can even execute the intercepted joinpoint with a different context (e.g., change the value of the method arguments).
More information about how the advice and proceed works can be found on this SO Thread.
Our around advice will intercept all the execution joinpoint of the methods from the class Circle, and will handle accordingly the exceptions thrown by those methods.
How should I pass the "type" parameter of a constructor in an if/else statement? For eg - cal(2,2,0,rectangle). So if the type=rectangle then calculate area of a rectangle. If type=circle, calculate the area of a circle.
I am using a single constructor. My issue is that I know the logic but I can't write it in syntax. I am using Java or Apex.
I want to use if-else statement. How should I pass the type parameter in the code?
My program is like this -
if "type"=square, the compiler will call calculate area of the square.
if "type"=circle, the compiler will call calculate area of the circle.
public class Area {
private String type;
private Integer length;
private Integer breadth;
private Integer height;
private Integer area;
public void setType(String t){
type=t;
}
public void setLength(Integer l){
length=l;
}
public void setbreadth(Integer b){
breadth=b;
}
public void setheight(Integer h){
height=h;
}
/* public void setArea(Integer a){
area=a;
} */
public Integer getLength(){
return length;
}
public Integer getbreadth(){
return breadth;
}
public Integer getheight(){
return height;
}
public string gettype(){
return type;
}
public Integer AreaRectangle(){
return area=length*breadth;
}
public Integer AreaSquare(){
return area=length*length;
}
public integer AreaTriangle(){
return area=1/2 *(breadth*height);
}
public Area(){ // default constructor
length=9;
breadth=2;
height=7;
}
public Area(String t,Integer l ,Integer b,Integer h ){ // parameterised constructor
type=t;
length=l;
breadth=b;
height=h;
}
}
You don't. You create an abstract class called shape.
public abstract class Shape {
abstract double area();
}
And then two other classes that extend Shape and each provides the proper implementation
public class Square extends Shape {
private int side;
public Square(int side) {
this.side = side;
}
public double area() {
return (double) side * side;
}
}
Now at the place you want to call it:
Shape shape = new Square(5);
double area = shape.area();
Int radius = 4;
shape = new Circle(radius);
double circle area = shape.area();
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
The method that I am having trouble with is the "getTotalCost" method.
Each method is as follows:
DemoRoomCarpet
package cnmt.sec01.homeworkassign05;
import javax.swing.JOptionPane;
public class DemoRoomCarpet {
private static double length;
private static double width;
private static double cost;
public static void main(String[] args) {
length = Double.valueOf(JOptionPane.showInputDialog("What is the length of your carpet?"));
width = Double.valueOf(JOptionPane.showInputDialog("What is the width of your carpet?"));
cost = Double.valueOf(JOptionPane.showInputDialog("What is the cost per square foot of carpet?"));
RoomDimension myRoomDim =
new RoomDimension(length,width);
RoomCarpet myRoomCarpet =
new RoomCarpet(cost);
myRoomDim.setLength(length);
myRoomDim.setWidth(width);
myRoomCarpet.setCarpetCost(cost);
myRoomCarpet.getTotalCost();
myRoomCarpet.toString();
}
}
RoomDimension
package cnmt.sec01.homeworkassign05;
public class RoomDimension {
private double length,
width;
public RoomDimension(double length, double width)
{
this.length = length;
this.width = width;
}
public RoomDimension(RoomDimension object)
{
length = object.length;
width = object.width;
}
/**
* #return the length
*/
public double getLength() {
return length;
}
/**
* #param length the length to set
*/
public void setLength(double length) {
this.length = length;
}
/**
* #return the width
*/
public double getWidth() {
return width;
}
/**
* #param width the width to set
*/
public void setWidth(double width) {
this.width = width;
}
public double getArea()
{
double area = length * width;
return area;
}
public String toString() {
String str = "Length is: " + length + "\nWidth is: " + width + "\nArea is: " + this.getArea();
return str;
}
}
and RoomCarpet
package cnmt.sec01.homeworkassign05;
public class RoomCarpet {
private RoomDimension dim;
private double carpetCost;
public RoomCarpet(double carpetCost)
{
this.carpetCost = carpetCost;
}
public RoomCarpet(RoomCarpet object)
{
carpetCost = object.carpetCost;
}
/**
* #return the carpetCost
*/
public double getCarpetCost() {
return carpetCost;
}
/**
* #param carpetCost the carpetCost to set
*/
public void setCarpetCost(double carpetCost) {
this.carpetCost = carpetCost;
}
public double getTotalCost()
{
double total = dim.getArea() * carpetCost;
return total;
}
public String toString()
{
String str = "Your total cost is " + this.getTotalCost() + " dollars";
return str;
}
}
I feel like the issue is something minor that I am missing, but I could be wrong. Apologies for no comments, but I will add them once I get over this error. Passing the getTotalCost method gives a null pointer exception, but I believe that I passed the user input through it.
Thats because, RoomDimension dim is not been initialized. The field has to be initialized either using constructor or through setter.
In RoomCarpet class:
public RoomCarpet(double carpetCost, RoomDimension dim)
{
this.carpetCost = carpetCost;
this.dim = dim;
}
In main:
RoomCarpet myRoomCarpet =
new RoomCarpet(cost, myRoomDim);
What does it mean to write another constructor that takes a reference to GeometricObject, which points to an object rather than null?
And how can I Initialize this object to be an independent copy of the parameter object?
The following code is the GeometricObject class.
public class GeometricObject {
public String color = "white";
public double area = 0;
public double perimeter = 0;
public boolean filled;
/** Construct a default geometric object */
public GeometricObject() {
}
public GeometricObject(String color, boolean filled){
this.color = color;
this.filled = filled;
}
/** Return color */
public String getColor() {
return color;
}
/** Return area */
public double getArea(){
return area;
}
/** Return object */
public GeometricObject copy() {
return null;
}
/** Return perimeter */
public double getPerimeter(){
return perimeter;
}
/** Set a new color */
public void setColor(String color) {
this.color = color;
}
/** Return filled. Since filled is boolean,
* the get method is named isFilled */
public boolean isFilled() {
return filled;
}
/** Set a new filled */
public void setFilled(boolean filled) {
this.filled = filled;
}
#Override
public String toString() {
return "\ncolor: " + color + " and filled: " + filled;
}
It basically means that your constructor takes in another object of the same class, and instantiates a new object using its values.
public GeometricObject(final GeometricObject other){
this.color = other.color;
this.filled = other.filled;
//copy other member variables
}
Then, if you have an object, you can create a copy of it like this:
final GeometricObject geometricObject = new GeometricObject();
//do stuff to geometricObject, give values to variables, etc
final GeometricObject copy = new GeometricObject(geometricObject);
so your should create your constructor like that
public GeometricObject(GeometricObject original){
if (original != null) {
this.color = original.color;
... other variables ...
}
}
I was wondering if I could get some help with my length and width. I dont know how to get them into the format of being a string. I thought about the toString() idea, but then I think I would need a char value for that. Any help would be amazing.
public class Rectangle
{
// instance variables
private int length;
private int width;
/**
* Constructor for objects of class rectangle
*/
public Rectangle(int l, int w)
{
// initialise instance variables
length = l;
width = w;
}
// return the height
public int getLength()
{
return length;
}
public int getWidth()
{
return width;
}
public String String()
{
return System.out.println(length + " X " + width);
}
}
I have changed your String() method to toString() which I overrided. This method is used when we need a string representation of an object. It is defined in Object class. This method can be overridden to customize the String representation of the Object.You can check this
public class Rectangle
{
// instance variables
private int length;
private int width;
/**
* Constructor for objects of class rectangle
*/
public Rectangle(int l, int w)
{
// initialise instance variables
length = l;
width = w;
}
// return the height
public int getLength()
{
return length;
}
public int getWidth()
{
return width;
}
#Override
public String toString()
{
// TODO Auto-generated method stub
return length + " X " + width;
}
}
class Main{
public static void main(String[] args) {
Rectangle test = new Rectangle(3, 4);
System.out.println(test.toString());
}
}
Rename String() method to toString() (the method that normally returns an object string representation) and return from it length + " X " + width.
You can use String as a method name, but it violates JCC and looks abnormally.
Methods should be verbs, in mixed case with the first letter
lowercase, with the first letter of each internal word capitalized.
Examples:
run();
runFast();
getBackground();
Try this.
public class Rectangle {
// instance variables
private int length;
private int width;
/**
* Constructor for objects of class rectangle
*/
public Rectangle(int l, int w)
{
// initialise instance variables
length = l;
width = w;
}
// return the height
public int getLength()
{
return length;
}
public int getWidth()
{
return width;
}
#Override
public String toString()
{
return length + " X " + width;
}
public static void main(String[] args) {
Rectangle rec = new Rectangle(8, 9);
System.out.println(rec.toString());
}
}