Java 是";继承的;子类可以访问解释超类静态方法的正确术语?

Java 是";继承的;子类可以访问解释超类静态方法的正确术语?,java,inheritance,static,polymorphism,static-methods,Java,Inheritance,Static,Polymorphism,Static Methods,澄清:这个问题与访问修饰符无关 确认B.m()和B.m()语句在以下代码中均有效: class A { static void m() { //some code } } class B extends A { } class Example { public static void main (String [] args) { B.m(); // running A's m() static method } public void try() { B

澄清:这个问题与访问修饰符无关

确认B.m()和B.m()语句在以下代码中均有效:

class A {
  static void m() { //some code }
}

class B extends A {
}

class Example {
  public static void main (String [] args) {
    B.m(); // running A's m() static method
  }

  public void try() {
    B b = new B();
    b.m(); // running A's m() static method
  }
}
我的问题是,我们可以说“静态方法是继承的”吗

如果“inherited”是正确的术语,那么如果我们向B类添加一个方法,我们将使用静态类的相同签名:

class A {
  static void m() { //some code }
}

class B extends A {
  static void m() { //some code }
}

class Example {
  public static void main (String [] args) {
    B.m(); // running B's m() static method
  }

  public void try() {
    B b = new B();
    b.m(); // running B's m() static method

    A a = new B();
    a.m(); // running A's m() static method, no polymorphism
  }
}
在这种情况下,请注意,我们没有多态性,这样说“静态方法是继承的而不是重写的,子类静态方法隐藏超类静态方法”是否正确

最后一个疑问是,对于这两个术语,“继承的”和“重写的”,哪一个与术语“多态性”直接相关?

是的,我认为“继承的”在这里是正确的术语,即使它不像可能的那样具有描述性。发件人:

类C从其直接超类和直接超接口继承超类和超接口的所有非私有方法(无论抽象与否),这些方法与C在同一个包中是公共的、受保护的或以默认访问权限声明的,并且不会被类中的声明覆盖(§8.4.8.1)或隐藏(§8.4.8.2)

这并没有指定实例方法,但对允许隐藏或覆盖的内容有特定的限制,如果静态方法没有被继承,这就没有意义

实际上,考虑到静态方法不参与多态性等,我只会将静态方法视为“无条件可访问”,而不是其他任何东西。我认为这一点值得非常清楚——例如,一个静态方法可以隐藏一个继承的方法,但它不能覆盖它

换句话说,虽然我认为“inherit”在技术上是正确的,但我会尽量避免在没有任何进一步解释的情况下使用它

对于你的第二个问题,我想说,基于上述情况,重写与多态性有关,但继承不一定


(我还强烈建议您避免“通过”变量调用静态方法,并在指定名称的任何位置使用声明静态方法的类的名称。我知道这不是问题的一部分,但我想我还是要添加它…)

我认为,试图用“继承的”和“重写的”这样的词来形容这类事情是没有成效的。这是一种误导,因为它给人的印象是,虚拟实例方法的效果可以与之媲美,而您指出,事实并非如此


(但正如Jon Skeet所指出的,Java语言规范与我不一致,它将这些方法组合在同一节中。)

确定静态方法不能被重写,但可以被重新定义,换句话说,它被称为隐藏
检查这个,他们解释得很好

伙计们,我想与所有java爱好者分享我的java知识

首先,让我告诉您,静态成员是那些可以直接访问的成员,而无需创建该特定类的对象,当一个类的静态成员在其他类中使用时,则应通过指定类名来使用它。(dot)静态成员的名称(例如,下例中的a.i),而且,如果任何子类继承自具有静态成员的超类,并且如果子类和超类都在同一个包中,那么即使不使用超类的类名,也可以从基类访问静态成员。请过目 例如:

package myProg; 
class A 
{ 
static int i = 10; 
A() 
{ 
System.out.println("Inside A()"); 
} 
} 

class B extends A 
{ 
public static void main(String[] args) 
{ 
System.out.println("i = " + i); //accessing 'i' form superclass without specifying class name 
System.out.println("A.i = " + A.i); //again accessing 'i' with the class name .(dot) static member 'i' 

/* 
we can also use the super class' object in order to access the static member compiler 
will not show any error but it is not the exact way of using static members. static members are created 
so that it could be used without creating the class object. see below the usage of object to use the 
static member i. 
*/ 
A obj = new A(); //creating class A object and A() also gets called 
obj.i = 20; 
System.out.println("obj.i = " + obj.i); 
} 
} 

/* 
This program was to show the usage of static member. Now, lets discuss on the topic of static member inheritance. 
SO GUYS I WOULD LIKE TO TELL YOU THAT STATIC MEMBERS ARE NOT INHERITED. This undermentioned program is 
to show the inheritance of static members. 
*/ 
class A 
{ 
static int i = 10; //initially the value of i is 10 
static int j = 20; //lets use one more static member int j, just to see the value of it through class A, and B 
static 
{ 
/* 
This is static initialization block(SIB) of class A, 
SIB gets executed first in the order of top to bottom only one time 
when the class is loaded. 
*/ 

System.out.println("A-SIB"); 
} 
} 
class B extends A 
{ 
static 
{ 
i = 12;//trying to modify the i's value to 12 
System.out.println("B-SIB"); 
} 
} 
class D extends A 
{ 
static int k = 15; 
static 
{ 
System.out.println("D-SIB"); 
} 
} 
class C 
{ 
public static void main(String [] arhs) 
{ 
System.out.println("D.k: " + D.k); 
/*here we are trying to access the static member k from class D, 
it will try to search this class and then that class 
will be loaded first i.e. SIB of class D will be loaded and SOP 
statement of class D will be printed first. When the class loading 
is done then the compiler will search for the static int k in class 
D and if found SOP statement will be executed with the value of k. 
*/ 
/* 
ONE GROUND RULE: as soon as the compiler see this statement the compiler will load 
class D into the memory, loading of class into memory is nothing but 
storing all the static members (i.e. static constant & SIBs) into the 
memory. 
*/ 


System.out.println("B.i: " + B.i); 
/*Now, this is what we are talking about... we think that static int i's 
value is there in class B and when we write B.i it compiles and executes 
successfully BUT... there compiler is playing a major role at this statement... 
Try to understand now... we know that class B is the subclass of class A 
BUT when the compiler sees this statement it will first try to search 
the static int i inside class B and it is not found there, then since it is 
the subclass of A, the compiler will search in class A and it is found 
there. NOW, WHEN STATIC INT I IS FOUND IN CLASS A THE COMPILER WILL CHANGE 
THIS STATEMENT B.i TO A.i and the class B WILL NOT AT ALL BE LOADED INTO 
THE MEMORY BECAUSE STATIC I IS ONLY PRESENT IN CLASS A. But in the previous 
statement static int k is present inside class D so when we try to access k's value 
the class D will be loaded into memory i.e. SIB will be executed and then 
the SOP statement of the value of k. USING B.i IS NOT WRONG BUT COMPILER 
ASSUMES THAT THE PROGRAMMER HAS MADE A MISTAKE AND IT REPLACES THE CLASS NAME 
B.i TO A.i. Thus this show that static members are not inherited to the subclass.And 
therefore the vaue of i will NOT BE CHANGE TO 12 AS YOU CAN SEE IN THE SIB OF 
CLASS B, it will be 10 only.. 
*/ 



System.out.println("A.j: " + A.j);//this statement will be executed as it is, compiler will not make 
System.out.println("A.i: " + A.i);//any modifications to these statements.  


System.out.println("B.j: " + B.j);//again compiler will modify this statement from B.j to A.j 

} 
} 
伙计们,如果你还有任何困惑,请通过此电子邮件id向我发送邮件: 普拉迪普_y2k@yahoo.co.in

问候
Pradeep Kumar Tiwari

@Downvoter:你是否不同意规范或我的解释?我不是Downvoter,但我有一个基于你回答的后续问题。超级类的静态成员的访问范式是否与“最终”成员的访问范式有所不同?你会说“最终”成员是继承的吗?@Chris:这似乎是一个复杂和/或棘手的后续问题。认为单独发布可能是一个好问题吗?@Chris:是的,我会说最终成员是继承的,但不能被覆盖-他们当然属于JLS中列出的继承成员集。@Nathan&Jon-我问最终成员的原因是为了说明他们与静态成员遵循相同的规则。因此,既然我们对最终成员使用术语“继承”,而静态成员的行为相同,那么对静态成员使用它应该同样有效。不管是否有效,这是规范使用的术语,所以我认为它的定义是正确的。不过,我通常会继续解释实际的行为。@Jon:是的,我刚才正在查看你的链接,谢谢。你从我这里得到+1。我不相信问题是关于行为,而是关于术语。@Jon:在我阅读JLS之后,我得出结论,上面的第一个代码段可以使用“继承的”,但第二个代码段不能,因为第二个代码段B的静态方法涉及隐藏,这破坏了JLS的语句"... 该类声明既不覆盖(§8.4.8.1)也不隐藏(§8.4.8.2),“该结论是否正确?”?