Я хотел бы знать:
- Почему статические методы нельзя переопределять в Java?
- Могут ли статические методы быть перегружены в Java?
Я хотел бы знать:
Статические методы не могут быть переопределены в точном смысле этого слова, но они могут скрывать родительские статические методы
На практике это означает, что компилятор решит, какой метод выполнять во время компиляции, а не во время выполнения, как это происходит с переопределенными методами экземпляра.
Для наглядного примера посмотрите здесь.
И это документация по Java, объясняющая разницу между переопределением методов экземпляра и сокрытием классовых (статических) методов.
Переопределение: Переопределение в Java просто означает, что конкретный метод будет вызываться на основе типа времени выполнения объекта и не в типе времени компиляции (как в случае с переопределением статические методы)
Скрытие: Статические методы родительского класса не являются частью дочернего класса (хотя они доступны), поэтому не возникает вопросов о переопределяя это. Даже если вы добавите еще один статический метод в подкласс, идентичен тому, что в родительском классе, этот статический метод подкласса уникален и отличается от статического метода в родительском классе.
Статические методы не могут быть переопределены, потому что нечего переопределять, так как это будут два разных метода. Например
static class Class1 {
public static int Method1(){
return 0;
}
}
static class Class2 extends Class1 {
public static int Method1(){
return 1;
}
}
public static class Main {
public static void main(String[] args){
//Must explicitly chose Method1 from Class1 or Class2
Class1.Method1();
Class2.Method1();
}
}
И да статические методы могут быть перегружены так же, как и любой другой метод.
Статические методы нельзя переопределить, поскольку они не отправляются на экземпляр объекта во время выполнения. Компилятор решает, какой метод вызывается.
Вот почему вы получаете предупреждение о компиляторе при написании
MyClass myObject = new MyClass();
myObject.myStaticMethod();
// should be written as
MyClass.myStaticMethod()
// because it is not dispatched on myObject
myObject = new MySubClass();
myObject.myStaticMethod();
// still calls the static method in MyClass, NOT in MySubClass
Статические методы могут быть перегружены (это значит, что вы можете иметь одно и то же имя метода для нескольких методов, если они имеют разные типы параметров).
Integer.parseInt("10");
Integer.parseInt("AA", 16);
Можем ли мы перегрузить статические методы?
Ответ Да. Мы можем иметь два или более статических метода с одинаковым именем, но различия в входных параметрах. Например, рассмотрим следующую программу Java.
public class Test {
public static void foo() {
System.out.println("Test.foo() called ");
}
public static void foo(int a) {
System.out.println("Test.foo(int) called ");
}
public static void main(String args[])
{
Test.foo(); //Test.foo() called printed
Test.foo(10); //Test.foo(int) called printed
}
}
Можем ли мы перегружать методы, которые отличаются только ключевым словом static?
Мы не можем перегружать два метода в Java, если они отличаются только статическим ключевым словом (количество параметров и типов параметров одинаково). См., Например, следующую программу Java. Такое поведение аналогично в С++.
public class Test {
public static void foo() {
System.out.println("Test.foo() called ");
}
public void foo() { // Compiler Error: cannot redefine foo()
System.out.println("Test.foo(int) called ");
}
public static void main(String args[]) {
Test.foo();
}
}
Можем ли мы переопределить статические методы в java?
Мы можем объявлять статические методы с одной и той же сигнатурой в подклассе, но это не считается переопределяющим, поскольку не будет никакого полиморфизма во время выполнения. Следовательно, ответ Нет.
Если производный класс определяет статический метод с той же сигнатурой, что и статический метод в базовом классе, метод в производном классе скрывает метод в базовом классе. , если статический метод переопределяется производным классом, тогда это не переопределение.
class Base {
// Static method in base class which will be hidden in subclass
public static void display() {
System.out.println("Static or class method from Base");
}
// Non-static method which will be overridden in derived class
public void print() {
System.out.println("Non-static or Instance method from Base");
}
}
class Derived extends Base {
// This method hides display() in Base
public static void display() {
System.out.println("Static or class method from Derived");
}
// This method overrides print() in Base
public void print() {
System.out.println("Non-static or Instance method from Derived");
}
}
public class Test {
public static void main(String args[ ]) {
Base obj1 = new Derived();
// As per overriding rules this should call to class Derive static
// overridden method. Since static method can not be overridden, it
// calls Base display()
obj1.display(); //output -> Static or class method from Base
// Here overriding works and Derive print() is called
obj1.print(); //output-> Non-static or Instance method from Derived
}
}
Методы родительского класса, которые являются статическими, не являются частью дочернего класса (хотя они доступны), поэтому нет вопроса об их переопределении. Даже если вы добавите еще один статический метод в подкласс, идентичный тому, который находится в его родительском классе, этот статический метод подкласса уникален и отличается от статического метода в его родительском классе.
Статические методы нельзя переопределить, поскольку они не являются частью состояния объекта. Скорее, они принадлежат классу (т.е. Они являются методами класса). Это нормально, чтобы перегрузить статические (и окончательные) методы.
Если я вызываю метод, используя имя SubClass MysubClass, тогда метод подкласса отображает то, что он означает, что статический метод может быть переопределен или нет
class MyClass {
static void myStaticMethod() {
System.out.println("Im in sta1");
}
}
class MySubClass extends MyClass {
static void myStaticMethod() {
System.out.println("Im in sta123");
}
}
public class My {
public static void main(String arg[]) {
MyClass myObject = new MyClass();
myObject.myStaticMethod();
// should be written as
MyClass.myStaticMethod();
// calling from subclass name
MySubClass.myStaticMethod();
myObject = new MySubClass();
myObject.myStaticMethod();
// still calls the static method in MyClass, NOT in MySubClass
}
}
Статические методы - это метод, единственный экземпляр которого разделяется всеми объектами класса. Статический метод относится к классу, а не к объектам. Поскольку статические методы не зависят от объектов, компилятору Java не нужно ждать создания объектов. Чтобы вызвать статический метод, мы используем синтаксис типа ClassName.method();
В случае перегрузки метода методы должны быть в одном классе для перегрузки. Даже если они объявлены как статические, их можно перегрузить, поскольку
Class Sample
{
static int calculate(int a,int b,int c)
{
int res = a+b+c;
return res;
}
static int calculate(int a,int b)
{
int res = a*b;
return res;
}
}
class Test
{
public static void main(String []args)
{
int res = Sample.calculate(10,20,30);
}
}
Но в случае переопределения метода метод суперкласса и метод в подклассе действуют как другой метод. суперкласс будет иметь свою собственную копию, а подкласс будет иметь свою собственную копию, поэтому он не подпадает под переопределение метода.
Нет. Статические методы не могут быть переопределены, поскольку они являются частью класса, а не объекта. Но можно перегрузить статический метод.
static
методы - это методы уровня class
.
Концепция скрытия используется для методов static
.
Смотрите: http://www.coderanch.com/how-to/java/OverridingVsHiding
Перегрузка также называется статическим связыванием, поэтому, как только используется слово static, это означает, что статический метод не может показать полиморфизм во время выполнения.
Мы не можем переопределить статический метод, но допустимо наличие разных реализаций одного и того же статического метода в суперклассе и его подклассе. Просто производный класс будет скрывать реализации базового класса.
Для статических методов вызов метода зависит от типа ссылки, а не от того, какой объект ссылается, т.е. статический метод принадлежит только классу, а не его экземплярам, поэтому вызов метода решается во время самой компиляции.
Принимая во внимание, что в случае перегрузки метода статические методы могут быть перегружены, если они имеют различные числа или типы параметров. Если два метода имеют одно и то же имя и один и тот же список параметров, их нельзя определить по-разному только с помощью ключевого слова static.
class SuperType {
public static void classMethod(){
System.out.println("Super type class method");
}
public void instancemethod(){
System.out.println("Super Type instance method");
}
}
public class SubType extends SuperType{
public static void classMethod(){
System.out.println("Sub type class method");
}
public void instancemethod(){
System.out.println("Sub Type instance method");
}
public static void main(String args[]){
SubType s=new SubType();
SuperType su=s;
SuperType.classMethod();// Prints.....Super type class method
su.classMethod(); //Prints.....Super type class method
SubType.classMethod(); //Prints.....Sub type class method
}
}
Этот пример для переопределения статического метода
Примечание: если мы будем называть статический метод с ссылкой на объект, тогда будет вызван статический метод ссылочного типа (класса), а не статический метод класса объекта.
Статический метод относится только к классу.
Из Почему Java не позволяет переопределять статические методы?
Переопределение зависит от наличия экземпляра класса. Точка полиморфизма заключается в том, что вы можете подклассифицировать класс, а объекты, реализующие эти подклассы, будут иметь разные типы поведения для тех же методов, которые определены в суперклассе (и переопределены в подклассах). Статический метод не связан ни с одним экземпляром класса, поэтому концепция не применима.
Существовали два соображения, вовлекающие Java-дизайн, который повлиял на это. Одной из них было беспокойство по поводу производительности: было много критики Smalltalk о том, что она слишком медленная (сбор мусора и полиморфные вызовы являются частью этого), и разработчики Java были настроены избегать этого. Другим было решение о том, что целевой аудиторией Java являются разработчики на С++. Статические методы работают так, как они имеют преимущество для программистов на C++, и также были очень быстрыми, потому что нет необходимости ждать, пока время выполнения не выяснит, какой метод вызывать.
Сама цель использования статического метода заключается в доступе к методу класса без создания экземпляра для него. Не имеет смысла, если мы переопределим этот метод, поскольку к ним будет обращаться класс name.method()
Нет, вы не можете переопределить статический метод. Статический разрешает класс, а не экземпляр.
public class Parent {
public static String getCName() {
return "I am the parent";
}
}
public class Child extends Parent {
public static String getCName() {
return "I am the child";
}
}
Каждый класс имеет статический метод getCName(). Когда вы вызываете имя класса, оно ведет себя так, как вы ожидали, и каждый возвращает ожидаемое значение.
@Test
public void testGetCNameOnClass() {
assertThat(Parent.getCName(), is("I am the parent"));
assertThat(Child.getCName(), is("I am the child"));
}
Никаких сюрпризов в этом unit test. Но это не переопределяет. Это объявление того, что имеет столкновение имен.
Если мы попытаемся достичь статичности из экземпляра класса (не очень хорошая практика), то он действительно показывает:
private Parent cp = new Child();
`enter code here`
assertThat(cp.getCName(), is("I am the parent"));
Несмотря на то, что cp является дочерним, статический разрешается с помощью объявленного типа "Родитель" вместо фактического типа объекта. Для нестатики это исправляется правильно, потому что нестатический метод может переопределить метод его родителя.
Вы можете перегрузить статический метод, но вы не можете переопределить статический метод. На самом деле вы можете переписать статический метод в подклассах, но это не называется переопределением, поскольку переопределение должно быть связано с полиморфизмом и динамической привязкой. Статический метод принадлежит классу, поэтому он не имеет ничего общего с этими понятиями. Переписывание статического метода больше похоже на затенение.
Я проектирую код статического метода overriding.I думаю, что это переопределить легко. Пожалуйста, объясните мне, как его невозможно переопределить статические члены. Вот мой код -
class Class1 {
public static int Method1(){
System.out.println("true");
return 0;
}
}
class Class2 extends Class1 {
public static int Method1(){
System.out.println("false");
return 1;
}
}
public class Mai {
public static void main(String[] args){
Class2 c=new Class2();
//Must explicitly chose Method1 from Class1 or Class2
//Class1.Method1();
c.Method1();
}
}
Его на самом деле довольно просто понять - все, что помечено как статическое, принадлежит только классу, например, статический метод не может быть унаследован в подклассе, потому что он принадлежит классу, в котором они были объявлены. См. Статическое ключевое слово.
Лучший ответ, который я нашел из этого вопроса:
http://www.geeksforgeeks.org/can-we-overload-or-override-static-methods-in-java/
Можем ли мы перегрузить статические методы?
Ответ "Да. У нас может быть два или более статических метода с одним и тем же именем, но различия в входных параметрах. Например, рассмотрим следующую программу Java.
// filename Test.java
public class Test {
public static void foo() {
System.out.println("Test.foo() called ");
}
public static void foo(int a) {
System.out.println("Test.foo(int) called ");
}
public static void main(String args[])
{
Test.foo();
Test.foo(10);
}
}
Вывод:
Test.foo() called
Test.foo(int) called
Можем ли мы переопределить статические методы в java?
Мы можем объявлять статические методы с одной и той же сигнатурой в подклассе, но это не считается переопределяющим, поскольку не будет никакого полиморфизма во время выполнения. Следовательно, ответ "Нет.
Если производный класс определяет статический метод с той же сигнатурой, что и статический метод в базовом классе, метод в производном классе скрывает метод в базовом классе.
/* Java program to show that if static method is redefined by
a derived class, then it is not overriding. */
// Superclass
class Base {
// Static method in base class which will be hidden in subclass
public static void display() {
System.out.println("Static or class method from Base");
}
// Non-static method which will be overridden in derived class
public void print() {
System.out.println("Non-static or Instance method from Base");
}
}
// Subclass
class Derived extends Base {
// This method hides display() in Base
public static void display() {
System.out.println("Static or class method from Derived");
}
// This method overrides print() in Base
public void print() {
System.out.println("Non-static or Instance method from Derived");
}
}
// Driver class
public class Test {
public static void main(String args[ ]) {
Base obj1 = new Derived();
// As per overriding rules this should call to class Derive static
// overridden method. Since static method can not be overridden, it
// calls Base display()
obj1.display();
// Here overriding works and Derive print() is called
obj1.print();
}
}
Выход:
Static or class method from Base
Non-static or Instance method from Derived
Как любой статический метод является частью экземпляра класса, поэтому невозможно переопределить статический метод
Да.. Практически... Теоретически... Если вы переопределите статический метод в Java, тогда он будет компилироваться и работать плавно.. но он потеряет Polymorphism.... который является основным свойством Java.. Вы будете читать повсюду, что его невозможно попробовать самостоятельно закомпилировать и запустить... вы получите свой ответ... например, если у вас есть класс животных и статический метод eat(), и вы переопределяете этот статический метод в своем подклассе, который вызывается это собака.. тогда, когда вы назначаете объект "Собака" в "Справочник животных" и звоните "eat" ().. согласно Java Dog eat() следует было называть... но в статическом режиме "Переопределение животных есть() будет вызываться..