Question Pourquoi les méthodes statiques ne peuvent-elles pas être abstraites en Java?


La question est en Java pourquoi ne puis-je pas définir une méthode statique abstraite? par exemple

abstract class foo {
    abstract void bar( ); // <-- this is ok
    abstract static void bar2(); //<-- this isn't why?
}

517
2017-12-16 10:45


origine


Réponses:


Parce que "abstrait" signifie: "Implémente pas de fonctionnalité", et "statique" signifie: "Il y a des fonctionnalités même si vous n'avez pas d'instance d'objet". Et c'est une contradiction logique.


507
2017-12-16 10:50



Mauvaise conception du langage. Il serait beaucoup plus efficace d'appeler directement une méthode abstraite statique que de créer une instance juste pour utiliser cette méthode abstraite. Surtout lorsque l'on utilise une classe abstraite comme solution de contournement pour l'incapacité d'étendre, ce qui est un autre exemple de conception médiocre. J'espère qu'ils vont résoudre ces limitations dans une prochaine version.


273
2017-10-20 14:27



Vous ne pouvez pas remplacer une méthode statique, donc la rendre abstraite n'aurait aucun sens. De plus, une méthode statique dans une classe abstraite appartiendrait à cette classe, et non à la classe supérieure, donc ne pourrait pas être utilisée de toute façon.


136
2017-12-16 10:48



le abstract L'annotation à une méthode indique que la méthode DOIT être remplacée dans une sous-classe.

En Java, un static member (méthode ou champ) ne peut pas être remplacé par des sous-classes (ce n'est pas nécessairement vrai dans d'autres langages orientés objet, voir SmallTalk.) A static le membre peut être caché, mais c'est fondamentalement différent de substitué.

Comme les membres statiques ne peuvent pas être remplacés dans une sous-classe, le abstract l'annotation ne peut pas leur être appliquée.

En passant, d'autres langages supportent l'héritage statique, tout comme l'héritage d'instance. Du point de vue de la syntaxe, ces langages exigent généralement que le nom de la classe soit inclus dans l'instruction. Par exemple, en Java, en supposant que vous écrivez du code en ClassA, ce sont des instructions équivalentes (si methodA () est une méthode statique, et qu'il n'y a pas de méthode d'instance avec la même signature):

ClassA.methodA();

et

methodA();

Dans SmallTalk, le nom de la classe n'est pas facultatif, donc la syntaxe est (notez que SmallTalk n'utilise pas le .txt pour séparer le "sujet" et le "verbe", mais l'utilise à la place comme terminateur de syntaxe):

ClassA methodA.

Comme le nom de la classe est toujours requis, la "version" correcte de la méthode peut toujours être déterminée en parcourant la hiérarchie des classes. Pour ce que ça vaut, je manque parfois static héritage, et a été mordu par le manque d'héritage statique en Java lorsque j'ai commencé avec lui. De plus, SmallTalk est dactylographié (et ne prend donc pas en charge programme par contrat). abstract modificateur pour les membres du groupe.


63
2017-12-16 20:17



J'ai aussi posé la même question, voici pourquoi

Comme la classe Abstract dit, il ne sera pas implémenté et permettra à la sous-classe de le donner

donc la sous-classe doit remplacer les méthodes de la superclasse,

RÈGLE NO 1 - Une méthode statique ne peut pas être surchargée 

Parce que les membres statiques et les méthodes sont des éléments de temps de compilation, c'est pourquoi la surcharge (Polymorphisme temporel de la compilation) des méthodes statiques est autorisée plutôt que la surcharge (Polymorphisme d'exécution)

Donc, ils ne peuvent pas être abstrait.

Il n'y a rien comme statique abstraite  <--- Non autorisé dans Java Universe


14
2018-05-15 07:13



C'est une conception de langage terrible et vraiment aucune raison pour laquelle cela ne peut pas être possible.

En fait, voici une implémentation sur comment POUVEZ être fait en JAVA:

public class Main {

        public static void main(String[] args) {
                // This is done once in your application, usually at startup
                Request.setRequest(new RequestImplementationOther());

                Request.doSomething();
        }

        public static final class RequestImplementationDefault extends Request {
                @Override
                void doSomethingImpl() {
                        System.out.println("I am doing something AAAAAA");
                }
        }

        public static final class RequestImplementaionOther extends Request {
                @Override
                void doSomethingImpl() {
                        System.out.println("I am doing something BBBBBB");
                }
        }

        // Static methods in here can be overriden
        public static abstract class Request {

                abstract void doSomethingImpl();

                // Static method
                public static void doSomething() {
                        getRequest().doSomethingImpl();
                }

                private static Request request;
                private static Request getRequest() {
                        // If setRequest is never called prior, it will default to a default implementation. Of course you could ignore that too. 
                        if ( request == null ) {
                                return request = new RequestImplementationDefault();
                        }
                        return request;
                }
                public static Request setRequest(Request r){
                        return request = r;
                }

        }
}

================= Ancien exemple ci-dessous =================

Recherchez getRequest et getRequestImpl ... setInstance peut être appelé pour modifier l'implémentation avant que l'appel ne soit effectué.

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

/**
 * @author Mo. Joseph
 * @date 16 mar 2012
 **/

public abstract class Core {


    // ---------------------------------------------------------------        
    private static Core singleton; 
    private static Core getInstance() {
        if ( singleton == null )
            setInstance( new Core.CoreDefaultImpl() );  // See bottom for CoreDefaultImpl

        return singleton;
    }    

    public static void setInstance(Core core) {
        Core.singleton = core;
    }
    // ---------------------------------------------------------------        



    // Static public method
    public static HttpServletRequest getRequest() {      
        return getInstance().getRequestImpl();
    }


    // A new implementation would override this one and call setInstance above with that implementation instance
    protected abstract HttpServletRequest getRequestImpl();




    // ============================ CLASSES =================================

    // ======================================================================
    // == Two example implementations, to alter getRequest() call behaviour 
    // == getInstance() have to be called in all static methods for this to work
    // == static method getRequest is altered through implementation of getRequestImpl
    // ======================================================================

    /** Static inner class CoreDefaultImpl */
    public static class CoreDefaultImpl extends Core { 
        protected HttpServletRequest getRequestImpl() {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        }
    }

     /** Static inner class CoreTestImpl : Alternative implementation */
    public static class CoreTestImpl extends Core { 
        protected HttpServletRequest getRequestImpl() {
            return new MockedRequest();
        }
    }       






}

9
2018-03-19 16:54



  • Une méthode abstraite est uniquement définie pour pouvoir être remplacée dans une sous-classe. Cependant, les méthodes statiques ne peuvent pas être surchargées. Par conséquent, c'est une erreur de compilation pour avoir une méthode statique et abstraite.

    Maintenant, la question suivante est pourquoi les méthodes statiques ne peuvent pas être remplacées ??

  • C'est parce que les méthodes statiques appartiennent à une classe particulière et non à son instance. Si vous essayez de surcharger une méthode statique, vous n'obtiendrez aucune erreur de compilation ou d'exécution, mais le compilateur cachera simplement la méthode statique de la superclasse.


5
2018-06-14 21:11