Latest web development tutorials

Perl เชิงวัตถุ

มีสอง Perl ที่แตกต่างกันในการดำเนินการเขียนโปรแกรมเชิงวัตถุ:

  • หนึ่งที่ไม่ระบุชื่อกัญชาวิธีตารางตามสาระสำคัญของตัวอย่างวัตถุแต่ละเป็นจุดของการอ้างอิงไปยังตารางแฮชที่ไม่ระบุชื่อ ในตารางแฮชนี้ที่ไม่ระบุชื่อในการจัดเก็บทุกคุณสมบัติเช่น
  • ที่สองจะขึ้นอยู่กับอาร์เรย์ของวิธีการในความหมายของการเรียนเราจะสร้างอสังหาริมทรัพย์สำหรับอินสแตนซ์ของอาร์เรย์แต่ละและสาระสำคัญของอินสแตนซ์แต่ละวัตถุที่เป็นตัวชี้ไปแถวในแถวอ้างอิงดัชนี ในอาร์เรย์เหล่านี้ความทรงจำของทุกคุณสมบัติอินสแตนซ์

แนวคิดพื้นฐานของการเชิงวัตถุ

วัตถุชั้นเรียนและวิธีการ: มีหลายแนวคิดพื้นฐานของวัตถุที่เราได้รับสาม

  • วัตถุ: วัตถุคือการอ้างอิงระดับรายการข้อมูล.

  • ระดับ: ระดับเป็นแพคเกจ Perl ซึ่งมีวัตถุเพื่อให้วิธีการในชั้นเรียน

  • วิธีการ: วิธีการที่เป็น subroutine Perl, ชื่อชั้นเป็นอาร์กิวเมนต์แรกของมัน

Perl ให้อวยพร () ฟังก์ชันอวยพรที่ใช้ในการสร้างวัตถุที่ผ่านการอ้างอิงและอวยพรชื่อที่เกี่ยวข้องกับชั้นนี้กลับอ้างอิงนี้ในการสร้างวัตถุ


การกำหนดระดับ

ชั้นเป็นเพียงแพคเกจที่เรียบง่าย

คุณสามารถใช้แพคเกจเป็นชั้นและใส่ถุงเป็นหน้าที่ของวิธีการเรียนที่จะใช้

แพคเกจ Perl ให้ namespace ที่แยกต่างหากวิธีการแพคเกจที่แตกต่างกันและชื่อตัวแปรไม่ขัดแย้ง

Perl เรียนนามสกุลไฟล์สำหรับ .pm

ต่อไปเราจะสร้างชั้นบุคคล:

package Person;

รหัสช่วงชั้นเรียนเพื่อบรรทัดสุดท้ายของไฟล์สคริปต์หรือแพคเกจก่อนที่คำหลักถัดไป


การสร้างและการใช้วัตถุ

สร้างอินสแตนระดับ (Object) เราจำเป็นต้องกำหนดตัวสร้างโปรแกรมส่วนใหญ่ใช้ชื่อชั้นเป็นผู้สร้างที่ Perl สามารถใช้ชื่อใด ๆ

คุณสามารถใช้ความหลากหลายของตัวแปรเป็นวัตถุ Perl Perl ในกรณีส่วนใหญ่เราจะใช้อาร์เรย์หรือการอ้างอิงกัญชา

ต่อไปเราจะสร้างคอนสตรัคสำหรับการเรียนบุคคลที่ใช้การอ้างอิงกัญชา 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 ยังเป็นที่รู้จักฟังก์ชั่นสมาชิก

object-oriented นิยามวิธี 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
设置前姓名为 : 小明
设置后姓名为 : 小强

สืบทอด

วิธีการเรียน Perl ในการทดแทนโดยอาร์เรย์ @ ISA อาร์เรย์ที่มีแพ็กเกจอื่น ๆ (ชั้น) ชื่อสืบทอดตัวแปรจะต้องมีการกำหนดอย่างชัดเจน

มรดกหลายเป็นอาร์เรย์ @ ISA ประกอบด้วยส่วนใหญ่ของคลาส (package) ชื่อ

วิธีการเท่านั้นที่สามารถได้รับการถ่ายทอดผ่าน @ ISA ข้อมูลไม่สามารถสืบทอด

ต่อไปเราจะสร้างพนักงานสืบทอด class ระดับบุคคล

รหัสไฟล์ Employee.pm เป็นดังนี้:

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA = qw(Person);    # 从 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
设置前姓名为 : 小明
设置后姓名为 : 小强

วิธีการแทนที่

ตัวอย่างข้างต้น, ระดับพนักงานขยายระดับบุคคล แต่ถ้าวิธีการเรียนบุคคลที่ไม่สามารถตอบสนองความต้องการก็เป็นสิ่งจำเป็นที่จะเขียนวิธีการของ

ต่อไปเราจะเพิ่มวิธีการใหม่ ๆ ในชั้นเรียนของพนักงานและแทนที่วิธีการเรียนบุคคล:

#!/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;

destructors และเก็บขยะ

เมื่อมีการอ้างอิงที่ผ่านมาไปยังวัตถุที่จะถูกปล่อยออกวัตถุที่ถูก destructed โดยอัตโนมัติ

หากคุณต้องการที่จะทำบางสิ่งบางอย่างใน destructor เมื่อคุณสามารถใช้วิธีการที่เรียกว่า "ทำลาย" ถูกกำหนดไว้ในชั้นเรียน โดยอัตโนมัติจะเรียกเวลาที่เหมาะสมและการดำเนินการล้างข้อมูลเพิ่มเติมตามสิ่งที่คุณหมายถึง

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

Perl อ้างอิงวัตถุจะถูกส่งผ่านที่จะทำลายเป็นพารามิเตอร์เท่านั้น โปรดทราบว่าคำพูดนี้เป็นอ่านอย่างเดียวซึ่งหมายความว่าคุณไม่สามารถเข้าถึง $ _ [0] เพื่อปรับเปลี่ยน (หมายเหตุการแปล: ดู perlsub) แต่วัตถุเอง (เช่น "$ {$ _ [0]" หรือ "@ {$ _ [0]}" และ "% {$ _ [0]}" ฯลฯ ) หรือสามารถ เขียน

หากคุณอีกครั้งอวยพรอ้างอิงวัตถุก่อนที่ผลตอบแทนเตาเผา, Perl แล้วจะโทรหาคุณอีกครั้งอวยพรทำลายวิธีการของวัตถุว่าหลังจากที่ผลตอบแทนเตาเผา นี้ช่วยให้คุณมีโอกาสที่จะเรียกคลาสฐานหรือคุณระบุ destructor ชั้นเรียนอื่น ๆ มันควรจะสังเกตทำลายนอกจากนี้ยังสามารถเรียกตนเอง แต่มักจะไม่จำเป็น

หลังจากการเปิดตัวของวัตถุปัจจุบันวัตถุอื่น ๆ ที่มีอยู่ในวัตถุปัจจุบันถูกปล่อยออกมาโดยอัตโนมัติ


ตัวอย่างของ 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