PowerShell 4.0で継承を実装する



1つ前の記事、class構文を使わずに、classを定義する方法で、継承を実装する方法を考えてみました。

以下では、Animalクラスを継承したDogクラスを定義し、
  • 親クラスのメソッド
  • オーバーライドしたメソッド
  • 子クラスで定義したメソッド
を呼び出しています。

Animal.psm1
# 親クラス
function getInstance () {
    $instance = New-Object -TypeName psobject
    $instance | Add-Member -MemberType NoteProperty -Name "name" -Value ""
    $instance | Add-Member -MemberType ScriptMethod -Name "getName" -Value {getName}
    $instance | Add-Member -MemberType ScriptMethod -Name "eat" -Value {eat}
    return $instance
}

function getName () {
    return $this.name
}
function eat () {
    Write-Host "eats something"
}

Dog.psm1
# 子クラス
Import-Module Animal -Prefix Animal.
function getInstance () {
    # 継承
    $instance = Animal.getInstance
    # 親クラスで定義された変数に代入
    $instance.name = "dog"
    # オーバーライド
    $instance | Add-Member -Force  -MemberType ScriptMethod -Name "eat" -Value {eat}
    # メソッド追加
    $instance | Add-Member -MemberType ScriptMethod -Name "cry" -Value {cry}
    return $instance
}

function eat () {
    Write-Host "eats meat"
}

function cry () {
    Write-Host "bowwow"
}

main.ps1
# クラスを使うスクリプト
$env:PSModulePath += ":."
Import-Module Dog -Prefix Dog.
$dog = Dog.getInstance
# 親クラスのメソッド呼び出し
Write-Output $dog.getName()
# オーバーライドしたメソッド呼び出し
$dog.eat()
# 追加したメソッド呼び出し
$dog.cry()

下記のディレクトリー構成とします。
.
├── Animal
│   └── Animal.psm1
├── Dog
│   └── Dog.psm1
└── main.ps1

実行すると、

$ pwsh main.ps1
dog
eats meat
bowwow

下記で部分で、Animalクラスのオブジェクトを取得しています。

$instance = Animal.getInstance

このAnimalクラスのオブジェクトを元にして、それに対してメンバーの追加や上書きを行うことで、継承を実現しています。

Add-Memberに-Forceオプションを付けることで、オブジェクトのメンバーを上書きすることができます。
これにより、オーバーライドします。
下記で、eatメソッドをオーバーライドしています。

$instance | Add-Member -Force -MemberType ScriptMethod -Name "eat" -Value {eat}

-Forceを付けないと、下記のエラーが出ます。

Add-Member : Cannot add a member with the name "eat" because a member with that name already exists. To overwrite the member anyway, add the Force parameter to your command.

あとは、Add-Memberで子クラス独自のメンバー変数やメソッドを追加するなりすれば良いです。

コメント

このブログの人気の投稿

PowerShell 6で、Shift_JISのCSVをImport-Csvで読み込んだら文字化けした

Windowsで、特定のユーザーに特定のサービスの再起動を許可する

PowerShellでイベントログを取得する時、「指定した選択条件に一致するイベントが見つかりませんでした。」が煩わしいのでcatchする