2017-06-14 170 views
4

有没有办法从子类中的构造函数中分配在超类中声明的实例变量?我已经习惯使用BUILD()作为构造函数,但是我想知道这是否是一个好主意。 I.e:Perl6:子类中的构造函数

use v6;  

class File                                                          
{                                                            
    has $!filename;                                                
}                                                                                                                      

class XmlFile is File                                                       
{                                                            
    submethod BUILD(:$!filename)                                                    
    { 
    } 
} 

my XmlFile $XF = XmlFile.new(filename => "test.xml"); 

上面的代码不起作用,提示错误:“属性$!文件名未在类XmlFile中声明”。这是使用正确的accesser的问题吗?改变“!”至 ”。”并不能解决问题。

回答

4

你在这里一半。你必须做出正确的更改您的代码:

class File { 
    has $.filename;     # 1. Replace `!` with `.` 
} 

class XmlFile is File { 
    submethod BUILD(:$filename) { } # 2. Remove `!` 
} 

dd my XmlFile $XF = XmlFile.new(filename => "test.xml"); 

# XmlFile $XF = XmlFile.new(filename => "test.xml") 

File类更换$!filename$.filename生成该类中的公共访问方法(.filename)。

(注:属性在技术上总是私人的一类,即始终无法提供其他类,甚至trusted的。当你看到“公共属性”的真正含义有一个“公开访问”控制访问到对应的下层专用属性。)

BUILD签名卸下! twigil在XmlFile类意味着你不再试图引用不存在的XmlFile属性,而不是仅仅通过命名参数。

Object Construction

Due to the default behavior of BUILDALL and BUILD submethods, named arguments to the constructor new derived from Mu can correspond directly to public attributes of any of the classes in the method resolution order, or to any named parameter of any BUILD submethod.

(有这个“公共属性”用词不当,它的意思是“匹配的公共访问属性”。)

+0

的确是的:)谢谢。 – Mikkel

0

如果你想它不公开,你可以总是将其直接添加到子类中。 (也许你不控制你正在继承的类)当然,你将必须小心哪些方法做你的类和子类之间的事情。

class File                                                          
{                                                            
    has $!filename;                                                
}                                                                                                                      

class XmlFile is File                                                       
{ 
    has $!filename; 

    submethod BUILD(:$!filename)                                                    
    { 
    } 
} 

my XmlFile $XF = XmlFile.new(filename => "test.xml"); 

您可能还需要考虑使用“有”关系,而不是一个“是”,方法是将该持有class File取决于您正在尝试做的class XmlFile的属性关系。

handles特征使委派到另一个类是一个特别容易和有用的选项来指导子类化。