I was reading a java book, where I came across this statement:
So, every subroutine is contained either in a class or in an object
I'm really confused why does it say "class or in an object"
I would like some explanation.
Let's try this example
public class Demo {
public static void classMethod() {
System.out.println("Call to static method");
}
public void objectMethod() {
System.out.println("Call to object method");
}
public static void main(String[] args) {
Demo demo = null;
demo.classMethod();
//demo.objectMethod();// throws NPE if uncommented
}
}
This code will work (even if the demo variable is null) because static method classMethod is contained within the class Demo. The commented line will throw a NullPointerException because the method objectMethod is not contained in the class but in the object so will need an instance of Demo class to call it.
Subroutine is a method written inside a class. We use them to do various tasks. That statement states that these methods/subroutines are written in an object or a class.
If we have an object instantiated, it will create new methods for every non-static method for that object which were defined in the class of the object. Hence those non-static methods/subroutines are in the object.
But if the class is a static class, we can't have any objects from it. But we can use subroutines/methods of that class. So, they are in a Class
That's what your statement says.
EDIT:
I thought to give an example for this.
public class ExampleClass {
public String getNonStaticString() {
return "This String is From Non-Static Method";
}
public static String getStaticString() {
return "This String is From Static Method"
}
}
Then, if you need to get the static String, all you have to do is
String staticString = ExampleClass.getStaticString();
Note that I havn't created an object from the ExampleClass Here. I just used the method.
But, if you need to get the String from the non-static method, you should instantiate an object first.
ExampleClass exampleObject = new ExampleClass();
String nonStaticString = exampleObject.getNonStaticString();
static methods also known as class method. Static method associated only with the class and not with any specific instance of that class(object).
So, every subroutine is contained either in a class or in an object
The statement is technically not 100% correct.
First of all, subroutines in java are commonly called methods. The following two terms are often used interchangeably:
Method: A subroutine working with an object instance, this.
Function: A subroutine not working with an object instance.
Here is an example scenario which should you get an idea what that means:
public class Circle {
//region static code
//we cannot call "this" in a static context, main(String[]) is no exception here
public static void main(String[] args) {
Circle a = new Circle(0, 0, 10);
Circle b = new Circle(10, 10, 2);
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("circumference of a = " + a.getCircumference());
System.out.println("circumference of b = " + b.getCircumference());
System.out.println("area of a = " + a.getArea());
System.out.println("area of b = " + b.getArea());
System.out.println("distance of a, b = " + distance(a, b));
System.out.println("a, b intersect = " + (intersects(a, b) ? "yes" : "no"));
}
//we cannot call "this" in a static context, but we have the circles a, b as parameters we can use to calculate their distance
public static double distance(Circle a, Circle b) {
return Math.sqrt(squared(a.x - b.x) + squared(a.y - b.y));
}
//we cannot call "this" in a static context, but we have the circles a, b as parameters we can use to check for an intersection
public static boolean intersects(Circle a, Circle b) {
return a.radius + b.radius > distance(a, b);
}
//we cannot call "this" in a static context, but we have the number x as parameter we can use to calculate the square of
public static double squared(double x) {
return x * x;
}
//we cannot call "this" in a static context, but we have the number radius as parameter we can use to check if its value is in range
public static void checkRadius(double radius) {
if(radius < 0) {
throw new IllegalArgumentException("radius must be >= 0");
}
}
//endregion
//region member / instance code
private double x;
private double y;
private double radius;
public Circle(double x, double y, double radius) {
checkRadius(radius);
this.x = x;
this.y = y;
this.radius = radius;
}
//region getters and setters
//we may refer to the instance variables with or without "this", sometimes it is necessary to clarify - see: setX(double)
public double getX() {
return x;
}
//we may refer to the instance variables with or without "this", but in this case we have two variables with name "x"
//if we write "x", the parameter is taken. for the circle's x coordinate, we need to clarify with "this.x"
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
checkRadius(radius);
this.radius = radius;
}
//endregion
//we may refer to the instance variables with or without "this", sometimes it is necessary to clarify - see: setX(double)
public double getCircumference() {
return 2 * Math.PI * radius;
}
public double getArea() {
return Math.PI * squared(radius);
}
//we may refer to the instance variables with or without "this", sometimes it is necessary to clarify - see: setX(double)
#Override
public String toString() {
return "circle at [" + x + ", " + y + "] with radius " + radius;
}
//endregion
}
Output:
a = circle at [0.0, 0.0] with radius 10.0
b = circle at [10.0, 10.0] with radius 2.0
circumference of a = 62.83185307179586
circumference of b = 12.566370614359172
area of a = 314.1592653589793
area of b = 12.566370614359172
distance of a, b = 14.142135623730951
a, b intersect = no
Related
I make a class Figure then two subclasses from it. Figure super class have a method named are(). this is the all class.
public class Figure
{
public double a, b;
public Figure(double a,double b) {
this.a = a;
this.b = b;
}
public double are() {
return 0;
}
}
public class Rectangle extends Figure
{
Rectangle(double a, double b) {
super(a,b);
}
double area (){
return this.a*this.b;
}
}
class Triangle extends Figure
{
Triangle(double a, double b) {
super(a,b);
}
// override area for right triangle
double area () {
return a * b / 2;
}
}
to easy print outpute I make
public void toastM(String str) {
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
}
now I use this code
Figure f = new Figure(10, 10);
Rectangle r = new Rectangle(9, 5);
Triangle t = new Triangle(10, 8);
Figure figref;
figref = r;
toastM("are..... " + figref.are());
figref = t;
toastM("are..... " + figref.are());
figref = f;
toastM("are..... " + figref.are());
expected values are 45 40 0
but it come 0 0 0
The parent class has a method called
double are()
the child classes
double area()
so it's not overridden
The functions you are overriding in both Rectangle and Triangle are called area AND NOT are as in the Figure class
You are calling the are() function of the super class Figure, not the area() function the subclass.
We got the following exercice in our last exam, and I don't understand the right answers except the 1st one.
Here is it:
public class Gran {
private int x;
public Gran() { this.x = 68; }
public int age() { this.x = this.x+1; return this.x; }
#Override
public String toString() { return "Gran " + age(); }
}
public class Dad extends Gran {
private int x;
public Dad() { this.x = 41; }
#Override
public String toString() { return "Dad " + age(); }
}
public class Bro extends Dad {
private int x;
public Bro() { this.x = 21; }
#Override
public int age() { System.out.print("Bro "); return x; }
}
public class Sis extends Dad {
private int x;
public Sis() { this.x = 17; }
#Override
public int age() { System.out.print("Sis "); return super.age() - x; }
#Override
public String toString() { return "Sis " + super.toString(); }
}
What would be the correct print-outs if we call this:
Gran[] family = new Gran[] {new Gran(), new Dad(), new Bro(), new Sis()};
for (Gran member : family) System.out.println(member.toString());
It would be really helpful for me, if you tell me the logic behind the right answers.. I got really confused when I checked them!
You should check out the spec.
Especially Example 8.4.8.1-1. Overriding:
class Point {
int x = 0, y = 0;
void move(int dx, int dy) { x += dx; y += dy; }
}
class SlowPoint extends Point {
int xLimit, yLimit;
void move(int dx, int dy) {
super.move(limit(dx, xLimit), limit(dy, yLimit));
}
static int limit(int d, int limit) {
return d > limit ? limit : d < -limit ? -limit : d;
}
}
The caption says:
Here, the class SlowPoint overrides the declarations of method move of class Point with its own move method, which limits the distance that the point can move on each invocation of the method. When the move method is invoked for an instance of class SlowPoint, the overriding definition in class SlowPoint will always be called, even if the reference to the SlowPoint object is taken from a variable whose type is Point.
So with that in consideration, lets look at your example.
The hierarchy is:
Dad is a Gran
Bro is a Dad
Sis is a Dad
The declared type of all of the objects is Gran because of the line Gran[] family = new Gran[] {new Gran(), new Dad(), new Bro(), new Sis()}; That is the same as saying that the reference to each of the objects in the array are taken from a variable whose type is Gran.
Now you will call toString() on each of the elements in the family array. The first is Gran.toString(). When that object was created its x variable was initialized to 68. So the Gran.toString() method will build a String that is first "Gran" then call the age() method which increments x by one then returns the value of x which is 69 at this point. The + operator implicitly creates a new String that coerces the int to a String giving a String "Gran 69".
Next Dad.toString is very similar to Gran. Notice that it starts with the String "Dad" then calls age() which is inherited from Gran. So the output should be "Dad 69". The trick here is that the x variable is private scope, so the x in Dad is a different x then in Gran. That is the same for all of the classes.
For Bro, this class is a Dad, and Dad is a Gran. There is no overridden toString here so Dad.toString() gets used. That makes a String "Dad" then calls Bro.age() this prints "Bro" then returns the x from Bro to create a new String "Dad 21". The line is will look like "Bro Dad 21" because the print of "Bro" happens before the print of "Dad 21".
As for Sis this one is the toughest one. You should take everything from above and convince your self of how Overriding and scoping works. Good luck! I hope this helps.
This question already has answers here:
How do I pass a primitive data type by reference?
(8 answers)
Closed 7 years ago.
here is my code
public class Scale {
public static void main(String[] args) {
int x = 4;
int y = 3;
int faktor = 2;
skaliere(x,y,faktor);
System.out.println(x + " " + y);
}
public static void skaliere(int x, int y, int faktor){
// ?
}
}
I want to change the scale the x and y by faktor, not using a return value. Just by the skaliere method.
I want to change the scale the x and y by faktor, not using a return value. Just by the skaliere method.
Note that Java is not pass by reference, it's always pass by value.
Without any hack, simply you can't because they are primitives. If they are mutable objects, yes you can change their state.
That hack would be making them static and assigning values inside that method.
You can always make your own MutableInteger class
class MutableInteger{
private int value;
public MutableInteger(int v){
this.value = v;
}
public int get(){
return value;
}
public void set(int newValue){
this.value = newValue;
}
#Override
public String toString() {
return Integer.toString(value);
}
}
Then use it in your code:
public static void main(String[] args) {
MutableInteger x = new MutableInteger(4);
MutableInteger y = new MutableInteger(3);
int faktor = 2;
skaliere(x,y,faktor);
System.out.println(x + " " + y);
}
public static void skaliere(MutableInteger x, MutableInteger y, int faktor){
x.set(x.get() *faktor);
y.set(x.get() *faktor);
}
Since you are making your own class, you can even move the skaliere method into your MutableInteger
class MutableInteger{
...
public void skaliere(int faktor){
this.value *=faktor;
}
}
which makes your code look like this:
public static void skaliere(MutableInteger x, MutableInteger y, int faktor){
x.skaliere(faktor);
y.skaliere(faktor);
}
You don't even need the static method anymore
You could do this with an object that wraps the two values. This is because the object reference is passed to the method. If you pass a primitive which are immutable, they will never be changed on the return, it would only change a copy in the method. Using an object, you can pass the containing values and it would be the ones referenced by the main method when retrieved.
public static void main(String[] args) {
// org.eclipse.swt.graphics.Point
Point p = new Point(0, 0);
p.x = 4;
p.y = 3;
int faktor = 2;
skaliere(p,faktor);
System.out.println(p.x + " " + p.y);
}
public static void skaliere(Point p, int factor){
p.x *= factor;
p.y *= factor;
}
The purpose of this program is to print
the number of solutions and the solution(s) to a quadratic function,
entered by the user.
The problems here is that I get errors for having private variables,
why is this? Also for my constructor it states that my variables cannot be resolved even though
they are established in the main method. Finally, my variables will pass to the main method or to the "toString" method for use
in the main method.
This is for a school assignment and my professor requires that I use the "toString" method as well as have private variables. I apologize in advance for any formatting mistakes and for the large question, for I am new
to this site.
import java.util.Scanner
public class QuadraticSolver
{
private static Scanner in;
public static void main(String[]args)
{
QuadraticSolver qs = new QuadraticSolver();
in = new Scanner(System.in);
private double a;
private double b;
private double c;
System.out.println("Enter coefficients for quadratic function. ");
a = in.nextDouble();
b = in.nextDouble();
c = in.nextDouble();
qs.getRoot1(a,b,c);
qs.getRoot2(a,b,c);
qs.numOfSolutions(a,b,c);
System.out.println("Your quadratic function is " + a + "x^2 + " + b + "x + " + c);
System.out.println(qs.toString());
}
public QuadraticSolver()
{
a = 0;
b = 0;
c = 0;
}
public double getRoot1(double a,double b,double c)
{
private double root1;
root1 = (-b + Math.sqrt(Math.pow(b,2) - 4*a*c)) / (2*a);
return root1;
}
public double getRoot2(double a,double b,double c)
{
private double root2;
root2 = (-b + Math.sqrt(Math.pow(b,2) - 4*a*c)) / (2*a);
return root2;
}
public int numOfSolutions(double a,double b,double c)
{
private int sol = 0;
private double d;
d = Math.pow(b,2) - 4*a*c;
if(d > 0)
{
sol = 2;
}
else if(d == 0)
{
sol = 1;
}
else if(d < 0)
{
sol = 0;
}
return sol;
}
public String toString()
{
return "There are(is) " + sol + " solution(s). x = " + root1 + " x = " + root2;
}
}
You should move the variables to the class level:
public class QuadraticSolver {
private double a;
private double b;
private double c;
...
}
Next, you need to access the variables that belong to the object qs:
public static void main(String[]args)
{
QuadraticSolver qs = new QuadraticSolver();
in = new Scanner(System.in);
System.out.println("Enter coefficients for quadratic function. ");
qs.a = in.nextDouble();
qs.b = in.nextDouble();
qs.c = in.nextDouble();
...
}
And finally, you should remove the variables from the methods getRoot1(), etc. This is because each method can access the variables a,b,c belonging to the object itself. Thus:
public double getRoot1()
{
double root1 = (-b + Math.sqrt(Math.pow(b,2) - 4*a*c)) / (2*a);
return root1;
}
And at the call sites:
public static void main(String[]args)
{
...
double root1 = qs.getRoot1();
double root2 = qs.getRoot2();
int numsol = qs.numOfSolutions();
...
}
Private instance variables belong to a class. When you create an object that is an instance of a class, the object may have instance variables that belong to the object; if you create multiple instances of a class, each of those instances (objects) has its own set of instance variables. You declare those in the class:
public class QuadraticSolver
{
private static Scanner in;
private double a; // instance variables
private double b;
private double c;
Now, to access those variables, you need to have an object. If you're in a non-static method inside the class, or in a constructor for the class, the method will work with an object called this, so you could say this.a or just a to get at that variable. If you're outside the class, or in a static method in the class (including main), you need to tell it what object you're working with. In your program, your main method has an object qs that is a QuadraticSolver, and you can get at that object's instance variables by saying qs.a, qs.b, etc.
Variables declared inside a method are local variables. They're for use only within that method. They don't declare instance variables for an object. You can't use the keyword private on them, because that keyword is only for instance variables (and other things that aren't variables). You can't use the variables outside that method. If you declare them in an inner set of curly braces, you can't use them outside the curly braces. If you declare a local variable that's the same name as an instance variable, there's no connection between the two.
I was wondering how I could call getJD() within getToD and keep the parameters intact,(or temporarily set the parameters as variables in main and call the variables to the method).
The parameters are going to be input using the scanner class later in the main method.
import static java.lang.Math.*;
public class jdMethods
{
public static double getJD(double y, double m, double d){
if (m<=2.0){
y--;
m += 12.0;
}
double a=floor(y/100.0);
return (365.25*(y+4716.0))+(30.6001*(m+1))+d+(2.0-a+floor(a/4.0))-1524.5;
}
public static double getToD(int h, int m, int s)
{
double a = getJD(a, a, a) + ((h-12)/24) + (m/1440) + (s/86400);
return a;
}
}
Edited for clarity.
It's not perfectly clear on what you are trying to do, but I assumed that you just want to save the result of your first getJD() and to use the result within your getToD(), so I made a private _jd and created a setter and getter for it.
import static java.lang.Math.*;
public class jdMethods
{
private double _jd;
public double getJD(){
return _jd;
}
public void setJD(double y, double m, double d){
if (m<=2.0){
y--;
m += 12.0;
}
double a=floor(y/100.0);
_jd = (365.25*(y+4716.0))+(30.6001*(m+1))+d+(2.0-a+floor(a/4.0))-1524.5;
}
public double getToD(int h, int m, int s)
{
double a = getJD() + ((h-12)/24) + (m/1440) + (s/86400);
return a;
}
}
So here is how you call it:
jdMethods testRun = new jdMethods();
testRun.setJD(1,2,3);
System.out.println(testRun.getToD(3, 2, 1));
All those parameters will be intact since you are using double and int, those are not Object s so it's value is copied when passed to a function, unlike Object s that a reference to it is passed to the function.
About your code, undefined variable a won't let it compile:
double a = getJD( a, a, a ) + ((h-12)/24) + (m/1440) + (s/86400);
I don't get what you are trying to do there, remember that a from getJD method is not the same a into getToD.