[玩转系统] 关于类构造函数
作者:精品下载站 日期:2024-12-14 02:24:14 浏览:11 分类:玩电脑
关于类构造函数
简短描述
描述如何定义 PowerShell 类的构造函数。
详细描述
构造函数使您能够在创建类实例时设置默认值并验证对象逻辑。构造函数与类具有相同的名称。构造函数可能有参数,用于初始化新对象的数据成员。
PowerShell 类构造函数被定义为类上的特殊方法。它们的行为与 PowerShell 类方法相同,但有以下例外:
- 构造函数没有输出类型。他们不能使用
return
关键字。 - 构造函数始终与类具有相同的名称。
- 构造函数不能直接调用。它们仅在创建实例时运行。
- 构造函数永远不会出现在
Get-Member
cmdlet 的输出中。
有关 PowerShell 类方法的详细信息,请参阅 about_Classes_Methods。
该类可以定义零个或多个构造函数。如果未定义构造函数,则为该类提供默认的无参数构造函数。此构造函数将所有成员初始化为其默认值。对象类型和字符串被赋予空值。定义构造函数时,不会创建默认的无参数构造函数。如果需要,创建一个无参数构造函数。
您还可以定义无参数静态构造函数。
句法
类构造函数使用以下语法:
默认构造函数语法
<class-name> () [: base([<params>])] {
<body>
}
静态构造函数语法
static <class-name> () [: base([<params>])] {
<body>
}
参数化构造函数语法(一行)
<class-name> ([[<parameter-type>]$<parameter-name>[, [<parameter-type>]$<parameter-name>...]]) [: base([<params>])] {
<body>
}
参数化构造函数语法(多行)
<class-name> (
[<parameter-type>]$<parameter-name>[,
[<parameter-type>]$<parameter-name>...]
) [: base([<params>])] {
<body>
}
示例
示例 1 - 使用默认构造函数定义类
ExampleBook1 类没有定义构造函数。相反,它使用自动默认构造函数。
class ExampleBook1 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
}
[ExampleBook1]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
0 1/1/0001 12:00:00 AM
笔记
Name 和 Author 属性的默认值为 $null
,因为它们被键入为字符串,这是一种引用类型。其他属性具有其定义类型的默认值,因为它们是值类型属性。有关属性默认值的详细信息,请参阅 about_Classes_Properties 中的“默认属性值”。
示例 2 - 覆盖默认构造函数
ExampleBook2 显式定义默认构造函数,将 PublishedOn 的值设置为当前日期,将 Pages 的值设置为 1
。
class ExampleBook2 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
ExampleBook2() {
$this.PublishedOn = (Get-Date).Date
$this.Pages = 1
}
}
[ExampleBook2]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
1 11/1/2023 12:00:00 AM
示例 3 - 定义构造函数重载
ExampleBook3 类定义了三个构造函数重载,使用户能够通过传递每个属性值以及传递书籍名称和作者的名称,从哈希表创建该类的实例。该类没有定义默认构造函数。
class ExampleBook3 {
[string] $Name
[string] $Author
[int] $Pages
[datetime] $PublishedOn
ExampleBook3([hashtable]$Info) {
switch ($Info.Keys) {
'Name' { $this.Name = $Info.Name }
'Author' { $this.Author = $Info.Author }
'Pages' { $this.Pages = $Info.Pages }
'PublishedOn' { $this.PublishedOn = $Info.PublishedOn }
}
}
ExampleBook3(
[string] $Name,
[string] $Author,
[int] $Pages,
[datetime] $PublishedOn
) {
$this.Name = $Name
$this.Author = $Author
$this.Pages = $Pages
$this.PublishedOn = $PublishedOn
}
ExampleBook3([string]$Name, [string]$Author) {
$this.Name = $Name
$this.Author = $Author
}
}
[ExampleBook3]::new(@{
Name = 'The Hobbit'
Author = 'J.R.R. Tolkien'
Pages = 310
PublishedOn = '1937-09-21'
})
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien', 310, '1937-09-21')
[ExampleBook3]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook3]::new()
Name Author Pages PublishedOn
---- ------ ----- -----------
The Hobbit J.R.R. Tolkien 310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien 310 9/21/1937 12:00:00 AM
The Hobbit J.R.R. Tolkien 0 1/1/0001 12:00:00 AM
MethodException:
Line |
42 | [ExampleBook3]::new()
| ~~~~~~~~~~~~~~~~~~~~~
| Cannot find an overload for "new" and the argument count: "0".
调用默认构造函数会返回方法异常。仅当类未定义任何构造函数时,才会为该类定义自动默认构造函数。由于 ExampleBook3 定义了多个重载,因此默认构造函数不会自动添加到该类中。
示例 4 - 使用共享方法链接构造函数
此示例展示了如何为构造函数编写可重用的共享代码。 PowerShell 类无法使用构造函数链,因此此示例类定义了一个 Init()
方法。该方法有多个重载。具有较少参数的重载调用具有未指定参数的默认值的更显式重载。
class ExampleBook4 {
[string] $Name
[string] $Author
[datetime] $PublishedOn
[int] $Pages
ExampleBook4() {
$this.Init()
}
ExampleBook4([string]$Name) {
$this.Init($Name)
}
ExampleBook4([string]$Name, [string]$Author) {
$this.Init($Name, $Author)
}
ExampleBook4([string]$Name, [string]$Author, [datetime]$PublishedOn) {
$this.Init($Name, $Author, $PublishedOn)
}
ExampleBook4(
[string]$Name,
[string]$Author,
[datetime]$PublishedOn,
[int]$Pages
) {
$this.Init($Name, $Author, $PublishedOn, $Pages)
}
hidden Init() {
$this.Init('Unknown')
}
hidden Init([string]$Name) {
$this.Init($Name, 'Unknown')
}
hidden Init([string]$Name, [string]$Author) {
$this.Init($Name, $Author, (Get-Date).Date)
}
hidden Init([string]$Name, [string]$Author, [datetime]$PublishedOn) {
$this.Init($Name, $Author, $PublishedOn, 1)
}
hidden Init(
[string]$Name,
[string]$Author,
[datetime]$PublishedOn,
[int]$Pages
) {
$this.Name = $Name
$this.Author = $Author
$this.PublishedOn = $PublishedOn
$this.Pages = $Pages
}
}
[ExampleBook4]::new()
[ExampleBook4]::new('The Hobbit')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien')
[ExampleBook4]::new('The Hobbit', 'J.R.R. Tolkien', (Get-Date '1937-9-21'))
[ExampleBook4]::new(
'The Hobbit',
'J.R.R. Tolkien',
(Get-Date '1937-9-21'),
310
)
Name Author PublishedOn Pages
---- ------ ----------- -----
Unknown Unknown 11/1/2023 12:00:00 AM 1
The Hobbit Unknown 11/1/2023 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 11/1/2023 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM 1
The Hobbit J.R.R. Tolkien 9/21/1937 12:00:00 AM 310
示例 5 - 派生类构造函数
以下示例使用为基类和从基类继承的派生类定义静态、默认和参数化构造函数的类。
class BaseExample {
static [void] DefaultMessage([type]$Type) {
Write-Verbose "[$($Type.Name)] default constructor"
}
static [void] StaticMessage([type]$Type) {
Write-Verbose "[$($Type.Name)] static constructor"
}
static [void] ParamMessage([type]$Type, [object]$Value) {
Write-Verbose "[$($Type.Name)] param constructor ($Value)"
}
static BaseExample() { [BaseExample]::StaticMessage([BaseExample]) }
BaseExample() { [BaseExample]::DefaultMessage([BaseExample]) }
BaseExample($Value) { [BaseExample]::ParamMessage([BaseExample], $Value) }
}
class DerivedExample : BaseExample {
static DerivedExample() { [BaseExample]::StaticMessage([DerivedExample]) }
DerivedExample() { [BaseExample]::DefaultMessage([DerivedExample]) }
DerivedExample([int]$Number) : base($Number) {
[BaseExample]::ParamMessage([DerivedExample], $Number)
}
DerivedExample([string]$String) {
[BaseExample]::ParamMessage([DerivedExample], $String)
}
}
以下块显示了调用基类构造函数的详细消息传递。静态构造函数消息仅在第一次创建类的实例时发出。
PS> $VerbosePreference = 'Continue'
PS> $b = [BaseExample]::new()
VERBOSE: [BaseExample] static constructor
VERBOSE: [BaseExample] default constructor
PS> $b = [BaseExample]::new()
VERBOSE: [BaseExample] default constructor
PS> $b = [BaseExample]::new(1)
VERBOSE: [BaseExample] param constructor (1)
下一个块显示了在新会话中调用派生类构造函数的详细消息传递。第一次调用派生类构造函数时,将调用基类和派生类的静态构造函数。这些构造函数不会在会话中再次调用。基类的构造函数始终在派生类的构造函数之前运行。
PS> $VerbosePreference = 'Continue'
PS> $c = [DerivedExample]::new()
VERBOSE: [BaseExample] static constructor
VERBOSE: [DerivedExample] static constructor
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor
PS> $c = [DerivedExample]::new()
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] default constructor
PS> $c = [DerivedExample]::new(1)
VERBOSE: [BaseExample] param constructor (1)
VERBOSE: [DerivedExample] param constructor (1)
PS> $c = [DerivedExample]::new('foo')
VERBOSE: [BaseExample] default constructor
VERBOSE: [DerivedExample] param constructor (foo)
构造函数运行顺序
当类实例化时,将执行一个或多个构造函数的代码。
对于不从另一个类继承的类,顺序是:
- 类的静态构造函数。
- 类的适用构造函数重载。
对于从另一个类继承的派生类,顺序为:
- 基类的静态构造函数。
- 派生类的静态构造函数。
- 如果派生类构造函数显式调用基构造函数重载,它将运行基类的该构造函数。如果它没有显式调用基构造函数,它将运行基类的默认构造函数。
- 派生类的适用构造函数重载。
在所有情况下,静态构造函数在会话中仅运行一次。
有关构造函数行为和排序的示例,请参阅示例 5。
隐藏构造函数
您可以通过使用 hidden
关键字声明类的构造函数来隐藏它们。隐藏类构造函数是:
- 不包含在该类的默认输出中。
- 不包含在
Get-Member
cmdlet 返回的类成员列表中。要使用Get-Member
显示隐藏属性,请使用 Force 参数。 - 除非完成发生在定义隐藏属性的类中,否则不会在制表符完成或 IntelliSense 中显示。
- 班级的公共成员。可以访问和修改它们。隐藏财产并不意味着它是私有的。它仅隐藏前面几点所述的属性。
笔记
当您隐藏任何构造函数时,new()
选项将从 IntelliSense 和完成结果中删除。
有关 hidden
关键字的更多信息,请参阅 about_Hidden。
静态构造函数
您可以通过使用 static
关键字声明构造函数,将构造函数定义为属于类本身而不是类的实例。静态类构造函数:
- 仅在会话中第一次创建该类的实例时调用。
- 不能有任何参数。
- 无法使用
$this
变量访问实例属性或方法。
派生类的构造函数
当一个类从另一个类继承时,构造函数可以使用 base
关键字从基类调用构造函数。如果派生类没有显式调用基类的构造函数,它将调用基类的默认构造函数。
要调用非默认基本构造函数,请在构造函数参数之后、主体块之前添加 : base()
。
class <derived-class> : <base-class> {
<derived-class>(<derived-parameters>) : <base-class>(<base-parameters>) {
# initialization code
}
}
定义调用基类构造函数的构造函数时,参数可以是以下任意项:
- 派生类构造函数中任何参数的变量。
- 任何静态值。
- 任何计算结果为参数类型值的表达式。
有关派生类的构造函数的示例,请参见示例 5。
链接构造函数
与 C# 不同,PowerShell 类构造函数不能使用 : this()
语法进行链接。要减少代码重复,请使用隐藏的 Init()
方法,并通过多个重载达到相同的效果。示例 4 显示了使用此模式的类。
使用 Update-TypeData 添加实例属性和方法
除了直接在类定义中声明属性和方法之外,您还可以使用 Update-TypeData
cmdlet 在静态构造函数中定义类实例的属性。
使用此代码片段作为模式的起点。根据需要替换尖括号中的占位符文本。
class <class-name> {
static [hashtable[]] $MemberDefinitions = @(
@{
Name = '<member-name>'
MemberType = '<member-type>'
Value = <member-definition>
}
)
static <class-name>() {
$TypeName = [<class-name>].Name
foreach ($Definition in [<class-name>]::MemberDefinitions) {
Update-TypeData -TypeName $TypeName @Definition
}
}
}
有用的提示
Add-Member
cmdlet 可以向非静态构造函数中的类添加属性和方法,但每次调用构造函数时都会运行该 cmdlet。在静态构造函数中使用 Update-TypeData
可确保将成员添加到类的代码只需在会话中运行一次。
仅当无法使用 Update-TypeData
定义属性(如只读属性)时,才在非静态构造函数中向类添加属性。
有关使用 Update-TypeData
定义实例方法的更多信息,请参阅 about_Classes_Methods。有关使用 Update-TypeData
定义实例属性的更多信息,请参阅 about_Classes_Properties。
局限性
PowerShell 类构造函数具有以下限制:
未实现构造函数链。
解决方法:定义隐藏的
Init()
方法并从构造函数中调用它们。构造函数参数不能使用任何属性,包括验证属性。
解决方法:使用验证属性重新分配构造函数主体中的参数。
构造函数参数不能定义默认值。参数始终是强制性的。
解决方法:无。
如果隐藏构造函数的任何重载,则构造函数的每个重载也将被视为隐藏。
解决方法:无。
参见
- 关于课程
- about_Classes_Inheritance
- about_类_方法
- about_Classes_Properties
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag