Является ли «унаследованным» правильный термин для объяснения статического метода суперкласса, доступ к которому может получить подкласс? - PullRequest
14 голосов
/ 16 августа 2011

Уточнение: этот вопрос не о модификаторе доступа

Подтверждено, что операторы 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
  }
}

Мой вопрос: можем ли мы сказать, что "статический метод наследуется"?

если «унаследовано» является правильным термином, если мы добавляем метод в класс 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
  }
}

В этом случае, обратите внимание, что у нас нет полиморфизма. Правильно ли говорить, что «статический метод наследуется, но не переопределяется, статический метод подкласса скрывает статический метод суперкласса»?

Последнее сомнение, для этих 2 терминов, «унаследованных» и «переопределенных», какой из них непосредственно связан с термином «полиморфизм»?

Ответы [ 4 ]

28 голосов
/ 16 августа 2011

Да, я думаю, что «наследовать» - правильный термин здесь, даже если он не такой описательный, как мог бы быть.Из раздела 8.4.8 Спецификации языка Java :

Класс C наследует от своего прямого суперкласса и прямого суперинтерфейса все не частные методы (абстрактные или нет)суперкласс и суперинтерфейсы, которые являются открытыми, защищены или объявлены с доступом по умолчанию в том же пакете, что и C, и не переопределяются (§8.4.8.1) и не скрываются (§8.4.8.2) объявлением в классе.

Это не определяет методы экземпляра, но являются конкретными ограничениями на то, что разрешено скрывать или переопределять что, что не имело бы смысла, если бы статические методы были не унаследованы.

Действительно, я бы просто рассматривал статические методы как «доступные без квалификации», а не как что-либо еще, учитывая, что они не участвуют в полиморфизме и т. Д. Я думаю, что это стоит прояснить - дляНапример, один статический метод может скрыть унаследованный, но он не может переопределить it.

Другими словами, хотя я думаю, что «наследовать» технически правильно, я бы постарался не использовать его без каких-либо дополнительных объяснений.

В отношении вашего второго вопроса я бы сказал, что исходя из вышеизложенного, переопределение связано с полиморфизмом, но наследование не обязательно.

(я также настоятельно рекомендую вам избегать вызова статических методов через переменные, а также использоватьимя класса, который объявляет статический метод, где бы вы ни указали имя.Я знаю, что это не часть вопроса, но я все равно решил добавить это ...)

4 голосов
/ 16 августа 2011

Я думаю, что пытаться применять такие слова, как «унаследованные» и «переопределенные», к таким вещам не продуктивно.Это вводит в заблуждение, потому что создает впечатление, что есть нечто сопоставимое с тем, что происходит с методами виртуальных экземпляров, и вы указываете, что это не так.

(Но, как отмечает Джон Скит, спецификация языка Java не согласна со мной, она группирует их вместе в одном разделе.)

1 голос
/ 27 декабря 2012

Ребята, я хотел бы поделиться своими знаниями в 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 

} 
} 

Ребята, если у вас все еще есть путаница, напишите мне на этот электронный адрес: pradeep_y2k@yahoo.co.in

С уважением Прадип Кумар Тивари

0 голосов
/ 16 августа 2011

Хорошо, статические методы не могут быть переопределены, но могут быть переопределены другими словами, это называется скрытием, проверьте это http://www.coderanch.com/how-to/java/OverridingVsHiding они довольно хорошо объясняют

...