I don't understand why most programming language don't allow developers/users to call non-static method from static method directly? What is the reason behind it?
p.s. I know, you can create object and call non-static method from static method.
I don't understand why most programming language don't allow developers/users to call non-static method from static method directly? What is the reason behind it?
p.s. I know, you can create object and call non-static method from static method.
Because a static field/method--by definition--is not tied to any single object/instance of the class, while a non-static field/method always refers to an actual object/instance in some way.
Since that probably sounded too vague/abstract to answer the question, and this kind of confusion usually stems from a misunderstanding of what static actually means, let's make this concrete with some C++-like pseudocode:
class Foo {
public:
static int a() { return 2; }
int b() { return d_x; }
Foo(int x) { d_x = x; }
private:
int d_x;
}
The static method a
is not tied to any particular instance of Foo
, meaning it can be called from anywhere, whether or not you have an actual Foo
object. In C++ you'd simply write Foo::a()
, and it would always return 2.
The non-static method b
is tied to a single instance of Foo
. Because it simply returns the int inside a given Foo
object, it doesn't make any sense to try calling b()
without a specific Foo
object. What would you expect it to return if it didn't have a Foo
? So Foo f; f.b();
makes sense but Foo::b()
does not.
If I tried to make a() call b(), then whenever I called a() without an actual instance of Foo
, I'd also be calling b() without an actual instance of Foo
, so now a() doesn't make sense either.
Essentially, the two methods are implemented something like this:
namespace Foo {
int a() {
return 2;
}
int b(Foo* this) {
return this->x;
}
};
When you look at the methods this way, it's fairly obvious why b() can call a() but not the other way around: a() simply doesn't have a Foo*
lying around to give to b().
Incidentally, you can "work around" this limitation by writing a static method that takes an actual Foo
object and then calls non-static methods on that Foo
object. But that's usually a code smell indicating that you have static methods which shouldn't be static or non-static method that should be static, or a class that's trying to do too many things at once.
Because all static things are not related to any object, but they are related to a class. So all objects of same class will access same static methods.
On the other hand, non static methods are attached to a particular object of a class.
You can call static methods without creating any object of a class, but that is not the case with non static methods.
Somewhat Tongue-in-cheek... Or at least this is the functional perspective on methods...
There is no such thing called "method"
class Apple
{
...
public void Eat()
{
this.weight --;
}
public static Apple ChangeColor(Apple apple)
{
apple.color = Color.GetRandomColor();
}
}
The example above defines a class with two methods one static and one isn't.
The second is actually a function that receives a single parameter of the Apple type and changes it's color. The first is also a function that implicitly receives a parameter called this
and decreases it's weight.
That's basically the idea behind a 'member function' / 'member method'. It receives an implicit first parameter of the type of the class.
so doing this: Apple.Eat()
doesn't make sense, there are too few parameters (Apple is the class name here).
while this does:
Apple x = new Apple();
x.eat()
That 'implicit first parameter' of 'member methods' in OOP languages also has a special feature around it. If a member method is virtual (language specific) then the method will be dynamically invoked based on the type of that parameter.
Dynamic dispatch or dynamic invocation, is something similar to method overloads - that is deciding which method to call based on compile time type, except it happens at runtime.
Some programming languages allow doing this on all parameters of a function - this is called Multiple dispatch
Though most OOP languages allow this only for the 'first implicit parameter' of 'member methods' - this is called virtual methods, Polymorphism and single dispatch.
By the way... There is a whole design pattern called Visitor solely to allow some sort of Multiple dispatch to languages that don't have the feature