Skip to content

Perl 面向对象

Perl 面向对象基础

包和对象

Perl 的面向对象编程基于包(Package)和引用:

perl
package Person;
use strict;
use warnings;

# 构造函数
sub new {
    my $class = shift;
    my $self = {
        name => shift,
        age => shift,
    };
    bless $self, $class;
    return $self;
}

# 方法
sub greet {
    my $self = shift;
    print "Hello, I'm $self->{name}\n";
}

1;

# 使用
package main;
use Person;

my $person = Person->new("Alice", 25);
$person->greet();

类的定义

基本类结构

perl
package Animal;
use strict;
use warnings;

# 构造函数
sub new {
    my $class = shift;
    my $self = {
        name => shift,
        species => shift,
    };
    bless $self, $class;
    return $self;
}

# 访问器(getter)
sub get_name {
    my $self = shift;
    return $self->{name};
}

sub get_species {
    my $self = shift;
    return $self->{species};
}

# 修改器(setter)
sub set_name {
    my ($self, $name) = @_;
    $self->{name} = $name;
}

# 普通方法
sub speak {
    my $self = shift;
    print "$self->{name} makes a sound\n";
}

1;

package main;
use Animal;

my $animal = Animal->new("Dog", "Canine");
print $animal->get_name, "\n";
$animal->speak();
$animal->set_name("Cat");
print $animal->get_name, "\n";

继承

基本继承

perl
package Animal;
use strict;
use warnings;

sub new {
    my $class = shift;
    my $self = {
        name => shift,
    };
    bless $self, $class;
    return $self;
}

sub speak {
    my $self = shift;
    print "Animal sound\n";
}

1;

package Dog;
use strict;
use warnings;
use base 'Animal';

sub new {
    my $class = shift;
    my $self = $class->SUPER::new(shift);
    $self->{breed} = shift;
    return $self;
}

sub speak {
    my $self = shift;
    print "Woof!\n";
}

sub bark {
    my $self = shift;
    print "Barking loud!\n";
}

1;

package main;
use Dog;

my $dog = Dog->new("Buddy", "Golden Retriever");
$dog->speak();
$dog->bark();

调用父类方法

perl
package Animal;
use strict;
use warnings;

sub new {
    my $class = shift;
    my $self = { name => shift };
    bless $self, $class;
    return $self;
}

sub introduce {
    my $self = shift;
    print "I am $self->{name}\n";
}

1;

package Dog;
use strict;
use warnings;
use base 'Animal';

sub new {
    my $class = shift;
    my $self = $class->SUPER::new(shift);
    return $self;
}

sub introduce {
    my $self = shift;
    $self->SUPER::introduce();
    print "I am a dog\n";
}

1;

package main;
use Dog;

my $dog = Dog->new("Buddy");
$dog->introduce();

多态

方法重写

perl
package Shape;
use strict;
use warnings;

sub new {
    my $class = shift;
    bless {}, $class;
}

sub area {
    die "Subclass must implement area()\n";
}

1;

package Circle;
use strict;
use warnings;
use base 'Shape';

sub new {
    my ($class, $radius) = @_;
    my $self = { radius => $radius };
    bless $self, $class;
}

sub area {
    my $self = shift;
    return 3.14159 * $self->{radius} ** 2;
}

1;

package Rectangle;
use strict;
use warnings;
use base 'Shape';

sub new {
    my ($class, $width, $height) = @_;
    my $self = { width => $width, height => $height };
    bless $self, $class;
}

sub area {
    my $self = shift;
    return $self->{width} * $self->{height};
}

1;

package main;
use Circle;
use Rectangle;

my @shapes = (
    Circle->new(5),
    Rectangle->new(4, 6),
    Circle->new(3)
);

foreach my $shape (@shapes) {
    printf "Area: %.2f\n", $shape->area();
}

封装

私有方法

perl
package BankAccount;
use strict;
use warnings;

sub new {
    my $class = shift;
    my $self = {
        balance => 0,
        owner => shift,
    };
    bless $self, $class;
    return $self;
}

sub deposit {
    my ($self, $amount) = @_;
    $self->_validate_amount($amount);
    $self->{balance} += $amount;
}

sub withdraw {
    my ($self, $amount) = @_;
    $self->_validate_amount($amount);
    
    if ($self->{balance} >= $amount) {
        $self->{balance} -= $amount;
    } else {
        die "Insufficient funds\n";
    }
}

sub get_balance {
    my $self = shift;
    return $self->{balance};
}

# 私有方法(以下划线开头)
sub _validate_amount {
    my ($self, $amount) = @_;
    die "Invalid amount\n" if $amount <= 0;
}

1;

package main;
use BankAccount;

my $account = BankAccount->new("Alice");
$account->deposit(100);
$account->withdraw(50);
print "Balance: ", $account->get_balance(), "\n";

高级特性

DESTROY 方法

perl
package Resource;
use strict;
use warnings;

sub new {
    my $class = shift;
    my $self = {
        name => shift,
        data => [],
    };
    print "Creating $self->{name}\n";
    bless $self, $class;
    return $self;
}

sub DESTROY {
    my $self = shift;
    print "Destroying $self->{name}\n";
}

1;

package main;
use Resource;

{
    my $res = Resource->new("Temp Resource");
    # $res 在此处超出作用域,DESTROY 被调用
}
print "End of scope\n";

重载运算符

perl
package Vector;
use strict;
use warnings;
use overload
    '""' => \&to_string,
    '+' => \&add,
    '==' => \&equals;

sub new {
    my ($class, $x, $y) = @_;
    my $self = { x => $x, y => $y };
    bless $self, $class;
    return $self;
}

sub to_string {
    my $self = shift;
    return "($self->{x}, $self->{y})";
}

sub add {
    my ($self, $other) = @_;
    return Vector->new(
        $self->{x} + $other->{x},
        $self->{y} + $other->{y}
    );
}

sub equals {
    my ($self, $other) = @_;
    return $self->{x} == $other->{x} && $self->{y} == $other->{y};
}

1;

package main;
use Vector;

my $v1 = Vector->new(1, 2);
my $v2 = Vector->new(3, 4);

my $v3 = $v1 + $v2;
print "$v3\n";  # (4, 6)

my $v4 = Vector->new(1, 2);
if ($v1 == $v4) {
    print "Vectors are equal\n";
}

实践示例

示例 1:图书管理系统

perl
package Book;
use strict;
use warnings;

sub new {
    my ($class, %args) = @_;
    my $self = {
        title => $args{title},
        author => $args{author},
        isbn => $args{isbn},
        available => 1,
    };
    bless $self, $class;
    return $self;
}

sub borrow {
    my $self = shift;
    die "Book is not available\n" unless $self->{available};
    $self->{available} = 0;
}

sub return_book {
    my $self = shift;
    $self->{available} = 1;
}

sub is_available {
    my $self = shift;
    return $self->{available};
}

1;

package Library;
use strict;
use warnings;

sub new {
    my $class = shift;
    my $self = { books => [] };
    bless $self, $class;
}

sub add_book {
    my ($self, $book) = @_;
    push @{$self->{books}}, $book;
}

sub find_by_title {
    my ($self, $title) = @_;
    return grep { $_->{title} eq $title } @{$self->{books}};
}

1;

package main;
use Book;
use Library;

my $library = Library->new();
$library->add_book(Book->new(
    title => "Perl Programming",
    author => "John Doe",
    isbn => "1234567890"
));

my @books = $library->find_by_title("Perl Programming");
print "Found: ", $books[0]->{author}, "\n";

示例 2:图形系统

perl
package Point;
use strict;
use warnings;
use overload
    '""' => \&to_string,
    '+' => \&add,
    '-' => \&subtract;

sub new {
    my ($class, $x, $y) = @_;
    bless { x => $x, y => $y }, $class;
}

sub to_string {
    my $self = shift;
    return "($self->{x}, $self->{y})";
}

sub add {
    my ($self, $other) = @_;
    return Point->new($self->{x} + $other->{x}, $self->{y} + $other->{y});
}

1;

package Circle;
use strict;
use warnings;
use base 'Point';

sub new {
    my ($class, $x, $y, $radius) = @_;
    my $self = $class->SUPER::new($x, $y);
    $self->{radius} = $radius;
    return $self;
}

sub area {
    my $self = shift;
    return 3.14159 * $self->{radius} ** 2;
}

sub circumference {
    my $self = shift;
    return 2 * 3.14159 * $self->{radius};
}

1;

package main;
use Circle;

my $circle = Circle->new(0, 0, 5);
printf "Center: %s\n", $circle;
printf "Area: %.2f\n", $circle->area();
printf "Circumference: %.2f\n", $circle->circumference();

小结

本章节学习了 Perl 的面向对象编程:

  1. ✅ 类和对象的基本概念
  2. ✅ 继承
  3. ✅ 多态
  4. ✅ 封装
  5. ✅ 高级特性(DESTROY、运算符重载)
  6. ✅ 实践示例

接下来,我们将学习 Perl 数据库连接