3

I've tried to work out a solution this afternoon, but I've only had partial success so far...

Here is my code:

class Animal {
    [int] $numOfLegs = 0;
    [int] $numOfEyes = 2;

    [scriptblock] $dog = { 
        class Dog { 
            [int] $numOfLegs = 4
            [int] getLegs(){ return $this.numOfLegs; }
            [int] getEyes(){ return $numOfEyes; }
        }

        return [dog]::new()       
     }
}

(The Dog class can be instantiated by doing this):

$mypetdog = & ([animal]::new().Dog)

Basically, my idea was to try to get scriptblocks to act as closures, so that each 'subclass' definition contained within Animal could be invoked (and still have access to it's parent scope). So for example, when getEyes() is executed on the Dog object, it would in theory return the number 2. However this didn't work because I think that the scriptblock cannot see outside its own scope (when defined within a class).

So when I do this:

$mypetdog.getLegs()

it correctly returns 4, but when I do this:

$mypetdog.getEyes()

Powershell has no idea what the variable $numOfEyes is and subsequently throws an error because the variable is undefined within the class.

Does anyone have a solution to imitating subclasses in PowerShell without using add-type?

1
  • Your question is about an inherited class not a subclass; a subclass would be a class inside another class such as class tree{class node{}}, where a node is not a specialized type of tree, but this specific type of node by itself has no meaning other than within the context of the parent tree class. Commented May 8, 2020 at 22:44

2 Answers 2

4

Classes in PowerShell 5.0 was created to simplify development of DSC resources which do not require inheritance, so this is not yet supported. As you can see below, they will work on it, but there is no ETA, which means that you might have to wait until v6+.

The focus for the September preview was to enable writing a DSC resource via PowerShell classes. This does not require inheritance, so you are correct, inheritance is not supported in the September preview.

Classes are still useful for many things without inheritance – for example C is alive and well and it still doesn’t have member functions, let alone inheritance.

That said, we obviously understand the importance of inheritance. No promises as to when it will be available, but it is something we are working on.

Source: WMF blog - Comments

You could try to get something working using New-Object, $obj.psobject.copy() and Add-Member(to define the properties and functions of the subclass), like someone has described here

UPDATE: Class inheritance is available in PowerShell 5.0 RTM. Example:

class Vehicle {
    [string]$Make
    [string]$Model
    [string]$Color

}    

class Car : Vehicle {
    [string]$VIN
}

$car = [car]@{
    Make = "Ford"
    Model = "Mustang"
    Color = "Red"
    VIN = "123456"
}
$car


VIN    Make Model   Color
---    ---- -----   -----
123456 Ford Mustang Red  
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @Frode F. - yep, i had a bit of a gut feeling that this may have been something Microsoft were considering, but i hadn't seen this comment... Hopefully in v6 there is something similar to the 'extends' or 'implements' keywords so that it's possible to program to interfaces, and ensure type safety when we need/want to...
RobertW has alread added this, but I've updated my answer with RTM results (thanks to the one who upvoted this so I could update my answer) :-)
1

Inheritance is given by ":" operator in very simple way.

class Animal {
[int] $numOfLegs = 0;
[int] $numOfEyes = 2;

  Animal(){} <- Constructor         
 }


class Dog : Animal { 
        [int] $numOfLegs = 4
  Dog(){} <- Constructor of dogs
        [int] getLegs(){ return $this.numOfLegs; }
        [int] getEyes(){ return $numOfEyes; }
    }

 New-Object Dog

1 Comment

[int] getEyes(){ return $numOfEyes; } must be [int] getEyes(){ return $this.numOfEyes; }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.