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:
this.
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