Static and Instance Methods with the Same Name

Static and Instance methods with the same name?

No you can't. The reason for the limitation is that static methods can also be called from non-static contexts without needing to prepend the class name (so MyStaticMethod() instead of MyClass.MyStaticMethod()). The compiler can't tell which you're looking for if you have both.

You can have static and non-static methods with the same name, but different parameters following the same rules as method overloading, they just can't have exactly the same signature.

Javascript - Same name for static and instance methods bad practice?

It's fine when it simplifies things for you (or considerable shortens your code or something), but of course it makes it confusing to assess which of the two ways to use. Also, what if I wanted to get a baz and a qux from an id? If I used the static method, it would need to go to the database twice. Therefore I'd rather recommend to use

class Foo extends Model {
… // constructor
static fromId(id) {
return new this({bar: execute(`select bar from foo where id = ${id}`)});
}
getBaz() {
return getBazFromBar(this.bar);
}
}

so that you can do Foo.fromId(…).getBaz() instead of Foo.getBaz(id).

Static and non static methods with the same name in parent class and implementing interface

A static and non static method can't have the same signature in the same class. This is because you can access both a static and non static method using a reference and the compiler will not be able to decide whether you mean to call the static method or the non static method.

Consider the following code for example :

Ov ov = new Ov();
ov.fun(); //compiler doesn't know whether to call the static or the non static fun method.

The reason why Java may allow a static method to be called using a reference is to allow developers to change a static method to a non static method seamlessly.

How to use a static and an instance method with the same name on the same class?

I haven't seen how Eloquent does it, but way to achieve this would be not to declare the method you want to reuse in neither the base class, nor the extended class; and instead use the magic methods __call($method, $arguments) and __callStatic($method, $arguments).

A simple example would be this:

class Base {

public static function __callStatic($method, $arguments) {
if ('foo' === $method) {
echo "static fooing\n";
}
return new static();
}

public function __call($method, $arguments) {
if ('foo' === $method) {
echo "instance fooing\n";
}
}

}

class Child extends Base {

}

Which would be used as:

Child::foo()->foo();

The first foo() goes through __callStatic() in the Base class, because it's a static call. The second foo() goes through __call(), since it's a non-static call.

This would output:

static fooing
instance fooing

You can see it working here.

Java, static and instance methods with same name

You can make two methods with the same name so long as their parameters (the input from the brackets) are different. So for example you could have

public boolean isPrime() { ... }
public static boolean isPrime(int num) { ... }

but not

public boolean isPrime() { ... }
public static boolean isPrime() { ... }

Python: Regular method and static method with same name

A similar question is here: override methods with same name in python programming

functions are looked up by name, so you are just redefining foo with an instance method. There is no such thing as an overloaded function in Python. You either write a new function with a separate name, or you provide the arguments in such a way that it can handle the logic for both.

In other words, you can't have a static version and an instance version of the same name. If you look at its vars you'll see one foo.

In [1]: class Test:
...: @staticmethod
...: def foo():
...: print 'static'
...: def foo(self):
...: print 'instance'
...:

In [2]: t = Test()

In [3]: t.foo()
instance

In [6]: vars(Test)
Out[6]: {'__doc__': None, '__module__': '__main__', 'foo': <function __main__.foo>}

Same name for classmethod and instancemethod

Class and instance methods live in the same namespace and you cannot reuse names like that; the last definition of id will win in that case.

The class method will continue to work on instances however, there is no need to create a separate instance method; just use:

class X:
@classmethod
def id(cls):
return cls.__name__

because the method continues to be bound to the class:

>>> class X:
... @classmethod
... def id(cls):
... return cls.__name__
...
>>> X.id()
'X'
>>> X().id()
'X'

This is explicitly documented:

It can be called either on the class (such as C.f()) or on an instance (such as C().f()). The instance is ignored except for its class.

If you do need distinguish between binding to the class and an instance

If you need a method to work differently based on where it is being used on; bound to a class when accessed on the class, bound to the instance when accessed on the instance, you'll need to create a custom descriptor object.

The descriptor API is how Python causes functions to be bound as methods, and bind classmethod objects to the class; see the descriptor howto.

You can provide your own descriptor for methods by creating an object that has a __get__ method. Here is a simple one that switches what the method is bound to based on context, if the first argument to __get__ is None, then the descriptor is being bound to a class, otherwise it is being bound to an instance:

class class_or_instancemethod(classmethod):
def __get__(self, instance, type_):
descr_get = super().__get__ if instance is None else self.__func__.__get__
return descr_get(instance, type_)

This re-uses classmethod and only re-defines how it handles binding, delegating the original implementation for instance is None, and to the standard function __get__ implementation otherwise.

Note that in the method itself, you may then have to test, what it is bound to. isinstance(firstargument, type) is a good test for this:

>>> class X:
... @class_or_instancemethod
... def foo(self_or_cls):
... if isinstance(self_or_cls, type):
... return f"bound to the class, {self_or_cls}"
... else:
... return f"bound to the instance, {self_or_cls"
...
>>> X.foo()
"bound to the class, <class '__main__.X'>"
>>> X().foo()
'bound to the instance, <__main__.X object at 0x10ac7d580>'

An alternative implementation could use two functions, one for when bound to a class, the other when bound to an instance:

class hybridmethod:
def __init__(self, fclass, finstance=None, doc=None):
self.fclass = fclass
self.finstance = finstance
self.__doc__ = doc or fclass.__doc__
# support use on abstract base classes
self.__isabstractmethod__ = bool(
getattr(fclass, '__isabstractmethod__', False)
)

def classmethod(self, fclass):
return type(self)(fclass, self.finstance, None)

def instancemethod(self, finstance):
return type(self)(self.fclass, finstance, self.__doc__)

def __get__(self, instance, cls):
if instance is None or self.finstance is None:
# either bound to the class, or no instance method available
return self.fclass.__get__(cls, None)
return self.finstance.__get__(instance, cls)

This then is a classmethod with an optional instance method. Use it like you'd use a property object; decorate the instance method with @<name>.instancemethod:

>>> class X:
... @hybridmethod
... def bar(cls):
... return f"bound to the class, {cls}"
... @bar.instancemethod
... def bar(self):
... return f"bound to the instance, {self}"
...
>>> X.bar()
"bound to the class, <class '__main__.X'>"
>>> X().bar()
'bound to the instance, <__main__.X object at 0x10a010f70>'

Personally, my advice is to be cautious about using this; the exact same method altering behaviour based on the context can be confusing to use. However, there are use-cases for this, such as SQLAlchemy's differentiation between SQL objects and SQL values, where column objects in a model switch behaviour like this; see their Hybrid Attributes documentation. The implementation for this follows the exact same pattern as my hybridmethod class above.

Static and non-static method in one class with the same name JAVA

I want this method to be usefull with an object and also without it.
Is it possible to do something like that without creating another
method?

You will have to create another method, but you can make the non-static method call the static method, so that you do not duplicate the code and if you want to change the logic in the future you only need to do it in one place.

public class Test {
private int a;
private int b;
private int c;

public Test(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}

public String count() {
return count(a, b, c);
}

public static String count(int a1, int b1, int c1) {
String solution;
solution = Integer.toString(a1 + b1 + c1);
return solution;
}

public static void main(String[] args) {
System.out.println(Test.count(1, 2, 3));
Test t1 = new Test(1, 2, 3);
System.out.println(t1.count());
}
}


Related Topics



Leave a reply



Submit