Перевод статьи From AS3 to C#, Part 2: Extending Classes and Implementing Interfaces
Эта статья продолжает серию "C# для AS3 разработчиков", и сегодня мы рассмотрим устройство классов в C# с точки зрения AS3 разработчика (наследование классов, реализация интерфейсов и наследование интерфейсов).
Начнём с наследования классов. Вот, как это выглядит в AS3:
class Shape
{
}
class Circle extends Shape
{
}
А вот, как это выглядить в C#:
class Shape
{
}
class Circle : Shape
{
}
Как вы могли заметить, вместо ключевого слова extends, используется: (двоеточие).
Похожим образом обстоят дела с реализацией интерфейсов. Как это выглядит в AS3:
interface IHasArea
{
function GetArea(): int;
}
interface IRound
{
function GetSmoothness(): int;
}
class Shape
{
}
class Circle extends Shape implements IHasArea, IRound
{
function GetArea(): int
{
return 33; // TODO рассчитать
}
function GetSmoothness(): int
{
return 44; // TODO рассчитать
}
}
Та же самая структура кода, но в C#:
interface IHasArea
{
int GetArea();
}
interface IRound
{
int GetSmoothness();
}
class Shape
{
}
class Circle : Shape, IHasArea, IRound
{
int GetArea()
{
return 33; // TODO рассчитать
}
int GetSmoothness()
{
return 44; // TODO рассчитать
}
}
В С#, двоеточие используется вместо ключевого слова implements, по такому же принципу, как и с extends. Описание интерфейсов в C# похоже на описание оных в AS3.
Пример расширения интерфейсов в AS3:
interface ISuper
{
}
interface ISub extends ISuper
{
}
Скорее всего, вы уже догадываетесь, как этот код выглядит в C#…
interface ISuper
{
}
interface ISub : ISuper
{
}
Давайте разберёмся, как описываются отношения между родительскими и дочерними классами/интерфейсами в C#. В AS3 вы можете использовать ключевые слова this и super в любых не статических функциях, чтобы обратиться к экземпляру текущего класса (this) или к экземпляру родительского класса (super). Например:
class Polygon
{
var numVertices:uint;
function printDescription(): String
{
return "Polygon (numVertices=" + numVertices + ")";
}
}
class Triangle extends Polygon
{
var color:String;
var polygonDescriptionAtConstructionTime:String;
function Triangle(color:String)
{
this.color = color;
polygonDescriptionAtConstructionTime = super.printDescription();
}
function printDescription(): String
{
return "Triangle (color=" + color + ")";
}
}
В данном примере, ключевое слово super обращается исключительно к переменным и функциям класса Polygon. Такой способ обращения к функциям используется крайне редко, но иногда он может помочь избежать в коде двусмысленностей, относительно того, какая из функций printDescription будет вызвана. Если бы в данном примере не использовалось слово super, то вызывалась бы функция printDescription класса Triangle, т.к. поиск в текущем классе происходит раньше родительского класса.
Ключевое слово this обращается исключительно к переменным и функциям класса Triangle. В примере, this используется, чтобы компилятор понимал, что нужно обрщаться к переменной color класса Triangle, а не к одноимённой переменной, передаваемой в конструктор.
А теперь версия на C#:
class Polygon
{
uint NumVertices;
String PrintDescription()
{
return "Polygon (numVertices=" + numVertices + ")";
}
}
class Triangle : Polygon
{
String Color;
String PolygonDescriptionAtConstructionTime;
Triangle(String color)
{
this.Color = color;
PolygonDescriptionAtConstructionTime = base.printDescription();
}
String printDescription()
{
return "Triangle (color=" + color + ")";
}
}
Эти два примера очень похожи, за исключением того, что в C#, вместо ключевого слова super, используется ключевое слово base. В C# base выполняет те же функции, что и super в AS3.
Другой пример использования super в AS3 (вызов родительского конструктора):
class Polygon
{
var numVertices:uint;
function Polygon(numVertices:uint)
{
this.numVertices = numVertices;
}
}
class Triangle extends Polygon
{
var color:String;
function Triangle(numVertices:uint, color:String)
{
super(numVertices);
this.color = color;
}
}
C# версия:
class Polygon
{
uint NumVertices;
Polygon(uint numVertices)
{
NumVertices = numVertices;
}
}
class Triangle : Polygon
{
String Color;
Triangle(uint numVertices, String color)
: base(numVertices)
{
}
}
Помимо того, что мы снова заменили super на base, вы можете заметить, что вызов происходит до выполнения кода в конструкторе (до фигурных скобок {}). Так же, вызову конструктора родительского класса предшествует двоеточие (:). Обратите внимание, что в конце строки вызова, не ставится точка с запятой (;).
Давайте разберём, как в AS3 сделать так, чтобы класс нельзя было расширить:
final class FinalClass
{
}
// Этот класс не будет компилироваться
class DerviedClass extends FinalClass
{
}
Похожий функционал в C#:
sealed class FinalClass
{
}
// Этот класс не будет компилироваться
class DerviedClass : FinalClass
{
}
В данном случае различия между C# и AS3 состоят только в названии ключевых слов. В C# класс, котоырй нельзя расширить обозначается ключевым словом sealed, а в AS3 для этого используется final, но эффект — абсолютно одинаковый.
В завершении, сравнение описанных особенностей C# и AS3 кода:
|
|
На этом мы сегодня закругляемся. В следующей статье мы поговорим о геттерах и сеттерах (getter/setter) и закончим описание основ классов. После чего, мы сможем перейти к нюансам C#, аналогов которых нет в AS3.
Автор: COOL_ALMANAH