2013-02-12 4 views
18

Мне сказали, что методы static неявно final и поэтому не могут быть переопределены. Это правда?Можно ли переопределить статический метод в C#?

  1. Может ли кто-нибудь дать лучший пример переопределения статического метода?

  2. Если статические методы - это просто методы класса, каково их использование?

+1

Нет, они не могут быть переопределены. Они связаны с классом, а не с объектом. –

+0

для реального использования: вы можете вызвать статический метод без экземпляра класса. – Najzero

+0

Спасибо. Я понимаю [что такое статический метод] (http://stackoverflow.com/a/4124118/2061309), лучший пример, данный SLaks. Поэтому для моего вопроса об переопределении статического метода (если bydefault является окончательным, а не сделать его окончательным) - означает ли это, что подкласс этого класса, который содержит статический, может определять статический метод с той же сигнатурой? – aspiring

ответ

17

(1) Статические методы нельзя переопределить, однако они могут быть скрыты с использованием ключевого слова «новое». В основном методы переопределения означают, что вы ссылаетесь на базовый тип и хотите вызвать производный метод. Поскольку static являются частью типа и не подпадают под запросы vtable, что не имеет смысла.

Э.Г. статика не может сделать:

public class Foo { 
    public virtual void Bar() { ... } 
} 
public class Bar : Foo { 
    public override void Bar() { ... } 
} 

// use: 
Foo foo = new Bar(); // make an instance 
foo.Bar(); // calls Bar::Bar 

Поскольку статика не работают в случаях, вы всегда указывать foo.bar или Bar.Bar явно. Поэтому переопределение здесь не имеет смысла (попробуйте выразить его в коде ...).

(2) Существуют разные способы использования статических методов. Например, он используется в шаблоне Singleton для получения одного экземпляра типа. Другим примером является «static void Main», который является основной точкой доступа в вашей программе.

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

[обновление]

Простой пример скрытие:

public class StaticTest 
{ 
    public static void Foo() { Console.WriteLine("Foo 1"); } 
    public static void Bar() { Console.WriteLine("Bar 1"); } 
} 

public class StaticTest2 : StaticTest 
{ 
    public new static void Foo() { Console.WriteLine("Foo 2"); } 
    public static void Some() { Foo(); Bar(); } // Will print Foo 2, Bar 1 
} 

public class TestStatic 
{ 
    static void Main(string[] args) 
    { 
     StaticTest2.Foo(); 
     StaticTest2.Some(); 
     StaticTest.Foo(); 
     Console.ReadLine(); 
    } 
} 

Обратите внимание, что если вы сделаете классы static, вы не можете сделать это. Статические классы должны быть получены от object.

Основное отличие между этим и наследованием заключается в том, что компилятор может определить во время компиляции, какой метод вызывать при использовании static. Если у вас есть экземпляры объектов, вам нужно сделать это во время выполнения (который называется поиском vtable).

+0

Спасибо, что дал мне этот пример переопределения. Да, я пытаюсь в коде. Итак, чтобы это правильно, 1) ** мы можем подклассифицировать статический класс, как любой другой нестатический класс **? 2) мы можем использовать статические методы без переопределения статических методов родительского класса, но скрывая их с помощью ключевого слова New. – aspiring

+0

Я добавил еще несколько объяснений и пример. (1) Нет, вы не можете подклассифицировать статический класс, но можете скрыть статические члены. (2) да, вы должны попробовать второй пример, он рассказывает, как он себя ведет. – atlaste

+3

когда это будет Foo <-> Бар бессмысленный конец ??? остановите использование FoorBar для примеров, в каждом случае Bar и Foo являются либо классами или подклассами, либо функциями или методами. так в чем смысл ??? просто используйте «Животные» для подкласса и действия для переопределения. 10x –

5

Вы не переопределяете статический метод. Вы прячете это. См. this answer для получения дополнительной информации.

Некоторые причины использовать статические методы:

  1. Они little bit faster, чем методы экземпляра. Также см. Это msdn article, в котором приведены номера производительности для резервного копирования (вкл. Статический вызов avg 0,2 нс, статический вызов avg 6.1ns, встроенный вызов вызова avg 1.1 ns, вызов экземпляра avg 6.8 ns)
  2. Менее подробный для выписки - t необходимо создать экземпляр класса, чтобы добраться до них (и создание экземпляров также может повлиять на производительность)
+0

У меня нет проблем с методами экземпляра. Я узнал, что класс 'static' не может быть создан. Но вы упомянули, что «статические методы - это то, что он создается только один раз в вашем приложении». Поэтому я сейчас запутался. Вы ссылаетесь на «Использование System.Math;», говоря, что статические методы создаются? Я несколько раз использовал Math-членов класса Math.Abs ​​() несколько раз в одном классе, не создавая экземпляров даже один раз. 1) Так вы могли бы прояснить, что вы подразумеваете под *** «экземпляром однажды» ***? 2) Может ли статический класс быть подклассом? Имеет ли смысл Sub-Class статический класс? – aspiring

+1

см. Мое редактирование. Я не должен был использовать термин «экземпляр» со статическим методом. более правильным является то, что он создается только один раз. –

+1

Все * методы * только «созданы» один раз. Даже нестатические методы имеют только одну копию существующего кода (код IL, который создается во время компиляции и преобразован в машинный код * один раз * во время выполнения). Не путайте код и данные! Нестатический метод является только * вызываемым * через экземпляр объекта, но это из-за скрытого «этого» указателя, который передается ему. Сам код является «статическим», поскольку он фиксированный и однострочный. –

5

Ну Вы не можете переопределить статический метод. Статический метод не может быть виртуальным, поскольку он не связан с экземпляром класса.

Метод «overriden» в производном классе фактически является новым методом, не связанным с тем, который определен в базовом классе (отсюда и новое ключевое слово).

Это важно понять: когда типы наследуются от других типов, они выполняют общий контракт, тогда как статические типы не связаны каким-либо контрактом (с точки зрения чистого ООП). Нет технического пути на языке, чтобы связать два статических типа вместе с контрактом «наследование». Если вы «переопределите» метод журнала в двух разных местах.

Если вы думаете об использовании статических методов, то это не имеет смысла; для виртуальной отправки вам нужен фактический экземпляр объекта для проверки.

Статический метод также не может реализовать интерфейс; если этот класс реализует интерфейс IRolesService, я бы утверждал, что метод не должен быть статическим вообще. Лучше иметь метод экземпляра, так что вы можете поменять свой MockRoleService с реальным сервисом, когда будете готовы

+0

Спасибо. Для меня это немного довольный уровень, но по пути я получу его :) PS: И я определенно хочу быть в вашем классе в этом случае. Нашел [этот пост тоже в контексте Java.] (Http://www.xyzws.com/Javafaq/can-static-methods-be-overridden/1) – aspiring

+1

хе-хе хорошо, даже я тоже изучаю C# .. мне 22 года старый и работающий в компании .. через простые вещи, и вы получите его шаг за шагом. – Neel

Смежные вопросы