I already wrote a class Geom that represents three-dimensional, geometrical forms and works with the attributes double dx, dy, dz (the coordinates of the form) and String colour (the colour of the form). Now I am supposed to get more specific, and I want to write a class Cube that extends Geom and that works furthermore with the attribute edge length, in order to calculate things like the volume or area of the form.
In order to do so, I need to write a method private double length, which saves the length of the edges. Besides that, I need to implement get- and set-methods.
This should be quite easy actually, but I don't what I have to do here. I started like this:
public class Cube extends Geom {
int edge;
public Cube (double dx, double dy, double dz, String colour, double edge) {
super(dx, dy, dz, colour);
edge = ///I don't know what do to here
}
private double length(double edge) {
this.edge = edge;
return this.edge;
}
public double getEdge() {
double a = length();
return a;
}
public void setEdge() {
this.edge = edge
}
...
This doesn't seem to make much sense though. I receive two errors, one telling me that this.edge = edge is a lossy conversion from double to int and one telling me that double a = width(); isn't possible because the method width() cannot be applied to the given types. I don't quite see the sense of "saving" the length first, then getting it and setting it in the end.
public class Cube extends Geom {
first of all should encapsulate variables like this and create getter and setter for them.
private int edge;
public Cube (double dx, double dy, double dz, String colour, int edge) {
super(dx, dy, dz, colour);
if you want to be able construct the Geom object with a given edge
you need something like, and change the parameter type to int
this.edge=edge;
this will set the given parameter to your variable 'this' keyword means that you want to invoke to this class edge variable, as the parameter name is the same.
I don't know why you created method length here what it should return ??
As far as i can see it returns the edge, then its the getter job to do so.
}
private double length(double edge) {
this.edge = edge;
return this.edge;
}
You expect to return double while your edge variable is an int, probably want this.
public int getEdge() {
return edge;
or
return this.edge;
it doest matter on that point
}
and the setter should take a value that matches the variable
again you dont necessarily need to say this.edge as the compiler will know what to do as this is the only edge variable here.
public void setEdge(int value) {
this.edge = value;
}
then you can do your calculations and stuff in the length method and parse it to double if you need to, or if need double in the first place, just change the type of the edge to double
Related
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.
I have a class Rectangle laid out like this:
package Inheritance;
/**
*
* #author Jacob
*/
public class Rectangle {
final private int length;
final private int width;
public Rectangle (int l, int w)
{
length = l;
width = w;
}
public int getLength ()
{
return length;
}
public int getWidth ()
{
return width;
}
#Override
public String toString ()
{
return String.format ("Rectangle (%dX%d)", length, width);
}
}
I then need to create class square in the following way:
ad Square:
Square extends Rectangle /
No fields are declared in class Square /
It has a parameterized constructor with (only) one parameter /
The parameter is used to initialize both fields of Rectangle /
It has a method called getSide to expose the side-length of the square /
Override the toString method so that it will return a String of the following form: / Square(side) e.g. Square(4)
The values for the sides are going to be hard coded. Rectangle is going to have a width of 4. In order to get the side of the square to be 4 do I create an instance of rectangle and call the method getWidth and set that as the side length. Thats how I would think to do it but in that case I would only be using one of the fields so, My question is how do I initialize both fields? Can I call Rectangle and make length and width equal or is there some other way I should do it?
Here is the code for my Square class:
public class Square {
public Square (int side)
{
super(side, side);
}
public int getSide ()
{
return side;
}
#Override
public String toString ()
{
return String.format ("Square (%d)", side);
}
}
For the line super(side, side) I get the error constructor Object in class Object cannot be applied to given types. Required no arguments, found int, int. For my return statements I get that it cannot find the variable side.
The values for the sides are going to be hard coded.
I assume that you mean that you will hardcode the values for the width and length when you create a Rectangle and Square object (for example in main()). These values should absolutely not be hardcoded any where in the Rectangle and Square classes.
Rectangle is going to have a width of 4. In order to get the side of the square to be 4 do I create an instance of rectangle and call the method getWidth and set that as the side length.
Not at all. Rather, Square should have its own constructor which calls the Rectangle constructor with the same value for both the width and length:
public Square(int side) {
super(side, side); // Set the width and length to the same value.
}
Hi I had this assignment for my class:
Implement a class named Box that will have the following attributes and methods:
int length, width, height
String color
Constructor method that:
will initialize the 3 integers to 10, 8, 6
will initialize the color to “black”
A setter and getter method for each of the 4 attributes
A method to get the volume of the box
A method to get the surface area of the box (all six sides)
I have all my getters and setters for length width and color. My only problem now is that for volume it will not calculate properly if I set the values to be different.
It only takes the initialized values. Any Ideas to go about it? My code is below for the class. example I could .setLength(7) and instead of printing the total 7*8*6, it prints out the total of 10*8*6.
public class Box
{
private int height = 6;
public void se(int height){
this.height=height;
}
public int getHeight(){
return height;
}
private int width = 8;
public void setWidth(int width){
this.width=width;
}
public int getWidth(){
return width;
}
private int length= 10;
public void setLength(int length){
this.length=length;
}
public int getLength(){
return length;
}
private String color="Black";
public void setColor(String color){
this.color=color;
}
public String getColor(){
return color;
}
private int vol=length*width*height;
public void setVol(int vol){
this.vol=vol;
}
public int getVol(){
return vol;
}
}
Get rid of the vol property and the setVol setter; that's not part of the spec for the class and is the root cause of your problems. Rewrite getVol to compute the volume from the length, width, and height each time it is called.
Your current design doesn't work because vol is not recalculated whenever length, width, or height is changed. You could keep your current set of fields and rewrite the dimension setters to recalculate the vol property each time one is called. That would speed up the getVol getter method at the cost of greater complexity for the class design and slower setter methods. It's a trade-off that you can make or not, as you see fit. However, you need to get rid of the setVol method, because when you set the volume, there's no way to know how to set the dimensions so that the values are consistent.
You need to create a getter function for vol
e.g.
public int getVol () {
vol=length*width*height;
return vol;
}
of course the setting of the intermediate vol is not necessary.
and you could just
return length*width*height;
This ensure that the current vol is always correctly calculated.
This question already has answers here:
Java - access private instance variables
(6 answers)
Closed 9 years ago.
I'm not really sure how to word the title nor this but I'll try to be as specific as I can. I have created a class that contains a constructor that allows me to create objects of "Circle" type, and this circle has an argument radius. Here is that class:
public class Circle {
private double radius;
public Circle(double radius) {
this.radius = radius; // this.radius refers to the instance variable above
}
public Circle() {
}
public double getArea() {
double area = radius * radius * Math.PI;
return area;
}
public double getCircumference() {
double circumference = 2 * Math.PI * radius;
return circumference;
}
}
I think the methods contained in this code are straight forward. I create an object given a radius, and it computes the circumference and area.
I also have another class, CircleTester, where I have created 2 objects of Circle type, c1 and c2, with a radius of 5 and 10, respectively.
public class CircleTester {
public static void main (String[] args) {
Circle c1 = new Circle(5);
double circumference1 = c1.getCircumference();
double area1 = c1.getArea();
System.out.println("Radius of c1: " + c1.radius);
System.out.printf("The circle c1 with circumference %.3f has area %.3f%n", circumference1, area1);
Circle c2 = new Circle(10);
double area2 = c2.getArea(); //objectReference.methodName()
double circumference2 = c2.getCircumference(); //objectReference.methodName()
System.out.println("Radius of c2: " + c2.radius);
System.out.printf("The circle c2 with circumference %.3f has area %.3f%n", circumference2, area2);
}
}
I'm having errors with the following 2 lines:
System.out.println("Radius of c2: " + c2.radius);
System.out.println("Radius of c2: " + c2.radius);
The program is failing to recognize c2.radius as the instance variable "radius" is declared as private in the circle class.
My question is is there any way to allow the CircleTester program to read the values of the radius of each object, without changing the instance variable from private to public? c1.radius and c2.radius do not work - the error is "Circle.radius is not visible" (because it is private)**
The reason I don't want to make it public is because I've been told by my tutor that declaring an instance variable as public can be seen as bad programming, and we could possibly be penalized in the exam.
I'm sorry if this is vague or stupid - explaining has never been my strong point. I'm also fairly new to Java so I am not 100% sure if I'm using all my terms correctly.
Just make a getter method:
public double getRadius() {
return radius;
}
The simplest (and standard) way is to declare a "getter" method in the Circle class, i.e.
public double getRadius() {
return radius;
}
Alternatively, you could use reflection, but it is not meant to be used for cases like the one described in the question. So, a getter method is the solution.
The best way is to create a getter for you variable radius in your class Circle
public double getRadius(){
return radius;
}
and use
System.out.println("Radius of c2: " + c2.getRadius());
When you define an object, consider all the things you might like to ask of the object. For example, for a circle object you may want to ask the area, radius, diameter, circumference ... so
Don't get seduced into exposing the internal parameters of an object directly.
public class Circle {
private double radius;
public Circle(Double radius) { this.radius = radius;}
public double getArea() { return radius*radius*Math.PI; }
public double getRadius() { return radius;}
public double getDiameter() { return 2*radius;}
public double getCircumference() { return Math.PI*getDiameter();}
}
Just use getter to get the variable:
public double getRadius() {
return radius;
}
This is in fact a good programming practice. You could do a setter similarly if you wanted to alter this value.
While a getter method is the best way to go, here's an approach using reflection. I wouldn't recommend using this unless you want your Circle object to be effectively immutable.
Circle circle = new Circle(10.0);
Field radius;
try {
radius = circle.getClass().getDeclaredField("radius");
radius.setAccessible(true); // required since field is private
System.out.println(radius.getDouble(circle));
radius.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
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.