Je ne comprends pas pourquoi une méthode statique ne peut pas utiliser de données non statiques. Quelqu'un peut-il expliquer quels sont les problèmes et pourquoi nous ne pouvons pas le faire?
Je ne comprends pas pourquoi une méthode statique ne peut pas utiliser de données non statiques. Quelqu'un peut-il expliquer quels sont les problèmes et pourquoi nous ne pouvons pas le faire?
Réponses:
Dans la plupart des langages OO, lorsque vous définissez une méthode dans une classe, celle-ci devient une méthode d'instance . Lorsque vous créez une nouvelle instance de cette classe, via le new
mot - clé, vous initialisez un nouvel ensemble de données unique pour cette instance uniquement. Les méthodes appartenant à cette instance peuvent ensuite utiliser les données que vous avez définies dessus.
Les méthodes statiques , en revanche, ignorent les instances de classe individuelles. La méthode statique est similaire à une fonction libre en C ou C ++. Cela n'est pas lié à une instanciation spécifique de la classe. C'est pourquoi ils ne peuvent pas accéder aux valeurs d'instance. Il n'y a pas d'exemple à prendre une valeur de!
Les données statiques sont similaires à une méthode statique. Une valeur déclarée static
n'a pas d'instance associée. Il existe pour chaque instance et n'est déclaré qu'en un seul endroit en mémoire. Si cela change un jour, cela changera pour chaque instance de cette classe.
Une méthode statique peut accéder à des données statiques car elles existent toutes les deux indépendamment des instances spécifiques d'une classe.
Il peut être utile de regarder comment vous appelez une méthode statique par rapport à une méthode d'instance. Disons que nous avions la classe suivante (utilisant un pseudocode semblable à Java):
class Foo {
// This static value belongs to the class Foo
public static final string name = "Foo";
// This non-static value will be unique for every instance
private int value;
public Foo(int value) {
this.value = value;
}
public void sayValue() {
println("Instance Value: " + value);
}
public static void sayName() {
println("Static Value: " + name);
}
}
Foo foo1 = new Foo(10);
Foo foo2 = new Foo(20);
foo1.sayValue(); // Prints "Instance Value: 10" - called on foo1
foo2.sayValue(); // Prints "Instance Value: 20" - called on foo2
Foo.sayName(); // Prints "Static Value: Foo" - called on Foo (not foo1 or foo2)
Comme COME FROM le souligne dans les commentaires, une méthode statique est capable de travailler avec des données non statiques, mais elle doit être transmise explicitement. Supposons que la Foo
classe utilise une autre méthode:
public static Foo Add(Foo foo1, Foo foo2) {
return new Foo(foo1.value + foo2.value);
}
Add
est toujours statique et n'a pas d' value
instance propre, mais étant membre de la classe Foo, il peut accéder aux value
champs privés des occurrences foo1
et foo2
instances passées . Dans ce cas, nous l'utilisons pour renvoyer une nouvelle Foo
avec les valeurs ajoutées des deux valeurs transmises.
Foo foo3 = Foo.Add(foo1, foo2); // creates a new Foo with a value of 30
this
référence implicite disponible. Je pense qu'il est extrêmement important de comprendre.
Permet de l'expliquer avec un échantillon hypothétique.
Imaginez un cours simple:
class User
{
User(string n) { name = n; };
string name;
}
Maintenant, nous créons 2 instances de cette classe:
User Bones = new User("Bones");
User Jim = new User("Jim");
Maintenant, réfléchissez - et si nous ajoutions une nouvelle méthode statique à User, par exemple:
static string GetName();
et vous l'appelez:
string x = User::GetName()
Que contiendrait x? "Jim", "Bones" ou autre chose?
Le problème est qu'une méthode statique est une méthode unique, définie sur la classe, pas les objets. Par conséquent, vous ne savez pas à quel objet il peut s’appliquer. C'est pourquoi c'est une chose spéciale. Il est préférable de considérer les méthodes statiques comme des choses individuelles, comme des fonctions en C par exemple. Le fait que des langages comme Java les contiennent dans les classes est principalement un problème, car Java n'autorise rien d'existant en dehors d'une classe. Par conséquent, des fonctions comme celle-ci doivent être forcées dans une classe d'une manière ou d'une autre à l’intérieur d’une classe aussi, quand tout le monde dit que ce devrait être une fonction singulière et autonome).
Il peut utiliser des données de terrain. considérez le code java suivant:
class MyBean {
private String myString;
static void myStaticMethod() {
myString = "tada";/*not allowed; if this was possible how would
be different from a field without static?*/
MyBean myBean = new MyBean();//allowed if associated with an instance
myBean.myString = "tada";
}
}
static
nessité.
Les données non statiques sont associées à une instance de la classe. Les méthodes statiques (et les données) ne sont pas associées à une instance particulière de la classe. Il n'est pas nécessaire qu'une instance de classe utilise des méthodes statiques dessus. Même s'il y avait des instances, il n'y aurait aucun moyen pour Java de garantir que vous opérez sur l'instance que vous attendez lorsque vous appelez une méthode statique. Par conséquent, les méthodes statiques ne peuvent pas accéder à des données non statiques.
Je pense que le problème ici est celui de la compréhension.
D'un point de vue technique, une méthode statique appelée depuis un objet serait tout à fait capable de voir les champs d'instance. Je soupçonne fortement que c'est ce qui a posé la question en premier lieu.
Le problème est que les méthodes peuvent être appelées de l'extérieur de l'objet. À ce stade, il n'y a aucune donnée d'instance à leur fournir - et donc aucun moyen pour le compilateur de résoudre le code. Comme autoriser les données d'instance a créé une contradiction, nous ne devons pas autoriser les données d'instance.
Considérez-le comme une méthode statique vivant dans une dimension non orientée objet.
Dans la "dimension orientée objet", une classe peut générer de multiples egos (instances), chaque ego a la conscience de lui-même via son état.
Dans la dimension plate, non-OO, une classe ignore que son ego vit dans la dimension OO. Leur monde est plat et procédural, presque comme si la POO n'avait pas encore été inventée, et comme si la classe était un petit programme procédural, et que les données statiques n'étaient que des variables globales.
Je pense que la meilleure façon d’expliquer cela est d’examiner du code, puis de déterminer les résultats attendus du code.
// Create three new cars. Cars have a name attribute.
Car car1 = new Car("Mazda3");
Car car2 = new Car("FordFocus");
Car car3 = new Car("HondaFit");
// Now we would like to print the names of some cars:
// First off why don't we try this:
Car.printCarName();
// Expected behaviour:
// If we think about what we are trying to do here it doesn't
// really make sense. What instance of car name should this
// print? Should it print Mazda3? FordFoucs?
// What is the expected behaviour? If we are going to have a
// static call on car call printCarName it should probably do
// something like print all car names or a random car name or
// throw an error.
//Now lets try this instead:
Car.printCarName(car1);
// Expected Behaviour:
// Luckily the expected behaviour is very clear here. This
// should print Mazda3. This works as expected.
// Finally lets try this:
car1.printMyName();
// Expected Behaviour:
// Same as previous example, however this is the *right* way
// to do it.
Pour être complet, voici la classe de voiture:
public class Car{
public String name;
public Car(String name){
this.name = name;
}
public static printCarName(){
print "Not sure what to do here... Don't know which car you are talking about.";
}
public static printCarName(Car c){
print c.name;
}
public /*NOT static*/ printMyName(){
print this.name;
}
}
Les autres réponses disent à peu près tout, cependant, il y a quelques "détails" que je voudrais ajouter.
Les méthodes statiques (disons celles en Java) n’ont tout simplement pas d’objet implicite associé (accessible via this
) dont les membres sont généralement accessibles directement par leur nom.
Cela ne signifie pas qu'ils ne peuvent pas accéder à des données non statiques.
class MyClass {
public static void foo(MyOtherClass object) {
System.out.println(object.member);
}
}
class MyOtherClass {
public int member = 10;
}
Je sais que ce n'est qu'un détail, mais j'ai trouvé votre question étrange quand je l'ai lue. "Peut utiliser uniquement des données statiques" est trop restrictif.
En passant, je n'ai pas testé le code, je l'ai simplement écrit ici pour illustrer ce que je disais.