I am doing a project for CS, and I just realized that I do not understand the mechanics behind the this. java reference and getters. Specifically, if I have the following:
class Circle{
private int radius;
}
public Circle(int radius){
this.radius = radius;
}
public int getRadius(){
return radius;
}
Why is it that for the constructor, I use this.radius to reference the data field "radius" in the Circle class, but for the constructor, I have this.radius = radius?
Does it make a difference whether or not I use the this. so long as it is the only data field named radius?
I just tested it on Sublime, and it outputs the same result.
Just according to my own logic, would it not make more sense to use this.radius to return the radius in the getRadius() getter instead of just return radius because I am referring to the data field in the object Circle?
I really appreciate all the help I can get!
It's because radius is the name of both parameter of constructor and field of the class. To disambiguate those this keyword is used. In case of getter this is not needed, but also won't hurt. Some formatters add this by default, it's equivalent to:
public int getRadius(){
return this.radius;
}
You don't need this in the constructor if you do not shadow the local name. That is with
public Circle(int r){
this.radius = r;
}
You can write
public Circle(int r){
radius = r;
}
The this is only required when it is used to specify which radius you are referring to.
Actually when you refer to this.radius that means you use a class field variable. Otherwise (in your code) you may re-assign your radius as an argument in a given constructor that is may be unwanted in your case. To distinguish it you must either use different name of a variable or use this.
Related
I'm trying to create a class Figure with subclasses like rectangle, triangle and circle. However, when I try to compile them I get the same error in all of them, which makes me believe that the error is in the Figure class. The error: cannot reference height before supertype constructor has been called.
Figure:
public abstract class Figure{
public double width;
public double height;
public Figure(double width, double height){
this.width = width;
this.height = height;
}
public abstract double area();
public abstract double perimeter();
}
Ellipse:
public class Ellipse extends Figure{
private double a;
private double b;
public Ellipse(){
a = width/2;
b = height/2;
}
public double area(){
return (Math.PI * a * b);
}
public double perimeter(){
return (2 * Math.PI * Math.sqrt((Math.pow(a,2) + Math.pow(b,2)))/2);
}
}
Thank you very much.
So your constructor for Ellipse does not call the inherited constructor of Figure. Yet you are are trying to use variables of Figure that are assigned values in the constructor of Figure. You need to update your Ellipse constructor to call the super with values. I recommend the following.
public Ellipse(int w, int h){
super(w,h);
a = width / 2;
b = width / 2;
}
You need call super class constructor in Ellipse:
public Ellipse(){
super(_width, _height)
a = width/2;
b = height/2;
}
You need to initialized you height and width, that are currently present in your Figure class. You can do this by specifically calling the Figure constructor from Ellipse, something like this.
public Ellipse(){
super(23, 23);
a = width /2;
b = height/2;
}
The super() method calls your Figure constructor, which will then initialized height and weight allowing you to use them to calculate a and b accordingly.
Every class has to call the constructor of its superclass as the first instruction in each of its own constructors[1]
This is done implicitly if the superclass has a default constructor (one without parameters). But if it has only a constructor with parameters, then you have to write that call yourself. You do that by using the word super and passing the appropriate parameters.
This is done so that the logical part of the current class that is inherited from the superclass can properly be initialized.
You have two possible solutions:
Add a default constructor to Figure. Perhaps one with default width and height of zero:
public Figure() {
this( 0.0, 0.0 );
}
This makes sense if there is a sensible default value for the width and height.
Change the constructors of the subclasses so that they accept (at least) width and height as well:
public Ellipse(double width, double height){
super(width, height);
a = width/2;
b = height/2;
}
This makes sense if there is no sensible default for the width and height.
The way you have tried doing this, there would be no values for width and height, so you couldn't possibly use them in the subclass (e.g. width/2 would be zero, because there was nothing that put any value in width, because nobody called the constructor of Figure). When you create an instance, there is no other place where the superclass constructor that sets width and height will be called - therefore all constructors have to start by calling their superclass constructors first.
[1] It's also OK to call one of the other constructors of the same class - if it has more than one - provided that ultimately, the constructor that gets called calls one of the supeclass constructors.
You need to call super as the very first thing in each constructor of every subclass of Figure:
public Ellipse(double ewidth, double eheight){
super(ewidth, eheight);
a = width/2;
b = height/2;
}
That is necessary because you use width and height, which are a member of Figure and are only getting initialized when the Figure constructor is executed, which is what the super call does. You basically used an uninitialized variable.
So why did I call the new parameter ewidth instead of width? Would I have named them width, the fields of the same name in the parent class would have been obscured by the local variable of the same name. In your example that would not have been a problem because the code path in both constructors is dead simple, but I'd like to raise awareness for this because it is a source of obscure bugs :)
Similar question has already been answered.
Refer to this:
java call superclass from a subclass constructor?
To add that if you had a non-parameterised constructor in your superclass then you wouldn't have to place an explicit call to the constructor of the superclass.
Also check this:https://docs.oracle.com/javase/tutorial/java/IandI/super.html
There is a note on this page: 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. Object does have such a constructor, so if Object is the only superclass, there is no problem.
I'm taking an object oriented programming class and I'm having some difficulty understanding how to build a circle object that lets the user declare what the radius is.
I created a data class and in it I put my instance variable, my getter and setter methods, my constructor, and then the basic computational function methods to compute the area and perimeter of the circle with a given radius.
Here is that class:
package shapesoo;
public class CircleDataClass {
private double radius;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public CircleDataClass(double radius) {
this.radius = radius;
}
public double getArea(){
return Math.PI * radius * radius;
}
public double getCircumference(){
return 2 * Math.PI * radius;
}
}
Then, I am creating a test class that builds the circle with the given radius and in my main method I create the new circle object with:
CircleDataClass myCircle = new CircleDataClass(radius);
I don't have radius declared anywhere in this test class so that's why I am getting a run-time error. But what I want is a user to input the value for that radius parameter that I have in my constructor and then have that radius passed to this circle object. Do I create a separate method in my main class that asks for the value of the radius? I think I am getting confused with what getters/setters/cosntructors are doing and how to pass the radius variable around to different classes.
EDIT: If I put this in, is the instance variable from my data class even used?
public static void main(String[] args) {
String shapeType = getShape();
if (shapeType.equalsIgnoreCase("Circle")){
String r = JOptionPane.showInputDialog("What is the radius: ");
double radius = Double.parseDouble(r);
CircleDataClass myCircle = new CircleDataClass(radius);
}
}
I know how to do this without using object-oriented principles and I am aware this must seem elementary to many of you but I would appreciate any help on it.
I don't have radius declared anywhere in this test class so that's why I am getting a run-time error.
Ok, that's normal
But what I want is a user to input the value for that radius parameter that I have in my constructor and then have that radius passed to this circle object. Do I create a separate method in my main class that asks for the value of the radius?
Yes. Basically, you can read the standard input for the user to enter a number and then instantiates the circle with it. See the Scanner class.
I think I am getting confused with what getters/setters/cosntructors are doing and how to pass the radius variable around to different classes.
The constructor is used to create and initialise an instance of a class.
The getter(s) gives read-only access to properties of your instance. In your case, if you want to check what is the radius of a particular instance of circle, you can have it through myCircle.getRadius().
The role of setter(s) is to mutate an instance, i.e. to change internal properties. It may not be good practice to have setters and can be better to create a new object when there is a need to change a property. This really depends on your design and context.
I'm just learning the ropes of overloaded methods. Here is an assignment in which I have to write the overloaded methods in the incomplete CircleStats class, but I have no idea how to set them up. I am supposed to find the circumference of a circle using its diameter/radius.
I understand that I have to make functions for finding circumference using the diameter, then using the radius, but don't know where to go from there. I also know that the radius will be double and the radius will be int, but am completely ousted with how to fill in the //code goes here part.
It would also be wonderful if someone could explain how to set up the math in each overload method to calculate circumference.Thanks in advance!
EDIT: In lines 21 and 22, it should be cStats.calcCircleCircumf instead of cStats.calcCircleArea
/* The calcCircleCircumf( ) method in the CircleStatsTester class is overloaded. Write the overloaded methods in the incomplete CircleStats class.*/
class CircleStats
{
CircleStats()
{
}
//…code goes here
}
public class CircleStatsTester
{
public static void main(String[] args)
{
int diameter = 5;
double radius = 2.5;
CircleStats cStats = new CircleStats();
System.out.println("The area = " + cStats.calcCircleArea(diameter));
System.out.println("The area = " + cStats.calcCircleArea(radius));
}
}
That is basically impossible.
Overloading a method consists in having two methods with the same name, but with a different signature (i.e. with a different number of arguments and/or arguments of different types).
Since a radius and a diameter have the same type, Java has no way to distinguish
calcCircleCircumf(double radius)
from
calcCircleCircumf(double diameter)
So you need two methods with different names:
computeCircumferenceFromRadius(double radius)
computeCircumferenceFromDiameter(double diameter)
and this is not overloading anymore.
Note about naming: these methods are part of a class named CircleStats. So puttin "Circle" in the method name is redundant and only adds noise. Using complete words makes the code more readable though, and that's the convention in Java. Hence computeCircumferenceFromRadiusand not calcCircleCircumf.
Even though this looks odd to me, but I think this is what you are asking.
public int calcCircleCircumf(int radius)
{
return (int)(2 * Math.PI * radius);
}
public double calcCircleCircumf(double diameter) //method overloading
{
return (2 * Math.PI * (diameter/2));
}
I think this is what you want.
Method overloading means that you have same method names, but different method signature.
Method signature includes
Method name
Method parameter type
Method parameter sequence
To overload a method, simply create another method of the same method name with a different signature.
Example:
public int getArea(int x)
{
}
public double getArea(double x) //Signature is different, method overloading occurs
{
}
public int getArea(int x, int y) //Signature is different, method overloading occurs
{
}
Note that the return type does not affect the method signature.
It is incorrect if you want to implement method overloading, yet providing different method names.
I was wondering what the best way of documenting this potential Point class is:
public class Point {
/* the X coordinate of this point */
private int x;
/* the Y coordinate of this point */
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
My concrete concern lies with the repetition between the x and y attributes and their respective getters and setters, as well with the constructor arguments.
It's not that I'm developing a public API or anything of the likes, it's no problem for me to have a general comment regarding some variable and then having the getter and setter have just the same text, for instance. I'd just like to avoid comment repetition in my own internal code. Is there a way to tie getX() and the int x argument of the constructor to the x attribute, for instance?
Thanks
Is there a way to tie getX() and the int x argument of the constructor
to the x attribute, for instance?
No, not that I'm aware of. What I do:
don't comment getters (or setters) at all
if X needs contextual information and if it somehow represents (part of the) state of the class I document it in the class-level Javadoc only
One obvious convention would be not writing JavaDoc comments for trivial getters.
I am trying to access a private final static double from another class.
Here is the class:
public class coolMath{
private final static double alpha = 5.87;
public coolMath(){
}
public static double calDistance(double x1, double y1, double x2, double y2){
double dist = Math.sqrt(Math.pow((x2-x1), 2) + Math.pow((y2-y1),2));
return dist;
}
}
I need to access the variable alpha in another class. Is this possible? Does something need to happen in the constructor to make it available? Any ideas?
Either make alpha a public field or provide a public static double getAlpha() that returns it.
If you make the field public, you access it like so double a = coolMath.alpha.
Otherwise, double a = coolMath.getAlpha();
I strongly suggest you go through java modifiers again.
This could technically be possible through some esoteric reflection methods, but I highly discourage it. It's better to change the visibility of your alpha variable or write some method that returns it (or perhaps sets it, if you need that also (but not if your var is final)).