Latest web development tutorials

Perlのオブジェクト指向

Perlのオブジェクト指向するプログラミングを二つの異なる実装があります。

  • 一つの無名ハッシュテーブルベースのアプローチは、各オブジェクトインスタンスの本質は無名ハッシュテーブルを参照のポイントです。 この匿名のハッシュテーブル内のすべてのインスタンスプロパティを格納します。
  • 第二は、方法の配列に基づいて、クラスの定義では、我々は、配列の各インスタンスのプロパティを作成し、各オブジェクトインスタンスの本質は、行インデックス参照の配列へのポインタです。 これらのアレイでは、すべてのインスタンスプロパティのメモリ。

オブジェクト指向の基本概念

オブジェクト、クラス、およびメソッド:私たちは3を受信したオブジェクト指向の多くの基本的な概念があります。

  • オブジェクト:オブジェクトがクラスの参照データ項目です。

  • クラス:クラスは、クラスのメソッドを提供するオブジェクトが含まれているPerlのパッケージです。

  • 方法:この方法は、Perlのサブルーチンでは、クラス名は、最初の引数です。

Perlは、参照を通じてオブジェクトを作成し、このクラスに関連付けられた名前を祝福し、オブジェクトを構築するには、この参照を返すために使用される祝福祝福()関数を提供します。


クラス定義

クラスは、単純なパッケージです。

あなたはクラスとしてパッケージを使用し、使用するクラスメソッドの関数としてバッグを置くことができます。

Perlパッケージは別の名前空間、異なるパッケージや変数名競合しない方法を提供します。

Perlはの.pmのための拡張クラスファイル。

次に、Personクラスを作成します。

package Person;

スクリプトファイルの最後の行に、または次のキーワードの前にパッケージへのクラスのコード範囲。


オブジェクトの作成と使用

我々はコンストラクタを定義する必要があるクラスのインスタンス(オブジェクト)を作成し、ほとんどのプログラムはコンストラクタとしてクラス名を使用し、Perlは任意の名前を使用することができます。

あなたは、Perl Perlオブジェクトなどの変数のさまざまなを使用することができます。 ほとんどの場合、我々は、配列やハッシュのリファレンスを使用します。

次に我々は、Personクラスのコンストラクタを作成するPerlのハッシュリファレンスを使用しています。

あなたがオブジェクトを作成するときは、オブジェクト参照を返すサブルーチンであるコンストラクタを提供する必要があります。

例としては、次のとおりです:

package Person;
sub new
{
    my $class = shift;
    my $self = {
        _firstName => shift,
        _lastName  => shift,
        _ssn       => shift,
    };
    # 输出用户信息
    print "名字:$self->{_firstName}\n";
    print "姓氏:$self->{_lastName}\n";
    print "编号:$self->{_ssn}\n";
    bless $self, $class;
    return $self;
}

次に、我々はオブジェクトを作成します。

$object = new Person( "小明", "王", 23234345);

定義法

Perlのクラスのメソッドだけが、それはまた、メンバ関数として知られているPerlサブルーチン、です。

オブジェクト指向Perl Perlはメソッド定義は、特別な構文を提供していませんが、最初のパラメータが参照されたオブジェクトまたはパッケージのための方法を指定します。

Perlはプライベート変数を提供していませんが、私たちは、補助の方法を介してオブジェクト・データを管理することができます。

次に、名前を取得する方法を定義します。

sub getFirstName {
    return $self->{_firstName};
}

同じことがまた書くことができます。

sub setFirstName {
    my ( $self, $firstName ) = @_;
    $self->{_firstName} = $firstName if defined($firstName);
    return $self->{_firstName};
}

次に、以下のように我々は、コードPerson.pmファイルを変更します。

#!/usr/bin/perl 

package Person;

sub new
{
    my $class = shift;
    my $self = {
        _firstName => shift,
        _lastName  => shift,
        _ssn       => shift,
    };
    # 输出用户信息
    print "名字:$self->{_firstName}\n";
    print "姓氏:$self->{_lastName}\n";
    print "编号:$self->{_ssn}\n";
    bless $self, $class;
    return $self;
}
sub setFirstName {
    my ( $self, $firstName ) = @_;
    $self->{_firstName} = $firstName if defined($firstName);
    return $self->{_firstName};
}

sub getFirstName {
    my( $self ) = @_;
    return $self->{_firstName};
}
1;

employee.plスクリプトコードは次のとおりです。

#!/usr/bin/perl

use Person;

$object = new Person( "小明", "王", 23234345);
# 获取姓名
$firstName = $object->getFirstName();

print "设置前姓名为 : $firstName\n";

# 使用辅助函数设置姓名
$object->setFirstName( "小强" );

# 通过辅助函数获取姓名
$firstName = $object->getFirstName();
print "设置后姓名为 : $firstName\n";

上記のプログラムを実行した後、出力は次のようになります。

$ perl employee.pl
名字:小明
姓氏:王
编号:23234345
设置前姓名为 : 小明
设置后姓名为 : 小强

受け継ぎます

@ISA配列によって連続してPerlのクラスメソッド、他のパッケージ(クラス)の名前を含む配列、変数を継承するには、明示的に設定する必要があります。

多重継承はクラス(パッケージ)名を複数備え@ISA配列です。

この方法は、唯一の@ISAを通じて継承することができ、データを継承することはできません。

次に、クラスEmployeeはPersonクラスを継承して作成します。

Employee.pmファイルのコードは次のとおりです。

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA = qw(Person);    # 从 Person 继承

今、EmployeeクラスはPersonクラスのすべてのメソッドとプロパティが含まれています、我々はmain.plファイルに次のコードを入力して実行します。

#!/usr/bin/perl

use Employee;

$object = new Employee( "小明", "王", 23234345);
# 获取姓名
$firstName = $object->getFirstName();

print "设置前姓名为 : $firstName\n";

# 使用辅助函数设置姓名
$object->setFirstName( "小强" );

# 通过辅助函数获取姓名
$firstName = $object->getFirstName();
print "设置后姓名为 : $firstName\n";

上記のプログラムを実行した後、出力は次のようになります。

$ perl main.pl
名字:小明
姓氏:王
编号:23234345
设置前姓名为 : 小明
设置后姓名为 : 小强

メソッドのオーバーライド

上記の例では、EmployeeクラスはPersonクラスを拡張しますが、Personクラスのメソッドは、需要を満たすことができない場合、そのメソッドを書き換える必要があります。

次に、我々は、Employeeクラスのいくつかの新しいメソッドを追加し、Personクラスのメソッドを書き換えます:

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA = qw(Person);    # 从 Person 继承

# 重写构造函数
sub new {
    my ($class) = @_;

    # 调用父类的构造函数
    my $self = $class->SUPER::new( $_[1], $_[2], $_[3] );
    # 添加更多属性
    $self->{_id}   = undef;
    $self->{_title} = undef;
    bless $self, $class;
    return $self;
}

# 重写方法
sub getFirstName {
    my( $self ) = @_;
    # 这是子类函数
    print "这是子类函数\n";
    return $self->{_firstName};
}

# 添加方法
sub setLastName{
    my ( $self, $lastName ) = @_;
    $self->{_lastName} = $lastName if defined($lastName);
    return $self->{_lastName};
}

sub getLastName {
    my( $self ) = @_;
    return $self->{_lastName};
}

1;

私たちは、次のコードmain.plファイルを入力して実行します。

#!/usr/bin/perl

use Employee;

$object = new Employee( "小明", "王", 23234345);
# 获取姓名,使用修改后的构造函数
$firstName = $object->getFirstName();

print "设置前姓名为 : $firstName\n";

# 使用辅助函数设置姓名
$object->setFirstName( "小强" );

# 通过辅助函数获取姓名
$firstName = $object->getFirstName();
print "设置后姓名为 : $firstName\n";

上記のプログラムを実行した後、出力は次のようになります。

$ perl main.pl
名字:小明
姓氏:王
编号:23234345
这是子类函数
设置前姓名为 : 小明
这是子类函数
设置后姓名为 : 小强

ロードデフォルト

現在でクラス、UNIVERSALは、要求された現在のすべてのベースクラスのクラス、およびクラスメソッドが見つからない場合は、再度)AUTOLOAD(という名前のメソッドを探します。 AUTOLOADを発見した場合は、不足しているメソッドのグローバル変数$ AUTOLOAD値の完全修飾名を設定しながら、呼び出します。

そうでない場合、それはPerlとエラーに失敗しました。

あなたは、基本クラスのAUTOLOADを継承したくない場合は、非常に単純な、ただ一つの文:

sub AUTOLOAD;

デストラクタとガベージコレクション

オブジェクトへの最後の参照が解放されると、オブジェクトは自動的に破壊されます。

あなたは「DESTROY」と呼ばれる方法は、クラスで定義されていることができますデストラクタで何かをしたい場合。 それは、自動的に適切な時間を呼び出しますし、あなたが何を意味するかに応じて、追加のクリーンアップ処理を実行します。

package MyClass;
...
sub DESTROY
{
    print "MyClass::DESTROY called\n";
}

Perlのオブジェクト参照は、唯一のパラメータとして破壊するために渡されます。 [0]、それを修正するために_あなたは$にアクセスすることはできませんを意味し、この引用が読み取り専用であることに注意してください。 (翻訳者注:はperlsubを参照してください)が、オブジェクト自体(例えば、「$ {$ _ [0]」または「@ {$ _ [0]} "と"%{$ _ [0]} "など)またはすることができます書かれました。

あなたはデストラクタ戻る前にオブジェクト参照を再祝福した場合、Perlはデストラクタが戻った後、そのオブジェクトの再祝福DESTROY方法にお電話いたします。 これは、基本クラスを呼び出したり、デストラクタ他のクラスを指定する機会を持つことができます。 また、手動で呼び出すことができますDESTROY、指摘したが、通常は必要ありませんする必要があります。

現在のオブジェクトの解放した後、現在のオブジェクトに含まれる他のオブジェクトは自動的に解除されます。


オブジェクト指向のPerlの例

私たちは、以下の実施例Perlオブジェクト指向アプリケーションによって理解することができます。

#!/usr/bin/perl

# 下面是简单的类实现
package MyClass;

sub new
{
   print "MyClass::new called\n";
   my $type = shift;            # 包名
   my $self = {};               # 引用空哈希
   return bless $self, $type;   
}

sub DESTROY
{
   print "MyClass::DESTROY called\n";
}

sub MyMethod
{
   print "MyClass::MyMethod called!\n";
}


# 继承实现
package MySubClass;

@ISA = qw( MyClass );

sub new
{
   print "MySubClass::new called\n";
   my $type = shift;            # 包名
   my $self = MyClass->new;     # 引用空哈希
   return bless $self, $type;  
}

sub DESTROY
{
   print "MySubClass::DESTROY called\n";
}

sub MyMethod
{
   my $self = shift;
   $self->SUPER::MyMethod();
   print "   MySubClass::MyMethod called!\n";
}

# 调用以上类的主程序
package main;

print "调用 MyClass 方法\n";

$myObject = MyClass->new();
$myObject->MyMethod();

print "调用 MySubClass 方法\n";

$myObject2 = MySubClass->new();
$myObject2->MyMethod();

print "创建一个作用域对象\n";
{
  my $myObject2 = MyClass->new();
}
# 自动调用析构函数

print "创建对象\n";
$myObject3 = MyClass->new();
undef $myObject3;

print "脚本执行结束...\n";
# 自动执行析构函数

上記のプログラムは、出力は次のようになります。

调用 MyClass 方法
MyClass::new called
MyClass::MyMethod called!
调用 MySubClass 方法
MySubClass::new called
MyClass::new called
MyClass::MyMethod called!
   MySubClass::MyMethod called!
创建一个作用域对象
MyClass::new called
MyClass::DESTROY called
创建对象
MyClass::new called
MyClass::DESTROY called
脚本执行结束...
MyClass::DESTROY called
MySubClass::DESTROY called