OOP - Accessing Objects Via Reference Variables with Instance Classes - java

I am learning Classes and Objects, and I am on reference variables, and accessing an object's data and methods. In my textbook, we created a program which calculates the area of a circle, given the radius.
They declare the object reference variable, create an object, and assign the reference to a variable here:
Circle myCircle = new Circle();
They later give an example below of finding the area (getArea()* just returns the area given the radius):
System.out.println("Area is " + new Circle(5).getArea());
Is the 5 (number in parentheses) an input for the radius?
If so, why isn't it in the getArea() parentheses?
Also, there are no arguments for Circle() so how can you have a number in the () anyway?
*Code for getArea():
By the way, could you get rid of the parentheses if there is only one statement inside?
double getArea()
{
return radius * radius * Math.PI;
}
Please excuse the horrid formatting - I wasn't able to use Ctrl-K, could someone edit it for me please.

Is the 5 (number in parentheses) an input for the radius?
System.out.println("Area is " + new Circle(5).getArea());
Not exactly.
It is the argument passed to a Circle constructor that should very probably value a radius field.
If so, why isn't it in the getArea() parentheses?
getArea() is an instance method of Circle. It relies on the state of the Circle instance that has already a radius information.
So passing a radius argument to getArea() makes no sense.
It would make sense if you had a utility static method in the Circle class to compute a area according to a radius.
For example :
public static double computeArea(double circleRadius){
...
}
You could invoke it in this way :
double area = Cicle.getArea(5.5);
Also, there are no arguments for Circle() so how can you have a number
in the () anyway?
Without a Circle constructor that accepts a radius information, the invocation new Circle(5) cannot compile. So it of course requires one.
You should have a Circle constructor defined such as :
public class Circle{
...
private double radius;
public Circle(double radius){
this.radius = radius;
}
}
by the way, could you get rid of the parentheses if there is only one
statement inside?
Parenthesis () refers to a specification of the Java language to declare method and constructor.
When you declare a method, you need it in any case.

I will try to explain in deep:
public class Circle {
// this variable can access only inside class
private final double radius;
// constructor for class Circle
public Circle(double rad) {
radius = rad;
}
// method of class Circle - can be access outside
public double area() {
return radius*radius*Math.PI;
}
}
when you instantiate class Circle as Circle circle5 = new Circle(5); you got instance of class Circle with encapsulated parameter radius = 5 now, you don't know any details, and just call method double area = circle5.area() to get the area of circle (rad*rad*Pi).
This is dramatically decrease complexity. Even in this very simple example.
now you can print you result
System.out.println(area);
I think, you got the idea.
1st step: you instantiated class and encapsulated all details into it via constructor;
2nd step: you can use you class (methods of the class) and never aware about implementation detail.
And in you sample, calling constructor without parameters new Circle() instead new Circle(5) - this is typographic mistake.

First let me explain constructors in Java.
There are two types of constructors in java: 1. Explicit and 2. Implicit.
Explicit means a constructor with argument and developed by developer.
Implicit means, default or non parameter constructor.
In your case let me analyse the operation:
System.out.println("Area is " + new Circle(5).getArea());
new Circle(5), actually means that invoking a n explicit constructor with input parameter 5.
According to your shared knowledge, it can be understood that a radius is set in this explicit constructor.
I mean, the following constructor should be exist:
public Circle(int i) {
radius = i;
}

Related

.getWidth(), .getHeight() in Java

So I just started learning Java yesterday coming from a different language, and I am reading through my textbook and finding it to be pretty nice so far. However I did an exercise that basically required me to create a new Object use Rectangle and find the area. Below is the working code I came up with.
Now coming from other programming languages I was just toying around with this and did int area,width,height;and then it gave me an error saying that I had to use double in order to utilize .getWidth();, .getHeight(). I couldn't find anything in my book telling me why I had to make this a double and I started looking online and found this link
Now I found some documentation online where It told me to use double as well, but I'm not really sure why would I need to set these as doubles. Is it because the people who made Java, knew that precision is needed when we are working with coordinates and doing math with widths, heights and coordinates? My book says that it takes more memory to make a double variable rather than an int ( I come from doing lots of javascript and PHP, so reading on what a float and double does was something good for me).
I.E. Why do I need to make my area,height,width variable doubles in order to use .getWidth,.getHeight
package keepo;
import java.awt.Rectangle;
public class tuna{
public static void main(String [] args){
Rectangle rect = new Rectangle(10,20,50,40);
double area,width,height;
width = rect.getWidth();
height = rect.getHeight();
area = width * height;
System.out.println("Width is : " + width + "Height is : " + height);
System.out.println("Area is : " + area);
}
}
It is because this is how these methods have been defined in the java api. As you can see under the modifier and type column that the methods getWidth(), getHeight() all return value of type double.
Because in this case, you should not use those methods. The AWT class Rectangle does store coordinates as ints. You can easily read them back as ints if that's what you want to do, by accessing the fields instead of calling the getter methods:
int area, width, height;
width = rect.width; // not getWidth()
height = rect.height; // not getHeight()
area = width * height;
The getWidth() and getHeight() methods serve zero purpose here, as they will always return the same value as the fields, except as a different type (and you can already assign any int value to a double anyway, when a double is what you want to use).
So why do those two methods (along with getX() and getY()) exist at all? Because in Java 1.2 the geometry stuff in the API was expanded. People wanted to be able to work with floating-point coordinates, which Rectangle cannot do. And the Java maintainers couldn't change the fields of Rectangle from int to double because that would break backwards compatibility with how old code was already using it. So two new classes, Rectangle2D.Float and Rectangle2D.Double were added, which store coordinates as floats and doubles respectively.
But what if you want to work generically with any rectangle, without writing separate code for all the rectangle flavors? A new abstract class, Rectangle2D was also added, as the superclass of the three rectangle classes. This class is abstract (meaning it cannot be created on its own, as it is incomplete) and it does not store any coordinates itself. It does however, specify a contract that its subclasses follow (meaning that any Rectangle2D method is available in all three of its implementations). That includes the getWidth() and getHeight() methods that return doubles, regardless of the actual storage type of the particular rectangle.
Taking the abstraction an extra, perhaps superfluous, level, they also added RectangularShape as the superclass of several shapes with rectangular bounds: Rectangle2D, RoundRectangle2D, Ellipse2D and Arc2D. That is the class that actually declares the getWidth() and getHeight() methods, which all RectangularShape subclasses must provide:
// What's this shape? A rectangle? An ellipse? Does it use ints? floats? doubles?
RectangularShape something = ......;
// We don't care!
System.out.println("The shape (whatever it is) occupies an area of:");
System.out.println(something.getWidth() + " × " + something.getHeight());
So you can call those getter methods on any rectangle (or "rectangular shape") to get its coordinates, but if you know you have a particular shape class, you can/should access its fields directly, as that is simpler, and it gives you the values without converting them to a different type.
P.S. It is a similar story with Point, which uses int coordinates, but provides double getX() and double getY() methods, because of the later-added classes Point2D.Float, and Point2D.Double, and the abstract superclass Point2D.
P.P.S. There is actually a small advantage to using double (or long) for your rectangle's area, even if your rectangle coordinates are ints. Large multiplications could overflow the 32-bit range of an int, producing the wrong result. If you convert at least one of the values to a larger type, it will cause the multiplication to be done in that larger type, which you can then safely store without overflow:
Rectangle big = new Rectangle(0, 0, 1000000, 1000000);
int area = big.width * big.height;
long bigArea = (long)big.width * big.height;
System.out.println(area); // -727379968 (uh oh!)
System.out.println(bigArea); // 1000000000000
Imran Ali is right.
This is java documentations for getHeight() and for getWidth() it's same.
java.​awt.​Rectangle
public double getHeight()
Returns the height of the bounding Rectangle in double precisionReturns:
the height of the bounding Rectangle.
But if you want/need to use int instead of double, use following codes for height and repeat them for width too:
using getSize() method which returns rectangle dimension then use it's fields (width and height)
int height = rect.getSize().height;
using data type casting
int height = (int) rect.getHeight();
int height = (int) rect.getSize().getHeight();
The Rectangle.getWidth() and Rectangle.getHeight()methods both return their values with double precision, as stated by others. It is easier if you just keep using them, in order to prevent the Rectangle's values from being changed on accident, by simply casting the value to an int:
int width = (int)rect.getWidth()
and int height = (int)rect.getHeight()

Object in Constructor Parameters: Create New Instance, or Assign Pointer?

If a class contains an object as an instance variable, and one of the constructors includes an object of the same type as a parameter, is it best practice to assign the argument to the instance variable, or to create a new object from the argument, and assign THE NEW OBJECT to the instance variable.
Here's an example from an exercise I'm working through:
public class MyCircle {
private MyPoint center; //contains variables int x and int y
private int radius;
//Non-controversial Constructor:
public MyCircle(int x, int y, int radius ) {
//creates new center using a valid MyPoint constructor
this.center = new MyPoint(x, y);
this.radius = radius;
}
//OPTION A
public MyCircle( MyPoint center, int radius ) {
this.center = center;
this.radius = radius;
}
//OPTION B
public MyCircle( MyPoint center, int radius ){
this.center = new MyPoint( center.getX(), center.getY() );
this.radius = radius;
}
}
Initially, I typed option A, but I thought that this could create buggy behavior if this.center referenced an existing object that could be modified indirectly unintentionally. The alternative way of thinking about it, I guess, is that this creates an avenue for creating multiple objects that share a center, and moving a single center would intentionally move all circles that share that center.
Since Java has no pointers (at least not for developers) that option will be discarded and is not the way to go..
Now this:
public MyCircle( MyPoint center, int radius ) {
this.center = center;
this.radius = radius; }
Is in my opinion better, you can just assign the center and don't need to make a risky copy of the class MyPoint... And I say risky because if you want to do that you should at least check the non-null condition of that parameter....
You can for sure think... what if center is null in option A, you are right, that can happen, then you can take care of it by either throwing an illegalparameterexception, or just assigning that object to a default value. ..
But as I said before is my opinion..
I think it depends on your program. If you want the circle to have a reference to the MyPoint object, then you must pass it. Otherwise, why not pass in the actually x and y values themselves.
For example, option B can be written as:
public MyCircle(int x, int y, int radius) {
// rest
}
both options are fine, but as you told, an object may change in the time, the option A is ok when you want to modify the center in more than one object at the same time, for example in an List of Circles, but if you want to have unique and independient center points, option B is correct. So you why don't you have both constructors and use one or another depending many cases in your app, use whatever you want you consider better, keep both, it is my advice.
Hope it helps to you.

Implementing classes that define three shapes in Java

I think I've implemented everything asked within these set of instructions:
Design and implement a set of three classes that define shapes: RoundShape, Sphere, Cone. For each class, store fundamental data about its size and provide methods to access and modify this data. In addition, provide appropriate methods to compute the area, and volume, for Sphere and Cone. In your design, consider how shapes are related and thus where inheritance can be implemented. Don't create duplicate instance variables. Create a main method which instantiates 2 Sphere objects (any parameters), 2 Cone objects (any parameters), display them with ToString(), change one parameter (your choice) in each, and display them again.
Here is my code:
class RoundShape{
double shape = 9;
double radius = 4;
int cone1 = 3;
int sphere1;
public String toString(){
return " the man" + cone1 + "this also" + sphere1;
}
}
//--------------------------------------------------------------
// class Sphere that extends RoundShape
//--------------------------------------------------------------
class Sphere extends RoundShape{
double getArea(){
double area = 4 * Math.PI * Math.pow(radius, 2);
return area;
} // end of getArea
double getVolume(){
double volume = (4/3) * Math.PI * Math.pow(radius, 3);
return volume;
} // end of getVolume
} // end of the class Sphere
//---------------------------------------------------------------
// class Cone that extends RoundShape
//---------------------------------------------------------------
class Cone extends RoundShape{
double height = 8;
double getArea(){
double area = Math.PI * radius * (radius + Math.sqrt(Math.pow(height, 2) + Math.pow(radius, 2)));
return area;
} // end of getArea for Cone
double getVolume(){
double volume = Math.PI * Math.pow(radius, 2) * (height/3);
return volume;
} // end of getVolume for Cone
} // end of the class Cone
public class Murray_A03A4 {
public static void main(String[] args) {
Sphere sphere1 = new Sphere();
sphere1.getArea();
sphere1.getVolume();
System.out.println(sphere1);
Cone cone1 = new Cone();
cone1.getArea();
cone1.getVolume();
System.out.println(cone1);
} // End of class header
} // End of method header
My main question is, how do I refer back to the toString method from content thats in the main method? Additionally, is the toString found within the correct class or should I place it in a new class or should I create a toString for every class?
Thanks for your help!
implement toString() methods in both Sphere & Cone. In those toString methods, put details specific to those classes and for the fields of the superclass invoke super.toString()
For Cone, it would be like :
public String toString() {
return height + super.toString();
}
Use super allows you to access parent class and interfaces.
Also, feel free to use casting:
var self = (BaseOfBase)super;
self.VirtualMethod();
Turned up a lil bit with csharps' base which is completely same.
I'm not quite sure what your question is but what I think you're trying to ask for is: "How to call the toString method on Sphere objects and Cone objects when in the main method they are simply RoundObject?"
You should Override the toString method in every class, and it should return the information relevant to that class. So the RoundObject does not need return the volume, just the radius (maybe something like return "RoundShape with radius " + radius;). Then you would do the same for sphere and cone, but it would also include the shapes volume.
Then in main, you can simply call the toString method on the RoundObjects. Because the toString method is an instance method (doesn't have the static keyword in its title) it is dynamically bound. Meaning, the method from the actual underlying object will be used.
I see that you are trying to pull sphere/cone fields (sphere1, cone1) into RoundObject but this is not required. (it's actually better for a parent to not know anything about child classes)
for more information, look up polymorphism, or this video.

Writing class method for test class

public class CirclTest{
public static void main(String[] args){
Circle first=new Circle('R',3.0);
Circle first=new Circle('R',3.0);
Circle second=new Circle();
System.out.println("first's radius is " + first.getRadius());
System.out.println("first's area is " + first.getArea());
System.out.println("second's area is " + second.getArea());
if(first.hasLargerAreaThan(20)){
System.out.println("first's area is larger than 20. ");
}else{
System.out.println("first's area is smaller than 20. ");
}
}
}
So i am supposed to write a circle class.This is what i have done.
public class Circle{
private double radius=0.0;
private double area=0.0;
private char colour=' ';
public Circle(char colour,double radius){
this.colour=colour;
this.radius=radius;
}
public Circle(){
radius=0;
colour='B';
}
public char getColour(){
return colour;
}
public double getRadius(){
return radius;
}
public double getArea(){
return area;
}
}
I am actually confused on how to write a class.Like i know i need to initialize the variables by private etc.And i need to build a constructor but somehow this code above does not work.the test method is correct.But i have to use it to implement my class.
You're declaring the variable
Circle first
twice. If you want to reassign its value, just do
first=new Circle('R',3.0);
And inside the if statement you're calling
first.hasLargerAreaThan(20)
when I don't see such a method defined in your class.
Can you please what you mean by the code does not work? If you are referring to area not getting calculated correct and is always 0, that is happening because you have a default value for the same as 0 and are never calculating it. You might want to put calculation logic in getArea() method.
First, you're going to want to use a testing framework to assert the validity of your code, if that's what is required. Look into JUnit.
A sample assertion of if the area was larger than some value would be written like this.
#Test
public void assertArea_calculatedProperly() {
//given that the radius is 5,
Circle c = new Circle('R', 5);
//when I get the area...
double result = c.getArea();
//then I expect it to be around 78.53981634.
assertTrue(result < 78.6);
assertTrue(result > 78.5);
}
Second, your getArea isn't actually getting the area. There's nothing in your code to retrieve, then calculate the area. You're not even using Math.PI. I would recommend that you implement that - but use the unit test as a valid way to assert that you're going to get an appropriate response back.

Adding up total in a class file

I'm pretty new to OOP, so any help is appreciated. I have a class file that takes some inputs and calculates the area of a triangle like such:
public class Triangle
{
private int base;
private int height;
private double area;
private String name;
private double totalArea = 0;
public void writeOutput()
{
System.out.println("Triangle name: " + name);
System.out.println("Triangle base: " + base);
System.out.println("Triangle height: " + height);
System.out.println("Triangle area: " + setArea());
System.out.println("Total Area: " + totalArea);
}
private double setArea()
{
area = (base * height) * 0.5;
return area;
}
private double setTotalArea()
{
totalArea += area;
return totalArea;
}
}
My problem is in the setTotalArea() method. Basically, it is supposed to add up a cumulative total of all the areas calculated, however, all it is doing is echoing the area and I can't figure out why. Any suggestions are appreciated!
You're mixing up setters and getters. For instance, your setArea() method is not a true "setter" method as it is private, accepts no parameter, sets nothing, and tries to return a value -- the exact opposite of most things a setter should do, and the same goes for your setTotalArea.
Anyway, sorry to say, but this code is borked, and I recommend you simply get rid of it and start over (it's not that big of a class yet, so this is no big deal), but start with your fields (height, base, and name), the constructor, perhaps one that sets class properties and with true public setter methods that actually accept parameters and use those parameters to set class fields. Then create your getter methods that return the values of the class fields. Your class shouldn't even have a setArea method or an area field since the area is a calculated value, not a set value, ant it should probably be calculated on the spot in the getArea() method and returned.
Edit, you state:
My problem is in the setTotalArea() method. Basically, it is supposed to add up a cumulative total of all the areas calculated, however, all it is doing is echoing the area and I can't figure out why. Any suggestions are appreciated!
Sorry, but I don't understand this. total of what areas? The class only describes one triangle and so there is no cumulative area concept here. Now if you have another class that holds an array or collection of Triangle objects, then a *get*TotalArea (not set total area) method would make sense as it would add the areas of all triangles in the collection, but you don't have this here.
I am not very clear to your execution but if -
Triangle t1 = new Triangle(); t1.setArea();
Triangle t2 = new Triangle(); t2.setArea();
Above 2 are seperate Objects , If you are using the above kind of Object creation , then you can not expect to get cumulative total as both object have their own copy of setArea method.

Categories

Resources