2017-06-14 10 views
4

サブクラスのコンストラクタからスーパークラスで宣言されたインスタンス変数を割り当てる方法はありますか?私はコンストラクタとしてBUILD()を使用することに慣れてきましたが、これが良い考えであるかどうかは疑問です。 I:Perl6:サブクラスのコンストラクタ

上記のコードは機能しません。「属性$!filenameはクラスXmlFileで宣言されていません」というエラーメッセージが表示されます。それは正しいアクセサを使用することの問題ですか? "!"を変更する"へ。"問題を解決しません。

答えて

4

あなたは途中です。あなたはあなたのコードへの正しい変更を行う必要があります。

Fileクラスに $.filename$!filenameの交換
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") 

は、そのクラスのパブリックアクセサ方法(.filename)を生成します。

(フレーズ「public属性」を参照してくださいするとき、それは本当にアクセスを制御する「パブリックアクセサ」があることを意味します。、すなわち常に、技術的には常に他のクラスでもtrustedものに使用できないクラスにプライベートな属性があります対応する基本的なプライベート属性に。)

XmlFileクラスのBUILD署名から! twigilを削除するあなたは、もはや存在しない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の属性にすることで関係「である」の代わりに「持っている」の関係を使用して検討する必要があります。

特性は、サブクラス化を指示するための特に簡単で便利な別のクラスへの委任を行います。

関連する問題