Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can an abstract class force the inheriting class to implement a method as static?

Python 3.2 in case that matters...

The following code shows that the "concrete class" can either implement some_method as a static method or an instance method:

import abc

class SomeAbstractClass(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def some_method(self): pass

class ValidConcreteClass1(SomeAbstractClass):

    @staticmethod
    def some_method():
        print("foo!")

class ValidConcreteClass2(SomeAbstractClass):

    def some_method(self):
        print("foo!")

ValidConcreteClass1.some_method()

instance = ValidConcreteClass2()
instance.some_method()

My question is, can I force the implementation of some_method to be static in the inheriting class?

I noticed @abc.abstractstaticmethod and thought this was the answer but the following code still runs just fine. I would think it would reject ValidConreteClass2 because some_method is not static:

import abc

class SomeAbstractClass(metaclass=abc.ABCMeta):

    @abc.abstractstaticmethod
    def some_method(self): pass

class ValidConcreteClass1(SomeAbstractClass):

    @staticmethod
    def some_method():
        print("foo!")

class ValidConcreteClass2(SomeAbstractClass):

    def some_method(self):
        print("foo!")

ValidConcreteClass1.some_method()

instance = ValidConcreteClass2()
instance.some_method()
like image 491
Matthew Lund Avatar asked Dec 08 '11 21:12

Matthew Lund


People also ask

Can abstract class have static methods?

Declaring abstract method static If you declare a method in a class abstract to use it, you must override this method in the subclass. But, overriding is not possible with static methods. Therefore, an abstract method cannot be static.

Can static class inherit abstract class?

It's not allowed because inheritance is about creating related classes of objects, and you're not creating any objects at all with static classes.

Does abstract class force implementation?

While an abstract class cannot be instantiated, it can have implementation details. The designers of C# chose to force the user to either implement the functionality, or specifically state that the functionality inherited from the interface will not be implemented at this level.

Why abstract methods Cannot be static?

A static method belongs to class not to object instance thus it cannot be overridden or implemented in a child class. So there is no use of making a static method as abstract.


1 Answers

I think some clarification is needed;

First, in Python every method is virtual - really virtual; so whether a method is static, or bound to a class or instance, that's a matter of the subclass, not of the parent one. You don't have a real reason for wanting to prevent that - what's your purpose?

Second, ABCs check for abstractness at instantiation time - if you try instancing a class that's still got any abstract method, an error will be raised. But ABCs can't do anything on static or class methods that are invoked from the class itself - there's NO CHECK performed on the method itself, just an attribute set on the method - it's ABCMeta that does the dirty work when the class is instanced.

Third, the purpose of abstractstaticmethod is to allow an abstract method - hence something that must be still be overriden someway by subclasses - to be static and used from anywhere - again, there's no check done on the method itself, so the following code is perfectly legal:

import abc

class SomeAbstractClass(metaclass=abc.ABCMeta):

    @abc.abstractstaticmethod
    def some_method(): 
        return 123

class ValidConcreteClass1(SomeAbstractClass):

    def some_method(self):
        return 456

inst = ValidConcreteClass1()
print(inst.some_method())
print(SomeAbstractClass.some_method())

The only reason for abstractstaticmethod/abstractclassmethod existence is that the following does not work because decorated methods lack a dict

class NotWorking(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    @staticmethod
    def some_method(self):
        return "asd"

One last thing: if you really wanted to, you could probably add such functionality by extending ABCMeta, but I won't give you an hook on how to do this unless you tell me why you're doing that :-)

like image 165
Alan Franzoni Avatar answered Sep 22 '22 18:09

Alan Franzoni