{"id":11594,"date":"2016-03-16T06:00:00","date_gmt":"2016-03-16T13:00:00","guid":{"rendered":"https:\/\/www.sapien.com\/blog\/?p=11594"},"modified":"2016-03-16T11:45:31","modified_gmt":"2016-03-16T18:45:31","slug":"inheritance-in-powershell-classes","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2016\/03\/16\/inheritance-in-powershell-classes\/","title":{"rendered":"Inheritance in PowerShell Classes"},"content":{"rendered":"<p>If you&#8217;re learning about classes in Windows PowerShell 5.0, one of the first new concepts that you&#8217;ll encounter is <i>inheritance<\/i>. When you create a class that is based on another class, your new <i>subclass<\/i> or <i>child class <\/i>automatically gets the <a>inheritable<\/a> members (e.g. properties and methods) of the parent class or <i>base class<\/i>.<\/p>\n<p>Inheritance is a really powerful and useful concept, so it&#8217;s important that you understand it. Fortunately, it&#8217;s pretty easy. Also, the inheritance principles that you learn in PowerShell are also used in other programming languages, so learning them in PowerShell gives you a head start on new languages.<\/p>\n<h1>Subclasses of System.Object<\/h1>\n<p>All PowerShell classes are subclasses of the System.Object class. So, they inherit the inheritable methods of the System.Object class.<\/p>\n<p>Create an empty class.<\/p>\n<pre class=\"output\">PS C:\\&gt; class AnyClass {}<\/pre>\n<p>Look at its type. The BaseType property shows the immediate parent class.<\/p>\n<pre class=\"output\">PS C:\\ &gt; [AnyClass]\r\n\r\nIsPublic IsSerial Name     BaseType\r\n-------- -------- ----     --------\r\nTrue     False    AnyClass System.Object<\/pre>\n<p>And, when you create an instance of the AnyClass class and pass it to Get-Member, you can see that there are four methods of the AnyClass class that you didn&#8217;t define. These methods are <i>inherited<\/i> from the System.Object base class.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anything = New-Object -TypeName AnyClass\r\n\r\nPS C:\\&gt; $anything | Get-Member\r\n\r\nTypeName: AnyClass\r\n\r\nName        MemberType    Definition\r\n----        ----------    ----------\r\nEquals      Method        bool Equals(System.Object obj)\r\nGetHashCode Method        int GetHashCode()\r\nGetType     Method        type GetType()\r\nToString    Method        string ToString()<\/pre>\n<p>You can call these methods on the instance of the AnyClass class. They work as though you wrote them in the AnyClass class.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anything.GetType()\r\n\r\nIsPublic IsSerial Name     BaseType\r\n-------- -------- ----     --------\r\nTrue     False    Anyclass System.Object\r\n\r\nPS C:\\&gt; $anything.ToString()\r\nAnyclass<\/pre>\n<p>NOTE: All PowerShell classes are automatically subclasses of System.Object. You do not need to specify System.Object as the base class.<\/p>\n<h1>Create a subclass<\/h1>\n<p>Creating a subclass is easy.<\/p>\n<p>Let&#8217;s create a base class and a subclass. Here&#8217;s the Glass class. The full code is in <a href=\"https:\/\/github.com\/juneb\/ClassOfWine\/blob\/master\/Glass.ps1\">Glass.ps1<\/a> on GitHub. If you&#8217;re testing this code, be sure to dot-source the file so that the class is added to the session.<\/p>\n<pre lang=\"PowerShell\">class Glass\r\n{\r\n    # Properties\r\n    [int]$Size\r\n    [int]$CurrentAmount\r\n\r\n    # Constructors\r\n    Glass ([int]$Size, [int]$Amount)\r\n    {\r\n        $this.Size = $Size\r\n        $this.CurrentAmount = $Amount\r\n    }\r\n\r\n    # Methods\r\n  + [Boolean] Fill ([int]$volume)\r\n    {}\r\n\r\n  + [Boolean] Drink ([int]$amount)\r\n    {}\r\n}<\/pre>\n<p>The syntax for a subclass is:<\/p>\n<pre lang=\"PowerShell\">class subclass : base class { ... }<\/pre>\n<p>PowerShell classes can inherit from only one base class, so you can&#8217;t specify more than one class name. (The class can implement multiple interfaces, but we&#8217;ll save that for another blog post.)<\/p>\n<p>To start with the simplest case, let&#8217;s create an empty subclass based on the Glass class. We&#8217;ll call it AnyGlass.<\/p>\n<pre class=\"output\">PS C:\\&gt; class AnyGlass : Glass {}<\/pre>\n<p>First, make sure that the class was created and that the base type is Glass.<\/p>\n<pre class=\"output\">PS C:\\&gt; [AnyGlass]\r\n\r\nIsPublic IsSerial Name     BaseType\r\n-------- -------- ----     --------\r\nTrue     False    AnyGlass Glass<\/pre>\n<p>Now, let&#8217;s create an AnyGlass object. There are several different ways to <a href=\"https:\/\/www.sapien.com\/blog\/2015\/10\/26\/creating-objects-in-windows-powershell\/\" target=\"_blank\">create an object<\/a> (&#8220;instantiate&#8221;) based on a class, but we&#8217;ll use New-Object here, because it&#8217;s so PowerShell.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anyGlass = New-Object -TypeName AnyGlass\r\n\r\nPS C:\\&gt; $anyGlass | Get-Member\r\n\r\nTypeName: AnyGlass\r\n\r\nName          MemberType     Definition\r\n----          ----------     ----------\r\nDrink         Method         bool Drink(int amount)\r\nEquals        Method         bool Equals(System.Object obj)\r\nFill          Method         bool Fill(int volume)\r\nGetHashCode   Method         int GetHashCode()\r\nGetType       Method         type GetType()\r\nToString      Method         string ToString()\r\nCurrentAmount Property       int CurrentAmount {get;set;}\r\nSize          Property       int Size {get;set;}<\/pre>\n<p>Notice that the AnyGlass object has the properties defined in the Glass class (Size, CurrentAmount), the methods defined in the Glass class (Drink, Fill), and the methods that the Glass class inherited from its base class, System.Object (Equals, GetHashCode, GetType, ToString).<\/p>\n<p>So, the AnyGlass class inherits from its parent and grandparent classes &#8212; its entire ancestry &#8212; just like people do.<\/p>\n<h1>Add Members to a Subclass<\/h1>\n<p>A subclass can have properties and methods (and all types of members) that are not in the base class. For example, the Glass class has properties that are not in System.Object.<\/p>\n<p>I&#8217;ll add a Name property to the AnyGlass class.<\/p>\n<pre class=\"output\">PS C:\\&gt; class AnyGlass : Glass\r\n{\r\n    [String]$Name\r\n}\r\n\r\nPS C:\\&gt; $anyGlass = New-Object AnyGlass\r\nPS C:\\&gt; $anyGlass\r\n\r\nName Size CurrentAmount\r\n---- ---- -------------\r\n     0    0<\/pre>\n<p>You use inherited members in exactly the same way as you use members that are defined in the current class. In fact, unless you do some quick discovery, you really don&#8217;t know if a property or method is inherited or defined.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anyGlass.Name = 'AnyGlass'\r\nPS C:\\&gt; $anyGlass.Size = 6\r\nPS C:\\&gt; $anyGlass\r\n\r\nName      Size   CurrentAmount\r\n----      ----   -------------\r\nAnyGlass  6      0<\/pre>\n<p>Also, inside the class, when you use $this to refer to the current object, you treat defined properties and inherited properties in the same way.<\/p>\n<pre lang=\"PowerShell\">class AnyGlass : Glass\r\n{\r\n    [String]$Name\r\n     \r\n    AnyGlass () {\r\n        $this.Size = 6\r\n        $this.CurrentAmount = 0\r\n        $this.Name = \"My glass\"\r\n    }\r\n}<\/pre>\n<h1>Overloading Methods in the Base Class<\/h1>\n<p>You can have members that have the same name as a member in the base class, but take <b><i>different parameters<\/i><\/b>. This is called an <i>overloaded method<\/i>. In a subclass, it works the same way that it would if you had a method defined twice in the same class.<\/p>\n<p>For example, the <b>Fill<\/b> method in the Glass class takes one integer argument that represents the volume added to the Glass.<\/p>\n<pre lang=\"PowerShell\">  + [Boolean] Fill ([int]$volume)<\/pre>\n<p>The Fill method in the AnyGlass takes the same volume integer argument and a string argument that represents a warning that it returns when you&#8217;ve overfilled the glass. (The Fill method in the base class has a predetermined warning.)<\/p>\n<pre lang=\"PowerShell\">class AnyGlass : Glass {\r\n\r\n\t# Methods\r\n\t[void] Fill ([int]$volume, [string]$Warning)\r\n\t{\r\n\t\tif ($this.currentAmount + $volume -le $this.Size)\r\n\t\t{\r\n\t\t\t$this.CurrentAmount += $volume\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tWrite-Warning $Warning\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>When I pipe $AnyGlass to Get-Member and specify the Fill method, it tells me it has two overloads. It doesn&#8217;t mention (and doesn&#8217;t really care) which one is defined locally and which one is inherited.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anyGlass | Get-Member -MemberType Method -Name Fill\r\n\r\nTypeName: AnyGlass\r\n\r\nName     MemberType     Definition\r\n----     ----------     ----------\r\nFill     Method         void Fill(int volume, string Warning), bool Fill(int volume)<\/pre>\n<p>When I call the Fill methods, they works exactly as they would if both Fill methods were defined in the same class. That is, the argument number and types determine which Fill method is called. I don&#8217;t need to do anything to call the Fill method of the Glass class, other than to provide only an integer.<\/p>\n<p>As a reminder, here&#8217;s the signature of each of the Fill methods:<\/p>\n<pre lang=\"PowerShell\"># In Glass\r\n+ [Boolean] Fill ([int]$volume)\r\n\r\n# In AnyGlass\r\n+ [void] Fill ([int]$volume, [string]$Warning)\r\n<\/pre>\n<p>If I call the Fill method with 2 arguments, an integer and a string, it calls the Fill method of the AnyGlass class, which when full, returns the warning string I specify.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anyGlass.Fill(3, \"Oops! Too much\")\r\nWARNING: Oops! Too much<\/pre>\n<p>If I call the Fill method with 1 argument, an integer, it calls the Fill method of the Glass class, which has a predefined warning message that includes the room left in the glass. It also returns a Boolean value, $False, which indicates that the AnyGlass was not filled. Notice that I didn&#8217;t need to specify anything to get the inherited Glass method, because the AnyGlass class has both methods.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anyGlass.Fill(3)\r\nWARNING: Sorry. The glass isn't big enough. You have room for 2.\r\nFalse<\/pre>\n<h1>Overriding Methods of the Base Class<\/h1>\n<p>To hide a method in the base class, write a method that has the same arguments as the method in the parent class. That&#8217;s called <i>overriding<\/i> a method. When methods have the same name and take arguments of the same type, the method in the subclass takes precedence, hides, or <i>overrides<\/i> the method in the parent class.<\/p>\n<p>You can do the same thing with Properties.<\/p>\n<p>Here&#8217;s the AnyGlass class with a Fill method that takes just one argument, an integer, just like the Fill method in the Glass class.<\/p>\n<pre lang=\"PowerShell\">class AnyGlass : Glass {\r\n    # Methods\r\n    [void] Fill ([int]$volume)\r\n    {\r\n        if ($this.currentAmount + $volume -le $this.Size)\r\n        {\r\n            $this.CurrentAmount += $volume\r\n        }\r\n        else\r\n        {\r\n            Write-Warning \"Oops! Not enough room\"\r\n        }\r\n    }\r\n}<\/pre>\n<p>Notice that the signatures of the Fill methods are not identical. The Fill method of the Glass class returns a Boolean. The Fill method of the AnyGlass class returns nothing ([void]).<\/p>\n<pre lang=\"PowerShell\"># In Glass\r\n+ [Boolean] Fill ([int]$volume)\r\n\r\n# In AnyGlass\r\n+ [void] Fill ([int]$volume)<\/pre>\n<p>But, when I create an AnyGlass object and pipe it to Get-Method, it returns only one Fill method signature, instead of two. And, because the return type is Void, we know that it&#8217;s returning the Fill method of the AnyGlass class, which overrides the Fill method of the Glass class.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anyGlass | Get-Member -MemberType Method -Name Fill\r\n\r\nTypeName: AnyGlass\r\n\r\nName     MemberType    Definition\r\n----     ----------    ----------\r\nFill     Method        void Fill(int volume)<\/pre>\n<p>When I call the Fill method with a volume, it calls the local Fill method.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anyGlass.Fill(1)\r\nPS C:\\&gt; $anyGlass.Fill(1)\r\nPS C:\\&gt; $anyGlass.Fill(1)\r\nWARNING: Oops! Not enough room.\r\nPS C:\\&gt;<\/pre>\n<p>When a subclass overrides a base class, does it completely hide the parent class? Happily, no!<\/p>\n<h1>Calling a member of a base class<\/h1>\n<p>Even when a base class member is hidden by a subclass member, you can still call the base class member on an instance of the subclass.<\/p>\n<p>Here&#8217;s the syntax:<\/p>\n<pre lang=\"PowerShell\">([baseClass]$instance).member<\/pre>\n<p>Essentially, you cast the object to the base class, enclose the casted object in parentheses to make sure it&#8217;s evaluated first, and then call the member in the usual way. For example, to call the Fill method of the <b>Glass<\/b> class on an AnyGlass object:<\/p>\n<pre class=\"output\">PS C:\\&gt; ([Glass]$anyGlass).Fill(4)\r\nWARNING: Sorry. The glass isn't big enough. You have room for 2.\r\nFalse<\/pre>\n<p>In the script for a class, you can use the same syntax to modify the $this variable that refers to the current object.<\/p>\n<p>For example, in my <a href=\"https:\/\/github.com\/juneb\/ClassOfWine\/blob\/master\/WineGlass.ps1\">WineGlass class<\/a>, the Fill method of the WineGlass class calls the Fill method of the Glass class, which updates the CurrentAmount property. Then, the Fill method of the WineGlass class updates a local property, TotalPoured.<\/p>\n<pre lang=\"PowerShell\">[void] Fill ([int]$volume)\r\n{\r\n    if (([Glass]$this).Fill($volume))\r\n    {\r\n        $this.TotalPoured += $volume\r\n    }\r\n}<\/pre>\n<p>You can also call all the way back to our common ancestor, System.Object. For example, if I add a ToString method to the AnyGlass or Glass class, I can call it. Or, I can call the ToString method on System.Object.<\/p>\n<pre class=\"output\">PS C:\\&gt; $anyGlass = [AnyGlass]::New()\r\nPS C:\\&gt; $anyGlass.Size = 6\r\nPS C:\\&gt; $anyGlass.CurrentAmount = 4\r\n\r\nPS C:\\&gt; $anyGlass.ToString()\r\nA 6-ounce glass with 4 ounces.\r\n\r\nPS C:\\&gt; ([System.Object]$anyGlass).ToString()\r\nAnyGlass<\/pre>\n<h1>Constructors are not inherited<\/h1>\n<p>When I talked about inheritance, I was careful not to say that &#8220;all&#8221; members, or all properties and methods, are inherited. <a href=\"https:\/\/www.sapien.com\/blog\/2015\/10\/21\/why-do-we-need-constructors\/\">Constructors<\/a>, which are really just special methods, are not inherited. Instead, like all PowerShell classes, the new class is created with a default (parameter-less) constructor.<\/p>\n<p>(Need help with constructors? See: <a href=\"https:\/\/www.sapien.com\/blog\/2015\/10\/21\/why-do-we-need-constructors\/\">Why do we need constructors?<\/a>)<\/p>\n<p>To find the constructors of a class, use the <b>New<\/b> static property that PowerShell adds to all classes. (Be sure to use the property, with no parentheses, not the method, with parentheses, which creates a new object).<\/p>\n<p>This command shows that the Glass class has two constructors; a default constructor and a constructor that takes two integers; the first for the size and the second for the amount.<\/p>\n<pre class=\"output\">PS C:\\&gt; [Glass]::New\r\n\r\nOverloadDefinitions\r\n-------------------\r\nGlass new()\r\nGlass new(int Size, int Amount)<\/pre>\n<p>But the AnyGlass class just has the default constructor that is added automatically to all PowerShell classes.<\/p>\n<pre class=\"output\">PS C:\\&gt; [AnyGlass]::New\r\n\r\nOverloadDefinitions\r\n-------------------\r\nAnyGlass new()<\/pre>\n<p>You can add constructors to the subclass as you would to any class. Remember, that when you add a constructor to the class, it <b>replaces<\/b> the automatic default constructor. So, if you want a default constructor on your class, you need to add it explicitly.<\/p>\n<h1>Calling a base class constructor<\/h1>\n<p>The last piece of the inheritance puzzle is calling the constructor of the base class.<\/p>\n<p>(Need help with constructors? See: <a href=\"https:\/\/www.sapien.com\/blog\/2015\/10\/21\/why-do-we-need-constructors\/\" target=\"_blank\">Why do we need constructors?)<\/a><\/p>\n<p>Here&#8217;s the scenario. The base class defines a constructor that takes property values as arguments and assigns each value to the correct property. The Glass class is intentionally simple, but it can get complex when the class defines many properties, or the arguments are used to calculate property values.<\/p>\n<pre lang=\"PowerShell\">Glass ([int]$Size, [int]$Amount)\r\n{\r\n    $this.Size = $Size\r\n    $this.CurrentAmount = $Amount\r\n}<\/pre>\n<p>In the subclass, you could easily define a corresponding constructor, such as:<\/p>\n<pre lang=\"PowerShell\">AnyGlass ([int]$Size, [int]$Amount)\r\n{\r\n    $this.Size = $Size\r\n    $this.CurrentAmount = $Amount\r\n}<\/pre>\n<p>But, you&#8217;re maintaining virtually the same code twice. Instead, you can call the base class constructor from the subclass.<\/p>\n<p>The syntax, which uses the <b>base<\/b> keyword, is:<\/p>\n<pre lang=\"PowerShell\"> Subclass (arguments) : base (argumentsToBaseClassConstructor) { ... }<\/pre>\n<p>For example, this AnyGlass constructor calls the Glass class constructor. In this case, there&#8217;s no logic in the constructor (inside the script block), but it&#8217;s permitted if you need it.<\/p>\n<pre lang=\"PowerShell\">AnyGlass ([int]$Size, [int]$Amount) : base($Size, $Amount) { }<\/pre>\n<p>The arguments and their types can be different, just so the call to the base class constructor provides the arguments it requires. For example, this AnyGlass constructor creates a full AnyGlass (Size -eq CurrentAmount) every time.<\/p>\n<pre lang=\"PowerShell\">AnyGlass ([int]$Amount) : base($Amount, $Amount) { }<\/pre>\n<p>However, when creating an instance of a subclass, you cannot call the constructor of a base class. <a href=\"https:\/\/twitter.com\/xvorsx\/status\/708416538320117760\">It&#8217;s explicitly prohibited<\/a>, because it&#8217;s error prone.<\/p>\n<h1>You can&#8217;t inherit from that (it&#8217;s sealed)<\/h1>\n<p>Now, a few limits to all of this power.<\/p>\n<p>You can&#8217;t create a subclass based on any class; only classes that are not <i>sealed<\/i>. The <i><a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms173150.aspx\">sealed<\/a><\/i> keyword in C# creates a class that you cannot use as a base class.<\/p>\n<p style=\"padding-left: 30px;\"><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.11.32.png\" rel=\"attachment wp-att-11607\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11607\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.11.32.png\" alt=\"Screenshot 2016-03-10 12.11.32\" width=\"858\" height=\"125\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.11.32.png 858w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.11.32-300x44.png 300w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.11.32-768x112.png 768w\" sizes=\"auto, (max-width: 858px) 100vw, 858px\" \/><\/a><\/p>\n<p>Programmers use <i>sealed<\/i> when they want to protect the interface from development that they cannot control. They don&#8217;t want to be responsible for someone&#8217;s bad implementation or any side effects it might have. They&#8217;d rather weather a bit of anger from a stymied programmer than a pile of bugs in code they don&#8217;t own. (Many thanks to Doug Finke, Kevin Ilsen, Adam Driscoll, Lee Holmes, Rodney Stewart, Eric Slesar, and David J. Brown for their insights on this topic.)<\/p>\n<p style=\"padding-left: 30px;\"><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/clip_image004.jpg\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border: 0px;\" title=\"clip_image004\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/clip_image004_thumb.jpg\" alt=\"clip_image004\" width=\"723\" height=\"226\" border=\"0\" \/><\/a><\/p>\n<p>As an aside, the opposite of <i>sealed<\/i>, well sort of, is <i>abstract<\/i>, which indicates that a class is designed <b>only<\/b> to be a base class for other subclasses. You can&#8217;t create an instance of an abstract class (e.g. New-Object or [&lt;Class&gt;}::New() ), but you can create subclasses.<\/p>\n<p>Most .NET classes are sealed, but the PowerShell classes that you create are not sealed (and the sealed keyword is not valid), so you can use any PowerShell class as a base class. And, you can use .NET classes that are not sealed, such as <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms132438(v=vs.110).aspx\">KeyedCollection<\/a>, which is an abstract base class.<\/p>\n<h1>You can&#8217;t inherit from that either (no default constructor)<\/h1>\n<p>In Windows PowerShell 5.0.10586.122 classes, you cannot inherit from a class that does not have a default <a href=\"https:\/\/www.sapien.com\/blog\/2015\/10\/21\/why-do-we-need-constructors\/\">constructor<\/a> (a constructor with no parameters), unless you explicitly define a default constructor in the subclass.<\/p>\n<p style=\"padding-left: 30px;\"><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/clip_image006.jpg\">\u00a0<\/a><a href=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.01.47.png\" rel=\"attachment wp-att-11614\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-11614\" src=\"https:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.01.47.png\" alt=\"Screenshot 2016-03-10 12.01.47\" width=\"800\" height=\"181\" srcset=\"https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.01.47.png 800w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.01.47-300x68.png 300w, https:\/\/dev.sapien.com\/blog\/wp-content\/uploads\/2016\/03\/Screenshot-2016-03-10-12.01.47-768x174.png 768w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>According to Jason Shirk on the PowerShell Team, <a href=\"https:\/\/twitter.com\/juneb_get_help\/status\/708016924660076544\">it&#8217;s a bug, but it&#8217;s not yet fixed<\/a>.<\/p>\n<p>When it&#8217;s fixed, you&#8217;ll be able to base a class on a class that has no default constructor, but the derived class constructor must call a constructor in the base class, just like in C#.<\/p>\n<p>That just about wraps it up. Thanks to Jason Shirk, Sergei Vorobev, and many others on Twitter and the PowerShell Facebook group for their help with this post.<\/p>\n<p><i>June Blender is a technology evangelist at SAPIEN Technologies, Inc. You can reach her at <a href=\"mailto:juneb@sapien.com\">juneb@sapien.com<\/a> or follow her on Twitter at <a href=\"https:\/\/twitter.com\/juneb_get_help\">@juneb_get_help<\/a>.<\/i><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;re learning about classes in Windows PowerShell 5.0, one of the first new concepts that you&#8217;ll encounter is inheritance. When you create a class that is based on another class, your new subclass or child class automatically gets the inheritable members (e.g. properties and methods) of the parent class or base class. Inheritance is [&hellip;]<\/p>\n","protected":false},"author":31,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[1033,941,1090,25],"tags":[934,28,961,1084,997,1085,1086],"class_list":["post-11594","post","type-post","status-publish","format-standard","hentry","category-classes-in-powershell-5-0","category-powershell-5-0","category-powershell-5-0-10586-122","category-windows-powershell","tag-juneb","tag-powershell","tag-powershell-5-0","tag-powershell-classes","tag-windows-powershell","tag-windows-powershell-5-0","tag-windows-powershell-classes"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/11594","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=11594"}],"version-history":[{"count":41,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/11594\/revisions"}],"predecessor-version":[{"id":11663,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/11594\/revisions\/11663"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=11594"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=11594"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=11594"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}