Aracılığıyla paylaş


about_Classes_Inheritance

Kısa açıklama

Diğer türleri genişleten sınıfları nasıl tanımlayabileceğinizi açıklar.

Uzun açıklama

PowerShell sınıfları, bir üst sınıfın davranışını yeniden kullanan (devralan), genişleten veya değiştiren bir alt sınıf tanımlamanızı sağlayan devralmayı destekler. Üyeleri devralınan sınıfa temel sınıf adı verilir. Temel sınıfın üyelerini devralan sınıf, türetilmiş sınıf olarak adlandırılır.

PowerShell yalnızca tek devralmayı destekler. Bir sınıf yalnızca tek bir sınıftan devralabilir. Ancak, devralma geçişlidir ve bir tür kümesi için devralma hiyerarşisi tanımlamanızı sağlar. Başka bir deyişle, D türü, A temel sınıf türünden devralan B türünden devralan C türünden devralabilir. Devralma geçişli olduğundan, A türünün üyeleri D türü için kullanılabilir.

Türetilmiş sınıflar temel sınıfın tüm üyelerini devralmaz. Aşağıdaki üyeler devralınmıyor:

  • Bir sınıfın statik verilerini başlatan statik oluşturucular.
  • Sınıfının yeni bir örneğini oluşturmak için çağırdığınız örnek oluşturucuları. Her sınıfın kendi oluşturucularını tanımlaması gerekir.

Varolan bir sınıftan türetilen yeni bir sınıf oluşturarak bir sınıfı genişletebilirsiniz. Türetilmiş sınıf, temel sınıfın özelliklerini ve yöntemlerini devralır. Temel sınıf üyelerini gerektiği gibi ekleyebilir veya geçersiz kılabilirsiniz.

Sınıflar, bir sözleşme tanımlayan arabirimlerden de devralabilir. Bir arabirimden devralan bir sınıfın bu sözleşmeyi uygulaması gerekir. Bunu yaptığı zaman sınıfı, bu arabirimi uygulayan diğer tüm sınıflar gibi kullanılabilir. Bir sınıf bir arabirimden devralır ancak arabirimi uygulamazsa, PowerShell sınıf için ayrıştırma hatası oluşturur.

Bazı PowerShell işleçleri, belirli bir arabirimi uygulayan bir sınıfa bağlıdır. Örneğin, -eq sınıf System.IEquatable arabirimini uygulamadığı sürece işleç yalnızca başvuru eşitliğini denetler. -le, -lt, -geve -gt işleçleri yalnızca System.IComparable arabirimini uygulayan sınıflarda çalışır.

Türetilmiş bir sınıf, bir temel sınıfı genişletmek veya arabirimleri uygulamak için söz dizimini kullanır : . Türetilmiş sınıf her zaman sınıf bildiriminde en sol tarafta olmalıdır.

Bu örnekte temel PowerShell sınıf devralma söz dizimi gösterilmektedir.

Class Derived : Base {...}

Bu örnekte, temel sınıftan sonra gelen bir arabirim bildirimiyle devralma gösterilmektedir.

Class Derived : Base, Interface {...}

Sözdizimi

Sınıf devralma aşağıdaki söz dizimlerini kullanır:

Bir satır söz dizimi

class <derived-class-name> : <base-class-or-interface-name>[, <interface-name>...] {
    <derived-class-body>
}

Örneğin:

# Base class only
class Derived : Base {...}
# Interface only
class Derived : System.IComparable {...}
# Base class and interface
class Derived : Base, System.IComparable {...}

Çok satırlı söz dizimi

class <derived-class-name> : <base-class-or-interface-name>[,
    <interface-name>...] {
    <derived-class-body>
}

Örneğin:

class Derived : Base,
                System.IComparable,
                System.IFormattable,
                System.IConvertible {
    # Derived class definition
}

Örnekler

Örnek 1 - Temel sınıftan devralma ve geçersiz kılma

Aşağıdaki örnekte, devralınan özelliklerin geçersiz kılınmadan ve geçersiz kılınmadan davranışı gösterilmektedir. Açıklamalarını okuduktan sonra kod bloklarını sırayla çalıştırın.

Temel sınıfı tanımlama

İlk kod bloğu, PublishedWork'i temel sınıf olarak tanımlar. Liste ve Sanatçılar olarak iki statik özelliği vardır. Ardından, statik List özelliğine ve sanatçılara Artists özelliğine çalışmalar eklemek için statik RegisterWork()yöntemi tanımlar ve listelerdeki her yeni girdi için bir ileti yazar.

sınıfı, yayımlanmış bir çalışmayı açıklayan üç örnek özelliği tanımlar. Son olarak ve ToString() örnek yöntemlerini tanımlarRegister().

class PublishedWork {
    static [PublishedWork[]] $List    = @()
    static [string[]]        $Artists = @()

    static [void] RegisterWork([PublishedWork]$Work) {
        $wName   = $Work.Name
        $wArtist = $Work.Artist
        if ($Work -notin [PublishedWork]::List) {
            Write-Verbose "Adding work '$wName' to works list"
            [PublishedWork]::List += $Work
        } else {
            Write-Verbose "Work '$wName' already registered."
        }
        if ($wArtist -notin [PublishedWork]::Artists) {
            Write-Verbose "Adding artist '$wArtist' to artists list"
            [PublishedWork]::Artists += $wArtist
        } else {
            Write-Verbose "Artist '$wArtist' already registered."
        }
    }

    static [void] ClearRegistry() {
        Write-Verbose "Clearing PublishedWork registry"
        [PublishedWork]::List    = @()
        [PublishedWork]::Artists = @()
    }

    [string] $Name
    [string] $Artist
    [string] $Category

    [void] Init([string]$WorkType) {
        if ([string]::IsNullOrEmpty($this.Category)) {
            $this.Category = "${WorkType}s"
        }
    }

    PublishedWork() {
        $WorkType = $this.GetType().FullName
        $this.Init($WorkType)
        Write-Verbose "Defined a published work of type [$WorkType]"
    }

    PublishedWork([string]$Name, [string]$Artist) {
        $WorkType    = $this.GetType().FullName
        $this.Name   = $Name
        $this.Artist = $Artist
        $this.Init($WorkType)

        Write-Verbose "Defined '$Name' by $Artist as a published work of type [$WorkType]"
    }

    PublishedWork([string]$Name, [string]$Artist, [string]$Category) {
        $WorkType    = $this.GetType().FullName
        $this.Name   = $Name
        $this.Artist = $Artist
        $this.Init($WorkType)

        Write-Verbose "Defined '$Name' by $Artist ($Category) as a published work of type [$WorkType]"
    }

    [void]   Register() { [PublishedWork]::RegisterWork($this) }
    [string] ToString() { return "$($this.Name) by $($this.Artist)" }
}

Geçersiz kılmalar olmadan türetilmiş bir sınıf tanımlama

İlk türetilen sınıf Albüm'dür. Hiçbir özelliği veya yöntemi geçersiz kılmaz. Temel sınıfta mevcut olmayan genres adlı yeni bir örnek özelliği ekler.

class Album : PublishedWork {
    [string[]] $Genres   = @()
}

Aşağıdaki kod bloğu, türetilmiş Album sınıfının davranışını gösterir. İlk olarak, sınıf yöntemlerinden gelen iletilerin konsola yayması için öğesini ayarlar $VerbosePreference . Sınıfının üç örneğini oluşturur, bunları bir tabloda gösterir ve ardından devralınan statik RegisterWork() yöntemle kaydeder. Ardından doğrudan temel sınıfta aynı statik yöntemi çağırır.

$VerbosePreference = 'Continue'
$Albums = @(
    [Album]@{
        Name   = 'The Dark Side of the Moon'
        Artist = 'Pink Floyd'
        Genres = 'Progressive rock', 'Psychedelic rock'
    }
    [Album]@{
        Name   = 'The Wall'
        Artist = 'Pink Floyd'
        Genres = 'Progressive rock', 'Art rock'
    }
    [Album]@{
        Name   = '36 Chambers'
        Artist = 'Wu-Tang Clan'
        Genres = 'Hip hop'
    }
)

$Albums | Format-Table
$Albums | ForEach-Object { [Album]::RegisterWork($_) }
$Albums | ForEach-Object { [PublishedWork]::RegisterWork($_) }
VERBOSE: Defined a published work of type [Album]
VERBOSE: Defined a published work of type [Album]
VERBOSE: Defined a published work of type [Album]

Genres                               Name                      Artist       Category
------                               ----                      ------       --------
{Progressive rock, Psychedelic rock} The Dark Side of the Moon Pink Floyd   Albums
{Progressive rock, Art rock}         The Wall                  Pink Floyd   Albums
{Hip hop}                            36 Chambers               Wu-Tang Clan Albums

VERBOSE: Adding work 'The Dark Side of the Moon' to works list
VERBOSE: Adding artist 'Pink Floyd' to artists list
VERBOSE: Adding work 'The Wall' to works list
VERBOSE: Artist 'Pink Floyd' already registered.
VERBOSE: Adding work '36 Chambers' to works list
VERBOSE: Adding artist 'Wu-Tang Clan' to artists list

VERBOSE: Work 'The Dark Side of the Moon' already registered.
VERBOSE: Artist 'Pink Floyd' already registered.
VERBOSE: Work 'The Wall' already registered.
VERBOSE: Artist 'Pink Floyd' already registered.
VERBOSE: Work '36 Chambers' already registered.
VERBOSE: Artist 'Wu-Tang Clan' already registered.

Album sınıfı Category veya herhangi bir oluşturucu için bir değer tanımlamamış olsa da, özelliğin temel sınıfın varsayılan oluşturucusunun tanımladığına dikkat edin.

Ayrıntılı mesajlaşmada, yönteme RegisterWork() yapılan ikinci çağrı, çalışmaların ve sanatçıların zaten kayıtlı olduğunu bildirir. İlk çağrısı RegisterWork() türetilmiş Album sınıfı için olsa da, temel PublishedWork sınıfından devralınan statik yöntemi kullandı. Bu yöntem, türetilmiş sınıfın geçersiz kılmadığı temel sınıftaki statik List ve Artist özelliklerini güncelleştirdi.

Sonraki kod bloğu kayıt defterini temizler ve Album nesnelerinde örnek yöntemini çağırırRegister().

[PublishedWork]::ClearRegistry()
$Albums.Register()
VERBOSE: Clearing PublishedWork registry

VERBOSE: Adding work 'The Dark Side of the Moon' to works list
VERBOSE: Adding artist 'Pink Floyd' to artists list
VERBOSE: Adding work 'The Wall' to works list
VERBOSE: Artist 'Pink Floyd' already registered.
VERBOSE: Adding work '36 Chambers' to works list
VERBOSE: Adding artist 'Wu-Tang Clan' to artists list

Album nesnelerindeki örnek yöntemi, türetilmiş veya temel sınıfta statik yöntemi çağırmakla aynı etkiye sahiptir.

Aşağıdaki kod bloğu, temel sınıfın statik özelliklerini ve türetilmiş sınıfı karşılaştırır ve bunların aynı olduğunu gösterir.

[pscustomobject]@{
    '[PublishedWork]::List'    = [PublishedWork]::List -join ",`n"
    '[Album]::List'            = [Album]::List -join ",`n"
    '[PublishedWork]::Artists' = [PublishedWork]::Artists -join ",`n"
    '[Album]::Artists'         = [Album]::Artists -join ",`n"
    'IsSame::List'             = (
        [PublishedWork]::List.Count -eq [Album]::List.Count -and
        [PublishedWork]::List.ToString() -eq [Album]::List.ToString()
    )
    'IsSame::Artists'          = (
        [PublishedWork]::Artists.Count -eq [Album]::Artists.Count -and
        [PublishedWork]::Artists.ToString() -eq [Album]::Artists.ToString()
    )
} | Format-List
[PublishedWork]::List    : The Dark Side of the Moon by Pink Floyd,
                           The Wall by Pink Floyd,
                           36 Chambers by Wu-Tang Clan
[Album]::List            : The Dark Side of the Moon by Pink Floyd,
                           The Wall by Pink Floyd,
                           36 Chambers by Wu-Tang Clan
[PublishedWork]::Artists : Pink Floyd,
                           Wu-Tang Clan
[Album]::Artists         : Pink Floyd,
                           Wu-Tang Clan
IsSame::List             : True
IsSame::Artists          : True

Geçersiz kılmalarla türetilmiş bir sınıf tanımlama

Sonraki kod bloğu, temel PublishedWork sınıfından devralan Illustration sınıfını tanımlar. Yeni sınıf, orta örnek özelliğini varsayılan değeri Unknownolan tanımlayarak temel sınıfı genişletir.

Türetilmiş Album sınıfından farklı olarak, Çizim aşağıdaki özellikleri ve yöntemleri geçersiz kılar:

  • Statik Artists özelliğini geçersiz kılar. Tanım aynıdır, ancak Illustration sınıfı bunu doğrudan bildirir.
  • Kategori örneği özelliğini geçersiz kılar ve varsayılan değeri olarak Illustrationsayarlar.
  • Bir çizimin ToString() dize gösteriminin oluşturulduğu ortamı içermesi için örnek yöntemini geçersiz kılar.

sınıfı, önce temel sınıf yöntemini çağırmak ve ardından sanatçıyı türetilen sınıfta RegisterWork() geçersiz kılınan Artists statik özelliğine eklemek için statik RegisterIllustration() yöntemi de tanımlar.

Son olarak, sınıfı üç oluşturucuyu da geçersiz kılar:

  1. Varsayılan oluşturucu, çizim oluşturduğunu belirten ayrıntılı bir ileti dışında boştur.
  2. Sonraki oluşturucu, çizimi oluşturan ad ve sanatçı için iki dize değeri alır. Oluşturucu, Name ve Artist özelliklerini ayarlamak için mantığı uygulamak yerine temel sınıftan uygun oluşturucuyu çağırır.
  3. Son oluşturucu, çizimin adı, sanatçısı ve ortamı için üç dize değeri alır. Her iki oluşturucu da bir çizim oluşturduklarını belirten ayrıntılı bir ileti yazar.
class Illustration : PublishedWork {
    static [string[]] $Artists = @()

    static [void] RegisterIllustration([Illustration]$Work) {
        $wArtist = $Work.Artist

        [PublishedWork]::RegisterWork($Work)

        if ($wArtist -notin [Illustration]::Artists) {
            Write-Verbose "Adding illustrator '$wArtist' to artists list"
            [Illustration]::Artists += $wArtist
        } else {
            Write-Verbose "Illustrator '$wArtist' already registered."
        }
    }

    [string] $Category = 'Illustrations'
    [string] $Medium   = 'Unknown'

    [string] ToString() {
        return "$($this.Name) by $($this.Artist) ($($this.Medium))"
    }

    Illustration() {
        Write-Verbose 'Defined an illustration'
    }

    Illustration([string]$Name, [string]$Artist) : base($Name, $Artist) {
        Write-Verbose "Defined '$Name' by $Artist ($($this.Medium)) as an illustration"
    }

    Illustration([string]$Name, [string]$Artist, [string]$Medium) {
        $this.Name = $Name
        $this.Artist = $Artist
        $this.Medium = $Medium

        Write-Verbose "Defined '$Name' by $Artist ($Medium) as an illustration"
    }
}

Aşağıdaki kod bloğu, türetilmiş Illustration sınıfının davranışını gösterir. Sınıfının üç örneğini oluşturur, bunları bir tabloda gösterir ve ardından devralınan statik RegisterWork() yöntemle kaydeder. Ardından doğrudan temel sınıfta aynı statik yöntemi çağırır. Son olarak, temel sınıf ve türetilmiş sınıf için kayıtlı sanatçıların listesini gösteren iletiler yazar.

$Illustrations = @(
    [Illustration]@{
        Name   = 'The Funny Thing'
        Artist = 'Wanda Gág'
        Medium = 'Lithography'
    }
    [Illustration]::new('Millions of Cats', 'Wanda Gág')
    [Illustration]::new(
      'The Lion and the Mouse',
      'Jerry Pinkney',
      'Watercolor'
    )
)

$Illustrations | Format-Table
$Illustrations | ForEach-Object { [Illustration]::RegisterIllustration($_) }
$Illustrations | ForEach-Object { [PublishedWork]::RegisterWork($_) }
"Published work artists: $([PublishedWork]::Artists -join ', ')"
"Illustration artists: $([Illustration]::Artists -join ', ')"
VERBOSE: Defined a published work of type [Illustration]
VERBOSE: Defined an illustration
VERBOSE: Defined 'Millions of Cats' by Wanda Gág as a published work of type [Illustration]
VERBOSE: Defined 'Millions of Cats' by Wanda Gág (Unknown) as an illustration
VERBOSE: Defined a published work of type [Illustration]
VERBOSE: Defined 'The Lion and the Mouse' by Jerry Pinkney (Watercolor) as an illustration

Category      Medium      Name                   Artist
--------      ------      ----                   ------
Illustrations Lithography The Funny Thing        Wanda Gág
Illustrations Unknown     Millions of Cats       Wanda Gág
Illustrations Watercolor  The Lion and the Mouse Jerry Pinkney

VERBOSE: Adding work 'The Funny Thing' to works list
VERBOSE: Adding artist 'Wanda Gág' to artists list
VERBOSE: Adding illustrator 'Wanda Gág' to artists list
VERBOSE: Adding work 'Millions of Cats' to works list
VERBOSE: Artist 'Wanda Gág' already registered.
VERBOSE: Illustrator 'Wanda Gág' already registered.
VERBOSE: Adding work 'The Lion and the Mouse' to works list
VERBOSE: Adding artist 'Jerry Pinkney' to artists list
VERBOSE: Adding illustrator 'Jerry Pinkney' to artists list

VERBOSE: Work 'The Funny Thing' already registered.
VERBOSE: Artist 'Wanda Gág' already registered.
VERBOSE: Work 'Millions of Cats' already registered.
VERBOSE: Artist 'Wanda Gág' already registered.
VERBOSE: Work 'The Lion and the Mouse' already registered.
VERBOSE: Artist 'Jerry Pinkney' already registered.

Published work artists: Pink Floyd, Wu-Tang Clan, Wanda Gág, Jerry Pinkney

Illustration artists: Wanda Gág, Jerry Pinkney

Örnekleri oluşturma işleminin ayrıntılı mesajlaşması şunları gösterir:

  • İlk örneği oluştururken temel sınıf varsayılan oluşturucu, türetilmiş sınıf varsayılan oluşturucusunun önünde çağrılır.
  • İkinci örnek oluşturulurken, türetilmiş sınıf oluşturucudan önce temel sınıf için açıkça devralınan oluşturucu çağrıldı.
  • Üçüncü örneği oluştururken, temel sınıf varsayılan oluşturucu türetilmiş sınıf oluşturucudan önce çağrıldı.

yönteminden gelen RegisterWork() ayrıntılı iletiler, çalışmaların ve sanatçıların zaten kayıtlı olduğunu gösterir. Bunun nedeni yönteminin RegisterIllustration() dahili olarak yöntemini çağırmasıdır RegisterWork() .

Ancak, hem temel hem de türetilmiş sınıf için statik Artist özelliğinin değeri karşılaştırılırken, değerler farklıdır. Türetilmiş sınıfın Artists özelliği yalnızca illüstratörleri içerir, albüm sanatçılarını içermez. Türetilmiş sınıfta Artist özelliğini yeniden tanımlayarak sınıfın temel sınıfta statik özelliği döndürmesini engeller.

Son kod bloğu, temel sınıftaki statik List özelliğinin girdilerinde yöntemini çağırırToString().

[PublishedWork]::List | ForEach-Object -Process { $_.ToString() }
The Dark Side of the Moon by Pink Floyd
The Wall by Pink Floyd
36 Chambers by Wu-Tang Clan
The Funny Thing by Wanda Gág (Lithography)
Millions of Cats by Wanda Gág (Unknown)
The Lion and the Mouse by Jerry Pinkney (Watercolor)

Albüm örnekleri yalnızca dizelerindeki adı ve sanatçıyı döndürür. Çizim örnekleri, bu sınıf yöntemin üzerine ToString() geçtiğinden, ortamı parantez içinde de içerir.

Örnek 2 - Arabirimleri uygulama

Aşağıdaki örnekte bir sınıfın bir veya daha fazla arabirimi nasıl uygulayabileceği gösterilmektedir. Örnek, daha fazla işlem ve davranışı desteklemek için Temperature sınıfının tanımını genişletir.

İlk sınıf tanımı

Arabirimleri uygulamadan önce Temperature sınıfı, Derece ve Ölçek olarak iki özellik ile tanımlanır. Örneği belirli bir ölçeğin dereceleri olarak döndürmek için oluşturucuları ve üç örnek yöntemini tanımlar.

sınıfı, TemperatureScale numaralandırması ile kullanılabilir ölçekleri tanımlar.

class Temperature {
    [float]            $Degrees
    [TemperatureScale] $Scale

    Temperature() {}
    Temperature([float] $Degrees)          { $this.Degrees = $Degrees }
    Temperature([TemperatureScale] $Scale) { $this.Scale = $Scale }
    Temperature([float] $Degrees, [TemperatureScale] $Scale) {
        $this.Degrees = $Degrees
        $this.Scale   = $Scale
    }

    [float] ToKelvin() {
        switch ($this.Scale) {
            Celsius    { return $this.Degrees + 273.15 }
            Fahrenheit { return ($this.Degrees + 459.67) * 5/9 }
        }
        return $this.Degrees
    }
    [float] ToCelsius() {
        switch ($this.Scale) {
            Fahrenheit { return ($this.Degrees - 32) * 5/9 }
            Kelvin     { return $this.Degrees - 273.15 }
        }
        return $this.Degrees
    }
    [float] ToFahrenheit() {
        switch ($this.Scale) {
            Celsius    { return $this.Degrees * 9/5 + 32 }
            Kelvin     { return $this.Degrees * 9/5 - 459.67 }
        }
        return $this.Degrees
    }
}

enum TemperatureScale {
    Celsius    = 0
    Fahrenheit = 1
    Kelvin     = 2
}

Ancak, bu temel uygulamada, aşağıdaki örnek çıktıda gösterildiği gibi birkaç sınırlama vardır:

$Celsius    = [Temperature]::new()
$Fahrenheit = [Temperature]::new([TemperatureScale]::Fahrenheit)
$Kelvin     = [Temperature]::new(0, 'Kelvin')

$Celsius, $Fahrenheit, $Kelvin

"The temperatures are: $Celsius, $Fahrenheit, $Kelvin"

[Temperature]::new() -eq $Celsius

$Celsius -gt $Kelvin
Degrees      Scale
-------      -----
   0.00    Celsius
   0.00 Fahrenheit
   0.00     Kelvin

The temperatures are: Temperature, Temperature, Temperature

False

InvalidOperation:
Line |
  11 |  $Celsius -gt $Kelvin
     |  ~~~~~~~~~~~~~~~~~~~~
     | Cannot compare "Temperature" because it is not IComparable.

Çıktıda Sıcaklık örnekleri gösterilmektedir:

  • Dize olarak doğru görüntülenmez.
  • Eşitlik için doğru şekilde denetlenemiyor.
  • Karşılaştırılamaz.

Bu üç sorun, sınıfı için arabirimler uygulanarak giderilebilir.

IFormattable Uygulama

Temperature sınıfı için uygulanacak ilk arabirim System.IFormattable'dır. Bu arabirim, sınıfın bir örneğini farklı dizeler olarak biçimlendirmeye olanak tanır. Arabirimi uygulamak için sınıfının System.IFormattable'dan devralması ve örnek yöntemini tanımlaması ToString() gerekir.

Örnek yönteminin ToString() aşağıdaki imzaya sahip olması gerekir:

[string] ToString(
    [string]$Format,
    [System.IFormatProvider]$FormatProvider
) {
    # Implementation
}

Arabirimin gerektirdiği imza, başvuru belgelerinde listelenir.

Sıcaklık için sınıfı üç biçimi desteklemelidir: C santigrat cinsinden örneği döndürmek, F Fahrenheit'te döndürmek ve K Kelvin'de döndürmek. Başka bir biçim için yöntemi bir System.FormatException oluşturmalıdır.

[string] ToString(
    [string]$Format,
    [System.IFormatProvider]$FormatProvider
) {
    # If format isn't specified, use the defined scale.
    if ([string]::IsNullOrEmpty($Format)) {
        $Format = switch ($this.Scale) {
            Celsius    { 'C' }
            Fahrenheit { 'F' }
            Kelvin     { 'K' }
        }
    }
    # If format provider isn't specified, use the current culture.
    if ($null -eq $FormatProvider) {
        $FormatProvider = [CultureInfo]::CurrentCulture
    }
    # Format the temperature.
    switch ($Format) {
        'C' {
            return $this.ToCelsius().ToString('F2', $FormatProvider) + '°C'
        }
        'F' {
            return $this.ToFahrenheit().ToString('F2', $FormatProvider) + '°F'
        }
        'K' {
            return $this.ToKelvin().ToString('F2', $FormatProvider) + '°K'
        }
    }
    # If we get here, the format is invalid.
    throw [System.FormatException]::new(
        "Unknown format: '$Format'. Valid Formats are 'C', 'F', and 'K'"
    )
}

Bu uygulamada yöntem, sayısal derece değerinin kendisini biçimlendirirken varsayılan olarak biçim ve geçerli kültür için örnek ölçeğini kullanır. Dereceleri To<Scale>() dönüştürmek, iki ondalık basameğe biçimlendirmek ve dizeye uygun derece simgesini eklemek için örnek yöntemlerini kullanır.

Gerekli imza uygulandığında sınıf, biçimlendirilmiş örneği döndürmeyi kolaylaştırmak için aşırı yüklemeler de tanımlayabilir.

[string] ToString([string]$Format) {
    return $this.ToString($Format, $null)
}

[string] ToString() {
    return $this.ToString($null, $null)
}

Aşağıdaki kod Sıcaklık için güncelleştirilmiş tanımı gösterir:

class Temperature : System.IFormattable {
    [float]            $Degrees
    [TemperatureScale] $Scale

    Temperature() {}
    Temperature([float] $Degrees)          { $this.Degrees = $Degrees }
    Temperature([TemperatureScale] $Scale) { $this.Scale = $Scale }
    Temperature([float] $Degrees, [TemperatureScale] $Scale) {
        $this.Degrees = $Degrees
        $this.Scale = $Scale
    }

    [float] ToKelvin() {
        switch ($this.Scale) {
            Celsius { return $this.Degrees + 273.15 }
            Fahrenheit { return ($this.Degrees + 459.67) * 5 / 9 }
        }
        return $this.Degrees
    }
    [float] ToCelsius() {
        switch ($this.Scale) {
            Fahrenheit { return ($this.Degrees - 32) * 5 / 9 }
            Kelvin { return $this.Degrees - 273.15 }
        }
        return $this.Degrees
    }
    [float] ToFahrenheit() {
        switch ($this.Scale) {
            Celsius { return $this.Degrees * 9 / 5 + 32 }
            Kelvin { return $this.Degrees * 9 / 5 - 459.67 }
        }
        return $this.Degrees
    }

    [string] ToString(
        [string]$Format,
        [System.IFormatProvider]$FormatProvider
    ) {
        # If format isn't specified, use the defined scale.
        if ([string]::IsNullOrEmpty($Format)) {
            $Format = switch ($this.Scale) {
                Celsius    { 'C' }
                Fahrenheit { 'F' }
                Kelvin     { 'K' }
            }
        }
        # If format provider isn't specified, use the current culture.
        if ($null -eq $FormatProvider) {
            $FormatProvider = [CultureInfo]::CurrentCulture
        }
        # Format the temperature.
        switch ($Format) {
            'C' {
                return $this.ToCelsius().ToString('F2', $FormatProvider) + '°C'
            }
            'F' {
                return $this.ToFahrenheit().ToString('F2', $FormatProvider) + '°F'
            }
            'K' {
                return $this.ToKelvin().ToString('F2', $FormatProvider) + '°K'
            }
        }
        # If we get here, the format is invalid.
        throw [System.FormatException]::new(
            "Unknown format: '$Format'. Valid Formats are 'C', 'F', and 'K'"
        )
    }

    [string] ToString([string]$Format) {
        return $this.ToString($Format, $null)
    }

    [string] ToString() {
        return $this.ToString($null, $null)
    }
}

enum TemperatureScale {
    Celsius    = 0
    Fahrenheit = 1
    Kelvin     = 2
}

Yöntem aşırı yüklemelerinin çıkışı aşağıdaki blokta gösterilir.

$Temp = [Temperature]::new()
"The temperature is $Temp"
$Temp.ToString()
$Temp.ToString('K')
$Temp.ToString('F', $null)
The temperature is 0.00°C

0.00°C

273.15°K

32.00°F

IEquatable Uygulama

Artık Temperature sınıfı okunabilirlik için biçimlendirilebildiğine göre, kullanıcıların sınıfın iki örneğinin eşit olup olmadığını denetleyebilmesi gerekir. Bu testi desteklemek için sınıfının System.IEquatable arabirimini uygulaması gerekir.

Arabirimi uygulamak için sınıfının System.IEquatable'dan devralması ve örnek yöntemini tanımlaması Equals() gerekir. Yöntemin Equals() aşağıdaki imzaya sahip olması gerekir:

[bool] Equals([object]$Other) {
    # Implementation
}

Arabirimin gerektirdiği imza, başvuru belgelerinde listelenir.

Sıcaklık için sınıfın yalnızca iki örneğini karşılaştırmayı desteklemesi gerekir. dahil olmak üzere $nulldiğer herhangi bir değer veya tür için döndürmelidir $false. İki sıcaklığı karşılaştırırken, sıcaklıklar farklı ölçeklerle bile eşdeğer olabileceğinden, yöntem her iki değeri de Kelvin'e dönüştürmelidir.

[bool] Equals([object]$Other) {
    # If the other object is null, we can't compare it.
    if ($null -eq $Other) {
        return $false
    }

    # If the other object isn't a temperature, we can't compare it.
    $OtherTemperature = $Other -as [Temperature]
    if ($null -eq $OtherTemperature) {
        return $false
    }

    # Compare the temperatures as Kelvin.
    return $this.ToKelvin() -eq $OtherTemperature.ToKelvin()
}

Uygulanan arabirim yöntemiyle, Temperature için güncelleştirilmiş tanım şu şekildedir:

class Temperature : System.IFormattable, System.IEquatable[object] {
    [float]            $Degrees
    [TemperatureScale] $Scale

    Temperature() {}
    Temperature([float] $Degrees)          { $this.Degrees = $Degrees }
    Temperature([TemperatureScale] $Scale) { $this.Scale = $Scale }
    Temperature([float] $Degrees, [TemperatureScale] $Scale) {
        $this.Degrees = $Degrees
        $this.Scale = $Scale
    }

    [float] ToKelvin() {
        switch ($this.Scale) {
            Celsius { return $this.Degrees + 273.15 }
            Fahrenheit { return ($this.Degrees + 459.67) * 5 / 9 }
        }
        return $this.Degrees
    }
    [float] ToCelsius() {
        switch ($this.Scale) {
            Fahrenheit { return ($this.Degrees - 32) * 5 / 9 }
            Kelvin { return $this.Degrees - 273.15 }
        }
        return $this.Degrees
    }
    [float] ToFahrenheit() {
        switch ($this.Scale) {
            Celsius { return $this.Degrees * 9 / 5 + 32 }
            Kelvin { return $this.Degrees * 9 / 5 - 459.67 }
        }
        return $this.Degrees
    }

    [string] ToString(
        [string]$Format,
        [System.IFormatProvider]$FormatProvider
    ) {
        # If format isn't specified, use the defined scale.
        if ([string]::IsNullOrEmpty($Format)) {
            $Format = switch ($this.Scale) {
                Celsius    { 'C' }
                Fahrenheit { 'F' }
                Kelvin     { 'K' }
            }
        }
        # If format provider isn't specified, use the current culture.
        if ($null -eq $FormatProvider) {
            $FormatProvider = [CultureInfo]::CurrentCulture
        }
        # Format the temperature.
        switch ($Format) {
            'C' {
                return $this.ToCelsius().ToString('F2', $FormatProvider) + '°C'
            }
            'F' {
                return $this.ToFahrenheit().ToString('F2', $FormatProvider) + '°F'
            }
            'K' {
                return $this.ToKelvin().ToString('F2', $FormatProvider) + '°K'
            }
        }
        # If we get here, the format is invalid.
        throw [System.FormatException]::new(
            "Unknown format: '$Format'. Valid Formats are 'C', 'F', and 'K'"
        )
    }

    [string] ToString([string]$Format) {
        return $this.ToString($Format, $null)
    }

    [string] ToString() {
        return $this.ToString($null, $null)
    }

    [bool] Equals([object]$Other) {
        # If the other object is null, we can't compare it.
        if ($null -eq $Other) {
            return $false
        }

        # If the other object isn't a temperature, we can't compare it.
        $OtherTemperature = $Other -as [Temperature]
        if ($null -eq $OtherTemperature) {
            return $false
        }

        # Compare the temperatures as Kelvin.
        return $this.ToKelvin() -eq $OtherTemperature.ToKelvin()
    }
}

enum TemperatureScale {
    Celsius    = 0
    Fahrenheit = 1
    Kelvin     = 2
}

Aşağıdaki blok, güncelleştirilmiş sınıfın nasıl davrandığını gösterir:

$Celsius    = [Temperature]::new()
$Fahrenheit = [Temperature]::new(32, 'Fahrenheit')
$Kelvin     = [Temperature]::new([TemperatureScale]::Kelvin)

@"
Temperatures are: $Celsius, $Fahrenheit, $Kelvin
`$Celsius.Equals(`$Fahrenheit) = $($Celsius.Equals($Fahrenheit))
`$Celsius -eq `$Fahrenheit     = $($Celsius -eq $Fahrenheit)
`$Celsius -ne `$Kelvin         = $($Celsius -ne $Kelvin)
"@
Temperatures are: 0.00°C, 32.00°F, 0.00°K

$Celsius.Equals($Fahrenheit) = True
$Celsius -eq $Fahrenheit     = True
$Celsius -ne $Kelvin         = True

IComparable Uygulama

Temperature sınıfı için uygulanacak son arabirim System.IComparable'dır. Sınıf bu arabirimi uyguladığında, kullanıcılar sınıfın -ltörneklerini karşılaştırmak için , -le, -gtve -ge işleçlerini kullanabilir.

Arabirimi uygulamak için sınıfının System.IComparable'dan devralması ve örnek yöntemini tanımlaması Equals() gerekir. Yöntemin Equals() aşağıdaki imzaya sahip olması gerekir:

[int] CompareTo([Object]$Other) {
    # Implementation
}

Arabirimin gerektirdiği imza, başvuru belgelerinde listelenir.

Sıcaklık için sınıfın yalnızca iki örneğini karşılaştırmayı desteklemesi gerekir. Farklı bir ölçeğe dönüştürülse bile Degrees özelliğinin temel türü kayan bir nokta numarası olduğundan, yöntem gerçek karşılaştırma için temel alınan türe dayanabilir.

[int] CompareTo([object]$Other) {
    # If the other object's null, consider this instance "greater than" it
    if ($null -eq $Other) {
        return 1
    }
    # If the other object isn't a temperature, we can't compare it.
    $OtherTemperature = $Other -as [Temperature]
    if ($null -eq $OtherTemperature) {
        throw [System.ArgumentException]::new(
            "Object must be of type 'Temperature'."
        )
    }
    # Compare the temperatures as Kelvin.
    return $this.ToKelvin().CompareTo($OtherTemperature.ToKelvin())
}

Temperature sınıfının son tanımı:

class Temperature : System.IFormattable,
                    System.IComparable,
                    System.IEquatable[object] {
    # Instance properties
    [float]            $Degrees
    [TemperatureScale] $Scale

    # Constructors
    Temperature() {}
    Temperature([float] $Degrees)          { $this.Degrees = $Degrees }
    Temperature([TemperatureScale] $Scale) { $this.Scale = $Scale }
    Temperature([float] $Degrees, [TemperatureScale] $Scale) {
        $this.Degrees = $Degrees
        $this.Scale = $Scale
    }

    [float] ToKelvin() {
        switch ($this.Scale) {
            Celsius { return $this.Degrees + 273.15 }
            Fahrenheit { return ($this.Degrees + 459.67) * 5 / 9 }
        }
        return $this.Degrees
    }
    [float] ToCelsius() {
        switch ($this.Scale) {
            Fahrenheit { return ($this.Degrees - 32) * 5 / 9 }
            Kelvin { return $this.Degrees - 273.15 }
        }
        return $this.Degrees
    }
    [float] ToFahrenheit() {
        switch ($this.Scale) {
            Celsius { return $this.Degrees * 9 / 5 + 32 }
            Kelvin { return $this.Degrees * 9 / 5 - 459.67 }
        }
        return $this.Degrees
    }

    [string] ToString(
        [string]$Format,
        [System.IFormatProvider]$FormatProvider
    ) {
        # If format isn't specified, use the defined scale.
        if ([string]::IsNullOrEmpty($Format)) {
            $Format = switch ($this.Scale) {
                Celsius    { 'C' }
                Fahrenheit { 'F' }
                Kelvin     { 'K' }
            }
        }
        # If format provider isn't specified, use the current culture.
        if ($null -eq $FormatProvider) {
            $FormatProvider = [CultureInfo]::CurrentCulture
        }
        # Format the temperature.
        switch ($Format) {
            'C' {
                return $this.ToCelsius().ToString('F2', $FormatProvider) + '°C'
            }
            'F' {
                return $this.ToFahrenheit().ToString('F2', $FormatProvider) + '°F'
            }
            'K' {
                return $this.ToKelvin().ToString('F2', $FormatProvider) + '°K'
            }
        }
        # If we get here, the format is invalid.
        throw [System.FormatException]::new(
            "Unknown format: '$Format'. Valid Formats are 'C', 'F', and 'K'"
        )
    }

    [string] ToString([string]$Format) {
        return $this.ToString($Format, $null)
    }

    [string] ToString() {
        return $this.ToString($null, $null)
    }

    [bool] Equals([object]$Other) {
        # If the other object is null, we can't compare it.
        if ($null -eq $Other) {
            return $false
        }
        # If the other object isn't a temperature, we can't compare it.
        $OtherTemperature = $Other -as [Temperature]
        if ($null -eq $OtherTemperature) {
            return $false
        }
        # Compare the temperatures as Kelvin.
        return $this.ToKelvin() -eq $OtherTemperature.ToKelvin()
    }
    [int] CompareTo([object]$Other) {
        # If the other object's null, consider this instance "greater than" it
        if ($null -eq $Other) {
            return 1
        }
        # If the other object isn't a temperature, we can't compare it.
        $OtherTemperature = $Other -as [Temperature]
        if ($null -eq $OtherTemperature) {
            throw [System.ArgumentException]::new(
                "Object must be of type 'Temperature'."
            )
        }
        # Compare the temperatures as Kelvin.
        return $this.ToKelvin().CompareTo($OtherTemperature.ToKelvin())
    }
}

enum TemperatureScale {
    Celsius    = 0
    Fahrenheit = 1
    Kelvin     = 2
}

Tam tanım ile, kullanıcılar herhangi bir yerleşik tür gibi PowerShell'deki sınıfın örneklerini biçimlendirebilir ve karşılaştırabilir.

$Celsius    = [Temperature]::new()
$Fahrenheit = [Temperature]::new(32, 'Fahrenheit')
$Kelvin     = [Temperature]::new([TemperatureScale]::Kelvin)

@"
Temperatures are: $Celsius, $Fahrenheit, $Kelvin
`$Celsius.Equals(`$Fahrenheit)    = $($Celsius.Equals($Fahrenheit))
`$Celsius.Equals(`$Kelvin)        = $($Celsius.Equals($Kelvin))
`$Celsius.CompareTo(`$Fahrenheit) = $($Celsius.CompareTo($Fahrenheit))
`$Celsius.CompareTo(`$Kelvin)     = $($Celsius.CompareTo($Kelvin))
`$Celsius -lt `$Fahrenheit        = $($Celsius -lt $Fahrenheit)
`$Celsius -le `$Fahrenheit        = $($Celsius -le $Fahrenheit)
`$Celsius -eq `$Fahrenheit        = $($Celsius -eq $Fahrenheit)
`$Celsius -gt `$Kelvin            = $($Celsius -gt $Kelvin)
"@
Temperatures are: 0.00°C, 32.00°F, 0.00°K
$Celsius.Equals($Fahrenheit)    = True
$Celsius.Equals($Kelvin)        = False
$Celsius.CompareTo($Fahrenheit) = 0
$Celsius.CompareTo($Kelvin)     = 1
$Celsius -lt $Fahrenheit        = False
$Celsius -le $Fahrenheit        = True
$Celsius -eq $Fahrenheit        = True
$Celsius -gt $Kelvin            = True

Örnek 3 - Genel bir temel sınıftan devralma

Bu örnek, System.Collections.Generic.List gibi genel bir sınıftan nasıl türetebileceğinizi gösterir.

Tür parametresi olarak yerleşik bir sınıf kullanma

Aşağıdaki kod bloğunu çalıştırın. Tür parametresi ayrıştırma zamanında tanımlandığı sürece yeni bir sınıfın genel bir türden nasıl devralınabileceğini gösterir.

class ExampleStringList : System.Collections.Generic.List[string] {}

$List = [ExampleStringList]::New()
$List.AddRange([string[]]@('a','b','c'))
$List.GetType() | Format-List -Property Name, BaseType
$List
Name     : ExampleStringList
BaseType : System.Collections.Generic.List`1[System.String]

a
b
c

Tür parametresi olarak özel bir sınıf kullanma

Sonraki kod bloğu ilk olarak tek bir örnek özelliği ve ToString() yöntemiyle exampleItem adlı yeni bir sınıfı tanımlar. Ardından System.Collections.Generic.List temel sınıfından devralan ExampleItemList sınıfını type parametresi olarak ExampleItem ile tanımlar.

Kod bloğunun tamamını kopyalayın ve tek bir deyim olarak çalıştırın.

class ExampleItem {
    [string] $Name
    [string] ToString() { return $this.Name }
}
class ExampleItemList : System.Collections.Generic.List[ExampleItem] {}
ParentContainsErrorRecordException: An error occurred while creating the pipeline.

PowerShell henüz ExampleItem sınıfını çalışma zamanına yüklemediğinden kod bloğunun tamamını çalıştırmak hataya neden olur. Henüz System.Collections.Generic.List temel sınıfı için tür parametresi olarak sınıf adı kullanamazsınız.

Aşağıdaki kod bloklarını tanımlandığı sırayla çalıştırın.

class ExampleItem {
    [string] $Name
    [string] ToString() { return $this.Name }
}
class ExampleItemList : System.Collections.Generic.List[ExampleItem] {}

Bu kez PowerShell herhangi bir hata oluşturmuyor. Her iki sınıf da tanımlanmıştır. Yeni sınıfın davranışını görüntülemek için aşağıdaki kod bloğunu çalıştırın.

$List = [ExampleItemList]::New()
$List.AddRange([ExampleItem[]]@(
    [ExampleItem]@{ Name = 'Foo' }
    [ExampleItem]@{ Name = 'Bar' }
    [ExampleItem]@{ Name = 'Baz' }
))
$List.GetType() | Format-List -Property Name, BaseType
$List
Name     : ExampleItemList
BaseType : System.Collections.Generic.List`1[ExampleItem]

Name
----
Foo
Bar
Baz

Modülde özel tür parametresiyle genel türetme

Aşağıdaki kod blokları, tür parametresi için özel bir tür kullanan genel bir temel sınıftan devralan bir sınıfı nasıl tanımlayabileceğinizi gösterir.

Aşağıdaki kod bloğunu olarak GenericExample.psd1kaydedin.

@{
    RootModule        = 'GenericExample.psm1'
    ModuleVersion     = '0.1.0'
    GUID              = '2779fa60-0b3b-4236-b592-9060c0661ac2'
}

Aşağıdaki kod bloğunu olarak GenericExample.InventoryItem.psm1kaydedin.

class InventoryItem {
    [string] $Name
    [int]    $Count

    InventoryItem() {}
    InventoryItem([string]$Name) {
        $this.Name = $Name
    }
    InventoryItem([string]$Name, [int]$Count) {
        $this.Name  = $Name
        $this.Count = $Count
    }

    [string] ToString() {
        return "$($this.Name) ($($this.Count))"
    }
}

Aşağıdaki kod bloğunu olarak GenericExample.psm1kaydedin.

using namespace System.Collections.Generic
using module ./GenericExample.InventoryItem.psm1

class Inventory : List[InventoryItem] {}

# Define the types to export with type accelerators.
$ExportableTypes =@(
    [InventoryItem]
    [Inventory]
)
# Get the internal TypeAccelerators class to use its static methods.
$TypeAcceleratorsClass = [psobject].Assembly.GetType(
    'System.Management.Automation.TypeAccelerators'
)
# Ensure none of the types would clobber an existing type accelerator.
# If a type accelerator with the same name exists, throw an exception.
$ExistingTypeAccelerators = $TypeAcceleratorsClass::Get
foreach ($Type in $ExportableTypes) {
    if ($Type.FullName -in $ExistingTypeAccelerators.Keys) {
        $Message = @(
            "Unable to register type accelerator '$($Type.FullName)'"
            'Accelerator already exists.'
        ) -join ' - '

        throw [System.Management.Automation.ErrorRecord]::new(
            [System.InvalidOperationException]::new($Message),
            'TypeAcceleratorAlreadyExists',
            [System.Management.Automation.ErrorCategory]::InvalidOperation,
            $Type.FullName
        )
    }
}
# Add type accelerators for every exportable type.
foreach ($Type in $ExportableTypes) {
    $TypeAcceleratorsClass::Add($Type.FullName, $Type)
}
# Remove type accelerators when the module is removed.
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    foreach($Type in $ExportableTypes) {
        $TypeAcceleratorsClass::Remove($Type.FullName)
    }
}.GetNewClosure()

İpucu

Kök modül, özel türleri PowerShell'in tür hızlandırıcılarına ekler. Bu düzen, modül kullanıcılarının önce deyimini kullanmaya using module gerek kalmadan intelliSense'e hemen erişmesine ve özel türler için otomatik tamamlamasına olanak tanır.

Bu düzen hakkında daha fazla bilgi için about_Classes'nin "Tür hızlandırıcılarıyla dışarı aktarma" bölümüne bakın.

Modülü içeri aktarın ve çıkışı doğrulayın.

Import-Module ./GenericExample.psd1

$Inventory = [Inventory]::new()
$Inventory.GetType() | Format-List -Property Name, BaseType

$Inventory.Add([InventoryItem]::new('Bucket', 2))
$Inventory.Add([InventoryItem]::new('Mop'))
$Inventory.Add([InventoryItem]@{ Name = 'Broom' ; Count = 4 })
$Inventory
Name     : Inventory
BaseType : System.Collections.Generic.List`1[InventoryItem]

Name   Count
----   -----
Bucket     2
Mop        0
Broom      4

InventoryItem sınıfı Inventory sınıfından farklı bir modül dosyasında tanımlandığından modül hatasız yüklenir. Her iki sınıf da modül kullanıcılarına sunulur.

Temel sınıfı devralma

Bir sınıf temel sınıftan devraldığında, temel sınıfın özelliklerini ve yöntemlerini devralır. Temel sınıf oluşturucularını doğrudan devralmaz, ancak bunları çağırabilir.

Temel sınıf PowerShell yerine .NET'te tanımlandığında şunları unutmayın:

  • PowerShell sınıfları korumalı sınıflardan devralamaz.
  • Genel bir temel sınıftan devralınırken, genel sınıfın tür parametresi türetilmiş sınıf olamaz. tür parametresi olarak türetilmiş sınıfın kullanılması ayrıştırma hatasına neden olur.

Devralma ve geçersiz kılmanın türetilmiş sınıflarda nasıl çalıştığını görmek için bkz . Örnek 1.

Türetilmiş sınıf oluşturucuları

Türetilmiş sınıflar doğrudan temel sınıfın oluşturucularını devralmaz. Temel sınıf varsayılan bir oluşturucu tanımlarsa ve türetilmiş sınıf herhangi bir oluşturucu tanımlamazsa, türetilmiş sınıfın yeni örnekleri temel sınıf varsayılan oluşturucuyu kullanır. Temel sınıf varsayılan bir oluşturucu tanımlamıyorsa, türetilmiş sınıfın en az bir oluşturucuyu açıkça tanımlaması gerekir.

Türetilmiş sınıf oluşturucuları temel sınıftan anahtar sözcüğüyle base bir oluşturucu çağırabilir. Türetilmiş sınıf açıkça temel sınıftan bir oluşturucu çağırmazsa, bunun yerine temel sınıf için varsayılan oluşturucuyu çağırır.

Ardıl olmayan bir temel oluşturucuyu çağırmak için oluşturucu parametrelerinin arkasına ve gövde bloğundan önce ekleyin : base(<parameters>) .

class <derived-class> : <base-class> {
    <derived-class>(<derived-parameters>) : <base-class>(<base-parameters>) {
        # initialization code
    }
}

Temel sınıf oluşturucuyu çağıran bir oluşturucu tanımlarken, parametreler aşağıdaki öğelerden herhangi biri olabilir:

  • Türetilmiş sınıf oluşturucusunun herhangi bir parametresinin değişkeni.
  • Herhangi bir statik değer.
  • Parametre türündeki bir değere göre değerlendirilen herhangi bir ifade.

Örnek 1'deki Çizim sınıfı, türetilmiş bir sınıfın temel sınıf oluşturucularını nasıl kullanabileceğini gösterir.

Türetilmiş sınıf yöntemleri

Bir sınıf bir temel sınıftan türetildiğinde, temel sınıfın yöntemlerini ve bunların aşırı yüklemelerini devralır. Gizli yöntemler de dahil olmak üzere temel sınıfta tanımlanan tüm yöntem aşırı yüklemeleri türetilmiş sınıfta kullanılabilir.

Türetilmiş bir sınıf, devralınan yöntem aşırı yüklemesini sınıf tanımında yeniden tanımlayarak geçersiz kılabilir. Aşırı yüklemeyi geçersiz kılmak için parametre türlerinin temel sınıfla aynı olması gerekir. Aşırı yüklemenin çıkış türü farklı olabilir.

Oluşturuculardan farklı olarak yöntemler, yöntemi için : base(<parameters>) temel sınıf aşırı yüklemesini çağırmak için söz dizimini kullanamaz. Türetilmiş sınıftaki yeniden tanımlanan aşırı yükleme, temel sınıf tarafından tanımlanan aşırı yüklemenin yerini tamamen alır. Bir örneğin temel sınıf yöntemini çağırmak için, yöntemini çağırmadan önce örnek değişkenini ($this) temel sınıfa yayınlayın.

Aşağıdaki kod parçacığı, türetilmiş bir sınıfın temel sınıf yöntemini nasıl çağırabileceğini gösterir.

class BaseClass {
    [bool] IsTrue() { return $true }
}
class DerivedClass : BaseClass {
    [bool] IsTrue()     { return $false }
    [bool] BaseIsTrue() { return ([BaseClass]$this).IsTrue() }
}

@"
[BaseClass]::new().IsTrue()        = $([BaseClass]::new().IsTrue())
[DerivedClass]::new().IsTrue()     = $([DerivedClass]::new().IsTrue())
[DerivedClass]::new().BaseIsTrue() = $([DerivedClass]::new().BaseIsTrue())
"@
[BaseClass]::new().IsTrue()        = True
[DerivedClass]::new().IsTrue()     = False
[DerivedClass]::new().BaseIsTrue() = True

Türetilmiş bir sınıfın devralınan yöntemleri nasıl geçersiz kılabileceğini gösteren genişletilmiş örnek için Örnek 1'deki Çizim sınıfına bakın.

Türetilmiş sınıf özellikleri

Bir sınıf bir temel sınıftan türetildiğinde, temel sınıfın özelliklerini devralır. Gizli özellikler de dahil olmak üzere temel sınıfta tanımlanan tüm özellikler türetilmiş sınıfta kullanılabilir.

Türetilmiş bir sınıf, devralınan bir özelliği sınıf tanımında yeniden tanımlayarak geçersiz kılabilir. Türetilmiş sınıftaki özelliği, varsa yeniden tanımlı türü ve varsayılan değeri kullanır. Devralınan özellik varsayılan bir değer tanımladıysa ve yeniden tanımlanan özellik tanımlamıyorsa, devralınan özelliğin varsayılan değeri yoktur.

Türetilmiş bir sınıf statik özelliği geçersiz kılmazsa, türetilmiş sınıf aracılığıyla statik özelliğe erişmek temel sınıfın statik özelliğine erişir. Türetilmiş sınıf aracılığıyla özellik değerinin değiştirilmesi, temel sınıftaki değeri değiştirir. Statik özelliği geçersiz kılmayan diğer türetilmiş herhangi bir sınıf da temel sınıfta özelliğinin değerini kullanır. Özelliği geçersiz kılmayan bir sınıfta devralınan statik özelliğin değerinin güncelleştirilmesi, aynı temel sınıftan türetilen sınıflar için istenmeyen etkilere neden olabilir.

Örnek 1,temel sınıf özelliklerini devralan, genişleten ve geçersiz kılan türetilmiş sınıfları gösterir.

Genel türlerden türetme

Bir sınıf genel bir sınıftan türetildiğinde, Tür parametresi PowerShell türetilmiş sınıfı ayrıştırmadan önce tanımlanmalıdır. Genel için tür parametresi aynı dosya veya kod bloğunda tanımlanan bir PowerShell sınıfı veya numaralandırmasıysa, PowerShell bir hata oluşturur.

Tür parametresi olarak özel bir türe sahip genel bir temel sınıftan sınıf türetmek için, tür parametresinin sınıfını veya numaralandırmasını farklı bir dosya veya modülde tanımlayın ve tür tanımını yüklemek için deyimini using module kullanın.

Genel bir temel sınıftan nasıl devralınacaklarını gösteren bir örnek için bkz . Örnek 3.

Devralınacak yararlı sınıflar

PowerShell modülleri yazarken devralmak için yararlı olabilecek birkaç sınıf vardır. Bu bölümde birkaç temel sınıf ve bunlardan türetilen bir sınıfın ne için kullanılabileceğini listeler.

  • System.Attribute - Değişkenler, parametreler, sınıf ve numaralandırma tanımları ve daha fazlası için kullanılabilecek öznitelikleri tanımlamak için sınıfları türetin.
  • System.Management.Automation.ArgumentTransformationAttribute - Bir değişken veya parametrenin girdisini belirli bir veri türüne dönüştürmeyi işlemek için sınıfları türetin.
  • System.Management.Automation.ValidateArgumentsAttribute - Değişkenlere, parametrelere ve sınıf özelliklerine özel doğrulama uygulamak için sınıfları türetin.
  • System.Collections.Generic.List - Belirli bir veri türünün listelerini oluşturmayı ve yönetmeyi kolaylaştırmak için sınıfları türetin.
  • System.Exception - Özel hataları tanımlamak için sınıfları türetin.

Arabirimleri uygulama

Bir arabirim uygulayan bir PowerShell sınıfı, bu arabirimin tüm üyelerini uygulamalıdır. Uygulama arabirimi üyelerinin atlanması betikte ayrıştırma zamanı hatasına neden olur.

Not

PowerShell, PowerShell betiğinde yeni arabirimler bildirmeyi desteklemez. Bunun yerine, arabirimler .NET kodunda bildirilmeli ve cmdlet veya deyimiyle Add-Type oturuma using assembly eklenmelidir.

Bir sınıf bir arabirim uyguladığında, bu arabirimi uygulayan diğer tüm sınıflar gibi kullanılabilir. Bazı komutlar ve işlemler, desteklenen türlerini belirli bir arabirimi uygulayan sınıflara sınırlar.

Arabirimlerin örnek uygulamasını gözden geçirmek için bkz . Örnek 2.

Uygulanacak kullanışlı arabirimler

PowerShell modülleri yazarken devralmak için yararlı olabilecek birkaç arabirim sınıfı vardır. Bu bölümde birkaç temel sınıf ve bunlardan türetilen bir sınıfın ne için kullanılabileceğini listeler.

  • System.IEquatable - Bu arabirim, kullanıcıların sınıfın iki örneğini karşılaştırmasına olanak tanır. Bir sınıf bu arabirimi uygulamadığında PowerShell, başvuru eşitliğini kullanarak iki örnek arasındaki denkliği denetler. Başka bir deyişle, iki örnekteki özellik değerleri aynı olsa bile sınıfın bir örneği yalnızca kendisine eşit olur.
  • System.IComparable - Bu arabirim, kullanıcıların sınıfın örneklerini , , -lt-geve -gt karşılaştırma işleçleriyle -lekarşılaştırmasına olanak tanır. Bir sınıf bu arabirimi uygulamadığında, bu işleçler bir hata oluşturur.
  • System.IFormattable - Bu arabirim, kullanıcıların sınıfın örneklerini farklı dizelere biçimlendirmesini sağlar. Bu, bütçe öğeleri, kaynakçalar ve sıcaklıklar gibi birden fazla standart dize gösterimine sahip sınıflar için kullanışlıdır.
  • System.IConvertible - Bu arabirim, kullanıcıların sınıfın örneklerini diğer çalışma zamanı türlerine dönüştürmesini sağlar. Bu, temel alınan sayısal değere sahip veya bir değere dönüştürülebilen sınıflar için yararlıdır.

Sınırlamalar

  • PowerShell, betik kodunda arabirim tanımlamayı desteklemez.

    Geçici çözüm: C# dilinde arabirimleri tanımlayın ve arabirimleri tanımlayan derlemeye başvurun.

  • PowerShell sınıfları yalnızca bir temel sınıftan devralabilir.

    Geçici çözüm: Sınıf devralma geçişli. Türetilmiş bir sınıf, temel sınıfın özelliklerini ve yöntemlerini almak için başka bir türetilmiş sınıftan devralabilir.

  • Genel bir sınıftan veya arabirimden devralırken, genel için tür parametresinin zaten tanımlanmış olması gerekir. Sınıf kendisini bir sınıf veya arabirim için tür parametresi olarak tanımlayamaz.

    Geçici çözüm: Genel bir temel sınıftan veya arabirimden türetmek için özel türü farklı .psm1 bir dosyada tanımlayın ve türünü yüklemek için deyimini using module kullanın. Bir özel türün genel bir türden devralırken tür parametresi olarak kendisini kullanması için geçici bir çözüm yoktur.

Ayrıca bkz: