是“继承的”吗?解释超类的静态方法可以被子类访问的正确术语是什么?

发布于 2024-11-30 03:52:10 字数 958 浏览 1 评论 0原文

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

确认 Bm() 和 bm() 语句在以下代码中都有效:

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
  }
}

我的问题是我们可以说“静态方法是继承的”吗?

如果“继承”是正确的术语,如果我们向 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
  }
}

在这种情况下,请注意我们没有多态性,“静态方法是继承的,但是未重写,子类静态方法隐藏超类静态方法”?

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

Clarification: this question is not about access modifier

Confirmed that B.m() and b.m() statements both works in the following code:

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
  }
}

My question is can we said "static method is inherited"?

if "inherited" is the correct term, if we add a method to B class we same signature of the static class:

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
  }
}

In this case, notice that we have no polymorphism, is it the correct term to said that "static method is inherited but not overridden, subclass static method hide superclass static method"?

Last doubt, for these 2 terms, "inherited" and "overriden", which one is directly tied to the term "polymorphism" ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

各自安好 2024-12-07 03:52:10

是的,我认为“继承”在这里是正确的术语,即使它并不像它可能的那样具有描述性。来自 Java 语言的 第 8.4.8 节规格

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

它没有指定实例方法,但是对于允许隐藏或重写什么内容有特定的限制,如果静态方法不是继承的,那么这些限制就没有意义。

实际上,我只是将静态方法视为“无需限定即可访问”,而不是其他任何东西,因为它们不参与多态性等。我认为值得非常清楚地了解这一点 - 例如,一个静态方法可以< em>隐藏继承的,但不能覆盖它。

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

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

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

Yes, I think "inherit" is the correct term here, even if it's not as descriptive as it might be. From section 8.4.8 of the Java Language Specification:

A class C inherits from its direct superclass and direct superinterfaces all non-private methods (whether abstract or not) of the superclass and superinterfaces that are public, protected or declared with default access in the same package as C and are neither overridden (§8.4.8.1) nor hidden (§8.4.8.2) by a declaration in the class.

That doesn't specify instance methods, but there are specific restrictions on what is allowed to hide or override what, which wouldn't make sense if static methods were not inherited.

Really though, I would simply view static methods as "accessible without qualification" rather than anything else, given that they don't take part in polymorphism etc. I think it's worth being very clear about that - for example, one static method can hide an inherited one, but it can't override it.

In other words, while I think "inherit" is technically correct, I would try to avoid using it without any further explanation.

For your second question, I'd say that based on the above, overriding is tied to polymorphism, but inheriting isn't necessarily.

(I would also strongly advise you to avoid calling static methods "via" variables, and also to use the name of the class which declares the static method wherever you specify the name at all. I know that's not part of the question, but I thought I'd just add it anyway...)

汹涌人海 2024-12-07 03:52:10

我认为尝试将“继承”和“覆盖”等词应用于此类事情是没有成效的。它具有误导性,因为它给人的印象是存在与虚拟实例方法类似的情况,而您指出并不存在。

(但正如 Jon Skeet 指出的那样,Java 语言规范不同意我的观点,它将它们分组在同一部分中。)

I think trying to apply words like 'inherited' and 'overridden' to this sort of thing is not productive. It's misleading because it gives the impression there is something comparable of what goes on with virtual instance methods, and you point out there isn't.

(But as Jon Skeet points out, the Java language spec doesn't agree with me, it groups these together in the same section.)

说不完的你爱 2024-12-07 03:52:10

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

首先让我告诉你,静态成员是那些不需要创建特定类的对象就可以直接访问的成员,当一个类的静态成员在其他类中使用时,应该通过指定类名来使用它。 (点)静态成员的名称(例如下面示例中的 Ai),并且如果任何子类从具有静态成员的超类继承,并且如果子类和超类都在同一个包中,则该静态成员可以是从基类访问,甚至不使用该类超类的名称。请通过
示例:

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 

} 
} 

如果大家还有任何困惑,请通过以下电子邮件地址给我发邮件:
[电子邮件受保护]

问候
普拉迪普·库马尔·蒂瓦里

Guys I would like to share my knowledge in java with all java lovers out there!

First of all let me tell you that static members are those members which can be accessed directly without creating an object of that particular class, when static members of a class is used in some other class then it should be used by specifying the class name .(dot) static member's name(e.g. A.i in the following example), and also if any subclass class is getting inherited from a super class which has static members and if both subclass and super class are in the same package then that static members can be accessed from the base class without even using the class name of the super class. Please go through the
Example:

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 

} 
} 

Guys if you still have any confusion mail me at this email-id:
[email protected]

Regards
Pradeep Kumar Tiwari

国产ˉ祖宗 2024-12-07 03:52:10

好的静态方法不能被覆盖,但可以重新定义,换句话说,它称为隐藏
检查这个http://www.coderanch.com/how-to/java/OverridingVsHiding 他们解释得很好

Ok static methods cannot be overridden but can be redefined in other words its called hiding
check this http://www.coderanch.com/how-to/java/OverridingVsHiding they explain pretty well

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文