その1 で説明したように、class の良さは class に処理(メソッド)とデータ(プロパティ)をひとまとめに任せることが出来る点にあるのですが、実はもう一つ大きな特徴があります。
それが「継承」です。
継承とは、既にある class に手を加えることなく機能の追加/変更ができる仕組みです。
function の機能拡張をする場合は、既にある function を書き換えますね。
あるいは、元の function を呼んで追加処理を書き足すといった修正をしますが、その場合は function 名が変わってしまいます。
class の場合は、既にある class に一切手を加える事なく、既にあるメソッドの機能追加や変更、あるいは新しくメソッドを追加することが出来るのです。
(文中で、「内部データ/データ」と「プロパティ」の2つの言葉が出てきますが、文脈によって使い分けているだけで同じ意味です)
元となるクラス(ベースクラス)の機能(メソッド)を呼び出す場合は、継承元のクラス名で this をキャストして呼び出します。
[D:\temp\testadd.ps1]
|
これを実行するとこのようになります。
PS D:\> D:\temp\testadd.ps1
Hello PowerShell Class !!This is hoge2 !!
PS D:\>
|
元となるクラス(ベースクラス)の機能(メソッド)を、継承するクラス(サブクラス)の同名メソッドで書き換えることを「オーバーライド」と言います。
まずは、機能変更がどうなるのか見てみましょう
[D:\temp\test30.ps1]
|
これを実行するとこのようになります。
PS D:\> D:\temp\test30.ps1
This is new hoge !!
PS D:\>
|
hoge メソッドが TestClass31 の hoge メソッドに置き換わっていますね。
では、継承元のメソッドを利用して機能拡張するケースを見てみましょう。
[D:\temp\test31.ps1]
|
PS D:\> D:\temp\test31.ps1
Hello PowerShell Class !! And new hoge !!
PS D:\>
|
オーバーライドした hoge メソッド内で ([TestClass30]$this).hoge() を使ってベースクラスの hoge を呼び出し、ベースクラスの hoge メソッドの機能拡張できたのがわかりますね。
継承元のメソッドを呼び出す場合は、([BaseClassName]$this) のように $this をベースクラスにキャストしてメソッドを呼び出します。
機能追加する場合も想像通りでこんな感じになります。
[D:\temp\test32.ps1]
|
PS D:\> D:\temp\test32.ps1
Hello PowerShell Class !! This is new hoge too !!
PS D:\>
|
このように、元となるベースクラスには一切手を入れず、継承したサブクラスで機能拡張することが出来ます。
コンストラクタをオーバーライドする場合は、通常のメソッドを呼ぶのとは異なり「base」でベースクラスのコンストラクタを指定します。
サブクラスで呼ばれるコンストラクタは、インスタンス時の引数に依存し、それに続いて : base() で指定されているベースクラスのコンストラクタが呼ばれます。
コンストラクタが呼び出される順番は、先にベースクラスのコンストラクタが呼ばれ、その後にサブクラスのコンストラクタが呼ばれます。
ぜひ PowerShell ISE でステップ実行して動きを確認してください。(コンストラクタ内で echo とかしても表示されない)
この時のミソは、
・ベースクラスに対応する全てのコンストラクタ作成
・サブクラスでは : base(引数)
でベースクラスのコンストラクタを指定
・サブクラスのコンストラクタに渡された引数がそままま : base(引数)
に渡され、ベースクラスのコンストラクタが先に実行される
・ベースクラスの内部データは 「([BaseClassName]$this).Property」
でアクセス
する点です。
こうすることで、結果的にサブクラスで内部データへの初期値セットが実現できます。
(コンストラクタは直接呼び出せないので、サブクラスのコンストラクタ内で ([TestClass30]$this)
みたいにしてコンストラクタを呼び出してもエラーになります)
それでは実際の動きを見てみましょう。
[D:\temp\test33.ps1]
|
PS D:\> D:\temp\test33.ps1
60
PS D:\>
|
ベースクラスの引数ありコンストラクタは呼ばれず、サブクラスのコントラクタでベースクラスのデータを
([TestClass34]$this).Data で更新しているのがわかると思います。
(ぜひ PowerShell ISE のステップ実行で動きを確認してください)
class を多段で継承している場合、直接継承している class で実装されていないメソッドを使用する時にはどうしたら良いのでしょうか?
メソッドを実装しているクラスを指定してメソッドを呼び出しても良いのですが、直接継承している class のメソッドとして呼び出す事が出来ます。
|
オーバーライドも同様に実装することが出来ます。
ただし、コンストラクタだけは継承したクラス全てで継承元のコンストラクタをオーバーライド( : base() を呼び出すだけであっても )実装しないと、実行時にエラーになるようです。(コンストラクタ引数の数を変更した場合だけかも?)
PowerShell の class は、.NET Framework から継承した class を定義することが出来ます。
「えー、そんなの滅多に使わないよ」と思う方もいらっしゃるかと思いますが、実は普通に作成した class も.NET Framework から継承されています。
その1で最初に作った class で確認してみます。
|
PS D:\> # クラス定義 PS D:\> class TestClass{ >> [string] hoge(){ >> return "Hello PowerShell Class !!" >> } >> } PS D:\> PS D:\> # インスタンス化 PS D:\> $TestObject = New-Object TestClass PS D:\> PS D:\> # メンバー PS D:\> $TestObject | Get-Member TypeName: TestClass Name MemberType Definition ---- ---------- ---------- Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() hoge Method string hoge() ToString Method string ToString() PS D:\> PS D:\> # タイプ PS D:\> $TestObject.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True False TestClass System.Object PS D:\> |
Get-Member を見ると、作成した hoge メソッド以外にもメソッドが存在していますし、GetType() を見ると BaseType が System.Object になっています。
つまり、作成した TestClass は、.NET Framework の System.Object クラスを継承した class なので、こう書いているのと同じ意味だったのです。
|
こんな感じで PowerShell の class は .NET Framework のクラスを継承して、強力なクラスを簡単に作ることが出来るのです。
ここは腕の見せ所ですね
超簡単な PowerShell Class の使い方(その1)
http://www.vwnet.jp/Windows/PowerShell/2017082001/PSv5Class01.htm
超簡単な PowerShell Class の使い方(その2/オーバーロード)
http://www.vwnet.jp/Windows/PowerShell/2017082101/PSv5Class02.htm
超簡単な PowerShell Class の使い方(その3/static)
http://www.vwnet.jp/Windows/PowerShell/2017082201/PSv5Class03.htm
超簡単な PowerShell Class の使い方(その5/スコープ)
http://www.vwnet.jp/Windows/PowerShell/2017082302/PSv5Class05.htm
超簡単な PowerShell Class の使い方(その6/まとめ)
http://www.vwnet.jp/Windows/PowerShell/2017082401/PSv5Class06.htm
PowerShell Class
http://www.vwnet.jp/Windows/etc.asp#PowerShell_Class
PowerShell クラスを使用したカスタム型の作成Creating Custom Types using
PowerShell Classes | Microsoft Docs
https://docs.microsoft.com/ja-jp/powershell/scripting/windows-powershell/wmf/whats-new/class-overview?WT.mc_id=WD-MVP-36880
Copyright © MURA All rights reserved.