Переменные являются глобальными, если не объявлены как локальные !!
Плохо (DoSomething () вызывается только 10 раз):
function CountToTen()
{
for(i=0; i< 10; i++)
{
DoSomething(i);
}
}
function countToFive()
{
for(i=0; i<5; i++)
{
CountToTen();
}
}
CountToFive();
Хорошо (DoSomething ( ) вызывается 50 раз, как и предполагалось):
function CountToTen()
{
var i;
for(i=0; i< 10; i++)
{
DoSomething(i);
}
}
function countToFive()
{
var i;
for(i=0; i<5; i++)
{
CountToTen();
}
}
CountToFive();
Итак, в основном, если в вашем классе-предке вам нужно определенное поведение для метода. Если ваш потомок использует тот же метод, но имеет другую реализацию, вы можете переопределить его, если у него есть ключевое слово virtual .
using System;
class TestClass
{
public class Dimensions
{
public const double pi = Math.PI;
protected double x, y;
public Dimensions()
{
}
public Dimensions (double x, double y)
{
this.x = x;
this.y = y;
}
public virtual double Area()
{
return x*y;
}
}
public class Circle: Dimensions
{
public Circle(double r): base(r, 0)
{
}
public override double Area()
{
return pi * x * x;
}
}
class Sphere: Dimensions
{
public Sphere(double r): base(r, 0)
{
}
public override double Area()
{
return 4 * pi * x * x;
}
}
class Cylinder: Dimensions
{
public Cylinder(double r, double h): base(r, h)
{
}
public override double Area()
{
return 2*pi*x*x + 2*pi*x*y;
}
}
public static void Main()
{
double r = 3.0, h = 5.0;
Dimensions c = new Circle(r);
Dimensions s = new Sphere(r);
Dimensions l = new Cylinder(r, h);
// Display results:
Console.WriteLine("Area of Circle = {0:F2}", c.Area());
Console.WriteLine("Area of Sphere = {0:F2}", s.Area());
Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
}
}
Изменить: Вопросы в комментарии
Если я не использую ключевое слово virtual в базовом классе, будет ли оно работать?
Если вы используете ключевое слово override
в своих дочерних классах, оно не будет работать. Вы получите ошибку компилятора CS0506 'function1':
Как любой другой язык ... когда вам нужен полиморфизм. Для этого есть множество способов использования. Например, вы хотите абстрагироваться от способа чтения ввода с консоли, файла или другого устройства. У вас может быть общий интерфейс читателя, за которым следуют несколько конкретных реализаций с использованием виртуальных функций.
например, методы прокси. т.е. методы перезаписи во время выполнения. Например, NHibernate использует это для поддержки отложенной загрузки.
В основном виртуальные члены позволяют выражать полиморфизм, производный класс может иметь метод с той же сигнатурой, что и метод в его базовом классе, и базовый класс вызовет метод производного класса.
Базовый пример:
public class Shape
{
// A few example members
public int X { get; private set; }
public int Y { get; private set; }
public int Height { get; set; }
public int Width { get; set; }
// Virtual method
public virtual void Draw()
{
Console.WriteLine("Performing base class drawing tasks");
}
}
class Circle : Shape
{
public override void Draw()
{
// Code to draw a circle...
Console.WriteLine("Drawing a circle");
base.Draw();
}
}
class Rectangle : Shape
{
public override void Draw()
{
// Code to draw a rectangle...
Console.WriteLine("Drawing a rectangle");
base.Draw();
}
}
class Triangle : Shape
{
public override void Draw()
{
// Code to draw a triangle...
Console.WriteLine("Drawing a triangle");
base.Draw();
}
}
Это позволяет достичь позднего связывания, то есть определять во время выполнения, а не во время компиляции, какой член объекта будет вызван. См. Википедию .
Из здесь :
В объектно-ориентированном программировании виртуальная функция или виртуальный метод функция или метод, поведение которых можно переопределить в наследуемом класс функцией с таким же подпись.
Например, у вас есть базовый класс Params и набор производных классов. Вы хотите иметь возможность выполнять ту же операцию с массивом, в котором хранятся все возможные классы, производные от params.
Нет проблем - объявите метод виртуальным, добавьте базовую реализацию в класс Params и переопределите ее в производных классах. Теперь вы можете просто пройти по массиву и вызвать метод по ссылке - будет вызван правильный метод.
class Params {
public:
virtual void Manipulate() { //basic impl here }
}
class DerivedParams1 : public Params {
public:
override void Manipulate() {
base.Manipulate();
// other statements here
}
};
// more derived classes can do the same
void ManipulateAll( Params[] params )
{
for( int i = 0; i < params.Length; i++ ) {
params[i].Manipulate();
}
}