Сайт о телевидении

Сайт о телевидении

» » Java: когда использовать статические методы. Методы Java — как вызывать и использовать

Java: когда использовать статические методы. Методы Java — как вызывать и использовать

Последнее обновление: 19.04.2018

Кроме обычных методов и полей класс может иметь статические поля, методы, константы и инициализаторы. Например, главный класс программы имеет метод main, который является статическим:

Public static void main(String args) { }

Для объявления статических переменных, констант, методов и инициализаторов перед их объявлением указывается ключевое слово static .

Статические поля

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

Например, создадим статическую переменную:

Public class Program{ public static void main(String args) { Person tom = new Person(); Person bob = new Person(); tom.displayId(); // Id = 1 bob.displayId(); // Id = 2 System.out.println(Person.counter); // 3 // изменяем Person.counter Person.counter = 8; Person sam = new Person(); sam.displayId(); // Id = 8 } } class Person{ private int id; static int counter=1; Person(){ id = counter++; } public void displayId(){ System.out.printf("Id: %d \n", id); } }

Класс Person содержит статическую переменную counter, которая увеличивается в конструкторе и ее значение присваивается переменной id. То есть при создании каждого нового объекта Person эта переменная будет увеличиваться, поэтому у каждого нового объекта Person значение поля id будет на 1 больше чем у предыдущего.

Так как переменная counter статическая, то мы можем обратиться к ней в программе по имени класса:

System.out.println(Person.counter); // получаем значение Person.counter = 8; // изменяем значение

Консольный вывод программы:

Id = 1 Id = 2 3 Id = 8

Статические константы

Также статическими бывают константы, которые являются общими для всего класса.

Public class Program{ public static void main(String args) { double radius = 60; System.out.printf("Radisu: %f \n", radius); // 60 System.out.printf("Area: %f \n", Math.PI * radius); // 188,4 } } class Math{ public static final double PI = 3.14; }

Стоит отметить, что на протяжении всех предыдущих тем уже активно использовались статические константы. В частности, в выражении:

System.out.println("hello");

out как раз представляет статическую константу класса System. Поэтому обращение к ней идет без создания объекта класса System.

Статические инициализаторы

Статические инициализаторы предназначены для инициализации статических переменных, либо для выполнения таких действий, которые выполняются при создании самого первого объекта. Например, определим статический инициализатор:

Public class Program{ public static void main(String args) { Person tom = new Person(); Person bob = new Person(); tom.displayId(); // Id = 105 bob.displayId(); // Id = 106 } } class Person{ private int id; static int counter; static{ counter = 105; System.out.println("Static initializer"); } Person(){ id=counter++; System.out.println("Constructor"); } public void displayId(){ System.out.printf("Id: %d \n", id); } }

Статический инициализатор определяется как обычный, только перед ним ставится ключевое слово static . В данном случае в статическом инициализаторе мы устанавливаем начальное значение статического поля counter и выводим на консоль сообщение.

В самой программе создаются два объекта класса Person. Поэтому консольный вывод будет выглядеть следующим образом:

Static initializer Constructor Constructor Id: 105 Id: 106

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

Статические методы

Статические методы также относятся ко всему классу в целом. Например, в примере выше статическая переменная counter была доступна извне, и мы могли изменить ее значение вне класса Person. Сделаем ее недоступной для изменения извне, но доступной для чтения. Для этого используем статический метод:

Public class Program{ public static void main(String args) { Person.displayCounter(); // Counter: 1 Person tom = new Person(); Person bob = new Person(); Person.displayCounter(); // Counter: 3 } } class Person{ private int id; private static int counter = 1; Person(){ id = counter++; } // статический метод public static void displayCounter(){ System.out.printf("Counter: %d \n", counter); } public void displayId(){ System.out.printf("Id: %d \n", id); } }

Теперь статическая переменная недоступна извне, она приватная. А ее значение выводится с помощью статического метода displayCounter. Для обращения к статическому методу используется имя класса: Person.displayCounter() .

При использовании статических методов надо учитывать ограничения: в статических методах мы можем вызывать только другие статические методы и использовать только статические переменные.

Вообще методы определяются как статические, когда методы не затрагиют состояние объекта, то есть его нестатические поля и константы, и для вызова метода нет смысла создавать экземпляр класса. Например:

Public class Program{ public static void main(String args) { System.out.println(Operation.sum(45, 23)); // 68 System.out.println(Operation.subtract(45, 23)); // 22 System.out.println(Operation.multiply(4, 23)); // 92 } } class Operation{ static int sum(int x, int y){ return x + y; } static int subtract(int x, int y){ return x - y; } static int multiply(int x, int y){ return x * y; } }

В данном случае для методов sum, subtract, multiply не имеет значения, какой именно экземпляр класса Operation используется. Эти методы работают только с параметрами, не затрагивая состояние класса. Поэтому их можно определить как статические.

Модификатор static в Java напрямую связан с классом, если поле статично, значит оно принадлежит классу, если метод статичный, аналогично - он принадлежит классу. Исходя из этого, можно обращаться к статическому методу или полю используя имя класса. Например, если поле count статично в классе Counter , значит, вы можете обратиться к переменной запросом вида: Counter.count . Конечно, следует учитывать модификаторы доступа. Например, поля private доступны только внутри класса, в котором они объявлены. Поля protected доступны всем классам внутри пакета (package ), а также всем классам-наследникам вне пакета. Для более подробной информации ознакомьтесь со статьей “private vs protected vs public ”. Предположим, существует статический метод increment() в классе Counter , задачей которого является инкрементирование счётчика count . Для вызова данного метода можно использовать обращение вида Counter.increment() . Нет необходимости создавать экземпляр класса Counter для доступа к статическому полю или методу. Это фундаментальное отличие между статическими и НЕ статическими объектами (членами класса). Важное замечание. Не забывайте, что статические члены класса напрямую принадлежат классу, а не его экземпляру. То есть, значение статической переменной count будет одинаковое для всех объектов типа Counter . В этой статье мы рассмотрим основополагающие аспекты применения модификатора static в Java, а также некоторые особенности, которые помогут понять ключевые концепции программирования.

Что должен знать каждый программист о модификаторе Static в Java.

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

    Вы НЕ можете получить доступ к НЕ статическим членам класса, внутри статического контекста, как вариант, метода или блока. Результатом компиляции приведенного ниже кода будет ошибка:

    public class Counter { private int count; public static void main (String args ) { System. out. println (count) ; //compile time error } }

    Это одна из наиболее распространённых ошибок допускаемых программистами Java, особенно новичками. Так как метод main статичный, а переменная count нет, в этом случае метод println , внутри метода main выбросит “Compile time error”.

    В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите - «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких как «состояние гонки» (race condition).

    Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый объект для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы как нельзя лучше подходят в качестве методов-фабрик (factory), и методов-утилит (utility). Класс java.lang.Math - замечательный пример, в котором почти все методы статичны, по этой же причине классы-утилиты в Java финализированы (final).

    Другим важным моментом является то, что вы НЕ можете переопределять (Override) статические методы. Если вы объявите такой же метод в классе-наследнике (subclass), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса (superclass) вместо переопределения. Это явление известно как сокрытие методов (hiding methods). Это означает, что при обращении к статическому методу, который объявлен как в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

    class Vehicle { public static void kmToMiles (int km) { System. out. println ("Внутри родительского класса/статического метода" ) ; } } class Car extends Vehicle { public static void kmToMiles (int km) { System. out. println ("Внутри дочернего класса/статического метода " ) ; } } public class Demo { public static void main (String args ) { Vehicle v = new Car () ; v. kmToMiles (10 ) ; } }

    Вывод в консоль:

    Внутри родительского класса/статического метода

    Код наглядно демонстрирует: несмотря на то, что объект имеет тип Car , вызван статический метод из класса Vehicle , т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло!

    Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны как «вложенные статические классы» (nested static class). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса - HashMap.Entry , который предоставляет структуру данных внутри HashMap . Стоит заметить, также как и любой другой внутренний класс, вложенные классы находятся в отдельном файле.class. Таким образом, если вы объявили пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением.class. Ещё одним примером использования является объявление собственного компаратора (Comparator), например компаратор по возрасту (AgeComparator) в классе сотрудники (Employee).

    Модификатор static также может быть объявлен в статичном блоке, более известным как «Статический блок инициализации» (Static initializer block), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему.

    Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных или не статических методов, которые связываются во время исполнения на реальном объекте. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности или необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утилиты хорошие образцы применения модификатора static . Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java », которая является обязательной для прочтения каждым программистом данного языка.

    Важным свойством статического блока является инициализация. Статические поля или переменные инициализируются после загрузки класса в память. Порядок инициализации сверху вниз, в том же порядке, в каком они описаны в исходном файле Java класса. Поскольку статические поля инициализируются на потокобезопасный манер, это свойство также используется для реализации паттерна Singleton . Если вы не используется список Enum как Singleton , по тем или иным причинам, то для вас есть хорошая альтернатива. Но в таком случае необходимо учесть, что это не «ленивая» инициализация. Это означает, что статическое поле будет проинициализировано ещё ДО того как кто-нибудь об этом «попросит». Если объект ресурсоёмкий или редко используется, то инициализация его в статическом блоке сыграет не в вашу пользу.

    Во время сериализации, также как и transient переменные, статические поля не сериализуются. Действительно, если сохранить любые данные в статическом поле, то после десериализации новый объект будет содержать его первичное (по-умолчанию) значение, например, если статическим полем была переменная типа int , то её значение после десериализации будет равно нулю, если типа float – 0.0, если типа Object – null . Честно говоря, это один из наиболее часто задаваемых вопросов касательно сериализации на собеседованиях по Java. Не храните наиболее важные данные об объекте в статическом поле!

    И напоследок, поговорим о static import . Данный модификатор имеет много общего со стандартным оператором import , но в отличие от него позволяет импортировать один или все статические члены класса. При импортировании статических методов, к ним можно обращаться как будто они определены в этом же классе, аналогично при импортировании полей, мы можем получить доступ без указания имени класса. Данная возможность появилась в Java версии 1.5, и при должном использовании улучшает читабельность кода. Наиболее часто данная конструкция встречается в тестах JUnit , т.к. почти все разработчики тестов используют static import для assert методов, например assertEquals() и для их перегруженных дубликатов. Если ничего не понятно – добро пожаловать за дополнительной информацией .

    На этом всё. Все вышеперечисленные пункты о модификаторе static в Java обязан знать каждый программист. В данной статье была рассмотрена базовая информация о статических переменных, полях, методах, блоках инициализации и импорте. В том числе некоторые важные свойства, знание которых является критичным при написании и понимании программ на Java. Я надеюсь, что каждый разработчик доведёт свои навыки использования статических концептов до совершенства, т.к. это очень важно для серьёзного программирования."

Модификатора static - с англ. "статичный", "постоянный" - делает переменную или метод "независимыми" от объекта. Давайте рассмотрим, как модификатор применяется к методам.

Модификатор static для методов

1. Метод вызывается без создания объекта класса.

Как и в случае с полями, статические методы можно вызывать без создания объекта. Например, представим, что у нас есть класс MyClass - а внутри его два метода, статический и "обычный":

class MyClass{ public static void firstMethod (){ System.out.println("Это статический метод!"); } public void secondMethod (){ System.out.println("Это НЕ статический метод!"); } }

class MyClass {

public static void firstMethod () {

System . out . println ("Это статический метод!" ) ;

public void secondMethod () {

System . out . println ("Это НЕ статический метод!" ) ;

Мы можем вызвать оба метода, создав объект класса MyClass:

class Test { public static void main (String args){ MyClass c1 = new MyClass(); c1.firstMethod(); c1.secondMethod(); } }

class Test {

MyClass c1 = new MyClass () ;

c1 . firstMethod () ;

c1 . secondMethod () ;

Тем не менее, попробуем записать то же самое без создания объекта - вот так:

class Test { public static void main (String args){ MyClass.firstMethod(); MyClass.secondMethod(); } }

class Test {

public static void main (String args ) {

MyClass . firstMethod () ;

MyClass . secondMethod () ;

Тут мы заменили название объекта - c1 - на название класса (ведь ни одного объекта теперь у нас нет! :)).

Как Вы думаете, что произойдет?

Естественно, такой код работать не будет. Дело в том, что так обращаться можно только к одному из этих методов - статическому:

class Test { public static void main (String args){ MyClass.firstMethod(); } }

class Test {

public static void main (String args ) {

MyClass . firstMethod () ;

Если нам понадобится второй, не статический метод, понадобится создавать объект класса MyClass . Как видите, если обращаться к статическим методам и через название объекта, и название класса, код будет работать. К нестатическим методам нужно обращаться исключительно через название объектов класса.

2. Статические методы нельзя переопределять.

Как Вы помните, один из фундаментальных - это "наследование". Дело в том, что в случаях, когда нам нужно создать новый класс, который имеет много общих свойств с каким-то уже существующим, вместо того, чтобы писать все заново, можно сделать "наследника" существующего класса. Этот "наследник" будет иметь те же самые метод и переменные, что и "родитель".

Тем не менее, в классе-наследнике обычно можно переопределять существующие методы. Это значит, что можно создать метод с таким же названием, только заменить его "внутренности". Так вот, статический метод нельзя переопределить. По аналогии с переменными, можно сказать, что этот метод "один для класса и его наследников" - так же, как статическая переменная "одна для класса и всех его объектов".

3. Статическим методам нужен "статический контекст".

Есть такое правило: статический метод не может ссылаться на нестатическую переменную . Что это значит?

Представьте, что у нас в каком-то классе есть статический метод. То есть это метод, к которому, как Вы знаете, можно обращаться без создания объекта класса . Это значит, что если статический метод будет обращаться к нестатическим переменным (которые попросту "не будут существовать", потому что объект не объявлен), то возникнет ошибка. Поэтому, статические методы могут ссылаться только на статические переменные . Это гарантирует, что во время выполнения нашего метода все элементы будут инициализированы и будут работать. Именно это и называется "статическим контекстом".

Итог двух частей - зачем применяется модификатор static

Итак, Вы в общих чертах поняли, в чем заключается принцип работы модификатора static. Давайте подытожим - как он применяется?

1. Если нужно объявить любую константу - например, = 3,14 - обязательно нужно использовать static. Они объявляются с использованием сочетание "static final":public class Test {

public static final double pi = 3.14159265359 ;

2. Если Вам нужно иметь доступ к переменной или методу без создания экземпляра класса. Например, представим, что у нас есть класс Cat. Логически, нет смысла делать статической переменную "имя кошки" - ведь оно будет индивидуальным для каждого экземпляра класс - т.е. для каждого кота. И метод "мяукать" делать статическим нет смысла - ведь без кошки (без создания объекта класса) вроде как некому будет мяукать 🙂

Но если представить, что у нас есть класс Math, в котором будет метод "найти корень квадратный". Это метод мы можем сделать статическим - ведь он нам явно очень пригодится, и будет часто использоваться. А зачем писать две строчки кода (создание экземпляра класса + вызов метода), если можно обойтись одной (вызов метода)? При этом, класс Math не несет никакой логическом нагрузки, в отличии от классов Cat, Dog или Car, и нам совершенно не нужен объект Math чтобы находить квадратные корни 🙂

3. У статических переменных и методов есть еще одно полезное свойство - они общие для всех экземпляров класса .

С одной стороны, это перекликается с установкой констант - пункт 1. Например, представьте, что у нас есть класс Cat, в котором есть два поля - "количество_лап" и "количество_хвостов". Понятно, что для всех экземпляров этого класса переменная "количество_лап" будет равна 4, а "количество_хвостов" равна 1. Мы можем сделать эти поля static, потому что они будут общими. Кроме того, это нам поможет сэкономить память, потому что эти переменные не будут "создаваться заново" для каждого экземпляра. Наоборот, все эти экземпляры будут ссылаться на одну и ту же - статическую - переменную.

Тот факт, что статическая переменная общая для всех классов, можно использовать и по-другому. Например, представьте, что у нас есть класс Dog. В этом классе, у нас будет статическая переменная "количество_собак", и мы сделаем так, чтобы каждый раз при создании объекта класса Dog она увеличивалась на 1. Таким образом, мы сможем посчитать, сколько мы создавали объектов! Или, как вариант, эту цифру можно использовать для присвоения уникального идентификационного номера каждой собаке.

Теперь Вы знаете основные способы применения модификатора static. Бывают и другие, но их мы рассмотрим позже.


Последнее обновление: 25.12.2018

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

Class Account { public static decimal bonus = 100; public decimal totalSum; public Account(decimal sum) { totalSum = sum + bonus; } } class Program { static void Main(string args) { Console.WriteLine(Account.bonus); // 100 Account.bonus += 200; Account account1 = new Account(150); Console.WriteLine(account1.totalSum); // 450 Account account2 = new Account(1000); Console.WriteLine(account2.totalSum); // 1300 Console.ReadKey(); } }

В данном случае класс Account имеет два поля: bonus и totalSum. Поле bonus является статическим, поэтому оно хранит состояние класса в целом, а не отдельного объекта. И поэтому мы можем обращаться к этому полю по имени класса:

Console.WriteLine(Account.bonus); Account.bonus += 200;

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

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

Статические свойства и методы

Подобным образом мы можем создавать и использовать статические методы и свойства:

Class Account { public Account(decimal sum, decimal rate) { if (sum < MinSum) throw new Exception("Недопустимая сумма!"); Sum = sum; Rate = rate; } private static decimal minSum = 100; // минимальная допустимая сумма для всех счетов public static decimal MinSum { get { return minSum; } set { if(value>0) minSum = value; } } public decimal Sum { get; private set; } // сумма на счете public decimal Rate { get; private set; } // процентная ставка // подсчет суммы на счете через определенный период по определенной ставке public static decimal GetSum(decimal sum, decimal rate, int period) { decimal result = sum; for (int i = 1; i <= period; i++) result = result + result * rate / 100; return result; } }

Переменная minSum, свойство MinSum, а также метод GetSum здесь определены с ключевым словом static , то есть они являются статическими.

Переменная minSum и свойство MinSum представляют минимальную сумму, которая допустима для создания счета. Этот оказатель не относится к какому-то конкретному счету, а относится ко всем счетам в целом. Если мы изменим этот показатель для одного счета, то он также должен измениться и для другого счета. То есть в отличии от свойств Sum и Rate, которые хранят состояние объекта, переменная minSum хранит состояние для всех объектов данного класса.

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

Таким образом, переменные и свойства, которые хранят состояние, общее для всех объектов класса, следует определять как статические. И также методы, которые определяют общее для всех объектов поведение, также следует объявлять как статические.

Статические члены класса являются общими для всех объектов этого класса, поэтому к ним надо обращаться по имени класса:

Следует учитывать, что статические методы могут обращаться только статическим членам класса. Обращаться к нестатическим методам, полям, свойствам внутри статического метода мы не можем.

Нередко статические поля применяются для хранения счетчиков. Например, пусть у нас есть класс User, и мы хотим иметь счетчик, который позволял бы узнать, сколько объектов User создано:

Class User { private static int counter = 0; public User() { counter++; } public static void DisplayCounter() { Console.WriteLine($"Создано {counter} объектов User"); } } class Program { static void Main(string args) { User user1 = new User(); User user2 = new User(); User user3 = new User(); User user4 = new User(); User user5 = new User(); User.DisplayCounter(); // 5 Console.ReadKey(); } }

Статический конструктор

Кроме обычных конструкторов у класса также могут быть статические конструкторы. Статические конструкторы имеют следующие отличительные черты:

    Статические конструкторы не должны иметь модификатор доступа и не принимают параметров

    Как и в статических методах, в статических конструкторах нельзя использовать ключевое слово this для ссылки на текущий объект класса и можно обращаться только к статическим членам класса

    Статические конструкторы нельзя вызвать в программе вручную. Они выполняются автоматически при самом первом создании объекта данного класса или при первом обращении к его статическим членам (если таковые имеются)

Статические конструкторы обычно используются для инициализации статических данных, либо же выполняют действия, которые требуется выполнить только один раз

Определим статический конструктор:

Class User { static User() { Console.WriteLine("Создан первый пользователь"); } } class Program { static void Main(string args) { User user1 = new User(); // здесь сработает статический конструктор User user2 = new User(); Console.Read(); } }

Статические классы

Статические классы объявляются с модификатором static и могут содержать только статические поля, свойства и методы. Например, если бы класс Account имел бы только статические переменные, свойства и методы, то его можно было бы объявить как статический:

Static class Account { private static decimal minSum = 100; // минимальная допустимая сумма для всех счетов public static decimal MinSum { get { return minSum; } set { if(value>0) minSum = value; } } // подсчет суммы на счете через определенный период по определенной ставке public static decimal GetSum(decimal sum, decimal rate, int period) { decimal result = sum; for (int i = 1; i <= period; i++) result = result + result * rate / 100; return result; } }

В C# показательным примером статического класса является класс Math, который применяется для различных математических операций.

Переменное число параметров метода

Иногда число аргументов, которые будут переданы методу, неизвестно до периода выполнения. Например, вам нужен класс, который чертит на графике линию, заданную последовательностями х- и у-координат. Этот класс должен содержать методом, принимающим единственный аргумент - объект типа Point, представляющий значения обеих координат х и у. Этот метод должен сохранять каждый объект типа Point в связанном списке или в элементах массива, пока вызывающая программа не даст команду на вывод всей последовательности точек. Однако такое решение может быть не очень эффективным потому, что оно требует наличия в классе связанного списка. Но ведь можно было бы использовать единственный метод - DrawLine, которому этот список может и не потребоваться. Эту проблему эффективно решает метод с переменным количеством аргументов.

Такому методу можно задать переменное число аргументов через ключевое слово params в видемассива. Рассмотрим пример класса Chart, написанного на C#, позволяющего пользователю одним вызовом получить и вывести произвольное число объектов Point:

using System;

class Point //Класс точки

public Point(int x, int y) { this.x = x; this.у = у; }

public int x; public int y;

class Chart //Класс рисовальщика

public void DrawLine(Graphics g, params Point p)

Console.WriteLine("\пЭтот метод позволяет нарисовать линию " +

"по следующим точкам:");

for (int i = 0; i < p.GetLength(0); i++)

{ Console.WriteLine("{0), {1}". p[i].x, p[i].y); }

class ChartApp

public static void Main()

Point p1 = new Point(5,10);

Point p2 = new Point(5, 15);

Point p3 = new Point(5, 20);

Chart chart = new Chart();

chart.DrawLine(p1, p2, p3);

Метод DrawLine сообщает компилятору C#, что он может принимать переменное число объектов типа Point. Затем в период выполнения метод использует простой цикл for для прохода по всем объектам Point и вывода всех точек.

Статическим называется метод, который существует в классе как в таковом, а не в отдельных его экземплярах. Как и в случае других статических членов, главное преимущество статических методов в том, что они расположены вне конкретных экземпляров класса, не засоряя глобальное пространство приложения. При этом они и не нарушают принципов ООП, поскольку ассоциированы с определенным классом.

Определить метод как статический позволяет ключевое слово static. Затем для вызова метода пользователь применяет синтаксис вида Класс. Метод. Этот синтаксис необходим, даже если у пользователя есть ссылка на экземпляр класса.


Статические (static ) методы, или методы класса, можно вызывать, не создавая экземпляр объекта. Именно таким образом используется метод Main .

public class Sample

public static int a;

public int b;

public static void DoubleA(){ a *= 2; }

public void SetB(){ b = a; }

public class Application

public static void Main()

Sample sc1 = new Sample(), sc2 = new Sample();

Sample.a = 1;

sc1.SetB();

Sample.a = 2;

sc2.SetB();

Console.WriteLine("sc1.b = {0}, sc2.b = {1}", sc1.b, sc2.b);

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