无涯教程-Perl - 面向对象

news2024/10/2 22:18:09

 Perl中的面向对象概念很大程度上基于引用以及匿名数组和哈希。让我们开始学习面向对象Perl的基本概念。

定义类

在Perl中定义一个类非常简单。类以最简单的形式对应于Perl软件包。要在Perl中创建一个类,我们首先构建一个包。

Perl软件包在Perl程序中提供了一个单独的名称空间,该名称空间使子例程和变量独立于与其他软件包中的子例程和变量的冲突。

package Person;

创建对象

要创建类的实例,我们需要一个对象构造函数。此构造函数是在包内定义的方法。大多数程序员选择将此对象构造函数方法命名为new,但是在Perl中可以使用任何名称。

package Person;
sub new {
   my $class=shift;
   my $self={
      _firstName => shift,
      _lastName  => shift,
      _ssn       => shift,
   };
   # Print all the values just for clarification.
   print "First Name is $self->{_firstName}\n";
   print "Last Name is $self->{_lastName}\n";
   print "SSN is $self->{_ssn}\n";
   bless $self, $class;
   return $self;
}

现在,让我们看看如何创建一个对象。

$object=new Person( "Mohammad", "Saleem", 23234345);

如果不想将任何值分配给任何类变量,则可以在构造函数中使用简单哈希。例如-

package Person;
sub new {
   my $class=shift;
   my $self={};
   bless $self, $class;
   return $self;
}

定义方法

其他面向对象的语言具有数据安全性的概念,以防止程序员直接更改对象数据,并且它们提供访问器方法来修改对象数据。 Perl没有私有变量,但是我们仍然可以使用辅助方法的概念来操作对象数据。

让我们定义一个辅助方法来获取人的名字-

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

另一个用于设置人的名字-

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

现在让我们看一个完整的示例:将Person包和辅助函数保存在Person.pm文件中。

#!/usr/bin/perl 

package Person;

sub new {
   my $class=shift;
   my $self={
      _firstName => shift,
      _lastName  => shift,
      _ssn       => shift,
   };
   # Print all the values just for clarification.
   print "First Name is $self->{_firstName}\n";
   print "Last Name is $self->{_lastName}\n";
   print "SSN is $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文件中的Person对象-

#!/usr/bin/perl

use Person;

$object=new Person( "Mohammad", "Saleem", 23234345);
# Get first name which is set using constructor.
$firstName=$object->getFirstName();

print "Before Setting First Name is : $firstName\n";

# Now Set first name using helper function.
$object->setFirstName( "Mohd." );

# Now get first name set by helper function.
$firstName=$object->getFirstName();
print "Before Setting First Name is : $firstName\n";

当我们执行以上程序时,它产生以下输出-

First Name is Mohammad
Last Name is Saleem
SSN is 23234345
Before Setting First Name is : Mohammad
Before Setting First Name is : Mohd.

类继承

例如,我们可以有一个Employee类,该类继承自Person。这被称为" isa"关系,因为员工是一个人。 Perl有一个特殊的变量@ISA,以帮助解决此问题。 @ISA控制(方法)继承。

因此,要创建一个新的Employee类以继承Person类的方法和属性,我们只需编写以下代码:将这些代码保存在Employee.pm中。

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA=qw(Person);    # inherits from Person

现在,Employee Class具有从Person类继承的所有方法和属性,您可以按如下方式使用它们:使用main.pl文件对其进行测试-

#!/usr/bin/perl

use Employee;

$object=new Employee( "Mohammad", "Saleem", 23234345);
# Get first name which is set using constructor.
$firstName=$object->getFirstName();

print "Before Setting First Name is : $firstName\n";

# Now Set first name using helper function.
$object->setFirstName( "Mohd." );

# Now get first name set by helper function.
$firstName=$object->getFirstName();
print "After Setting First Name is : $firstName\n";

当我们执行以上程序时,它产生以下输出-

First Name is Mohammad
Last Name is Saleem
SSN is 23234345
Before Setting First Name is : Mohammad
Before Setting First Name is : Mohd.

方法重载

子类Employee从父类Person继承所有方法。但是,如果您想在子类中覆盖这些方法,则可以通过提供自己的实现来实现。您可以在子类中添加其他函数,也可以在其父类中添加或修改现有方法的函数。可以按照以下步骤完成:修改Employee.pm文件。

#!/usr/bin/perl

package Employee;
use Person;
use strict;
our @ISA=qw(Person);    # inherits from Person

# Override constructor
sub new {
   my ($class)=@_;

   # Call the constructor of the parent class, Person.
   my $self=$class->SUPER::new( $_[1], $_[2], $_[3] );
   # Add few more attributes
   $self->{_id}  =undef;
   $self->{_title}=undef;
   bless $self, $class;
   return $self;
}

# Override helper function
sub getFirstName {
   my( $self )=@_;
   # This is child class function.
   print "This is child class helper function\n";
   return $self->{_firstName};
}

# Add more methods
sub setLastName{
   my ( $self, $lastName )=@_;
   $self->{_lastName}=$lastName if defined($lastName);
   return $self->{_lastName};
}

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

1;

现在,让我们再次尝试在main.pl文件中使用Employee对象并执行它。

#!/usr/bin/perl

use Employee;

$object=new Employee( "Mohammad", "Saleem", 23234345);
# Get first name which is set using constructor.
$firstName=$object->getFirstName();

print "Before Setting First Name is : $firstName\n";

# Now Set first name using helper function.
$object->setFirstName( "Mohd." );

# Now get first name set by helper function.
$firstName=$object->getFirstName();
print "After Setting First Name is : $firstName\n";

当我们执行以上程序时,它产生以下输出-

First Name is Mohammad
Last Name is Saleem
SSN is 23234345
This is child class helper function
Before Setting First Name is : Mohammad
This is child class helper function
After Setting First Name is : Mohd.

自动加载

Perl提供了其他任何编程语言都找不到的函数:默认子程序。这意味着,如果定义一个名为 AUTOLOAD的函数,那么对未定义子例程的任何调用都会自动调用AUTOLOAD函数。缺少的子例程的名称可以在该子例程中以$AUTOLOAD的形式访问。

默认的自动加载函数对于错误处理非常有用。这是实现AUTOLOAD的示例,您可以以自己的方式实现此函数。

sub AUTOLOAD {
   my $self=shift;
   my $type=ref ($self) || croak "$self is not an object";
   my $field=$AUTOLOAD;
   $field =~ s/.*://;
   unless (exists $self->{$field}) {
      croak "$field does not exist in object/class $type";
   }
   if (@_) {
      return $self->($name)=shift;
   } else {
      return $self->($name);
   }
}

垃圾回收

如果您以前使用面向对象编程进行编程,那么您将意识到有必要创建析构函数,以在使用完对象后释放分配给该对象的内存。一旦对象超出范围,Perl就会自动为您执行此操作。

析构函数方法只是名为DESTROY的成员函数在以下情况下会自动调用-

  • 当对象引用的变量超出范围时。
  • 未定义对象引用的变量时。
  • 脚本终止时。
  • 当perl解释器终止时。

例如,您可以将以下方法DESTROY放在您的类中-

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

完整示例

这是另一个不错的示例,它将帮助您理解Perl的面向对象概念。将此源代码放入任何perl文件中并执行它。

#!/usr/bin/perl

# Following is the implementation of simple Class.
package MyClass;

sub new {
   print "MyClass::new called\n";
   my $type=shift;            # The package/type name
   my $self={};               # Reference to empty hash
   return bless $self, $type;   
}

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

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


# Following is the implemnetation of 遗产.
package MySubClass;

@ISA=qw( MyClass );

sub new {
   print "MySubClass::new called\n";
   my $type=shift;            # The package/type name
   my $self=MyClass->new;     # Reference to empty hash
   return bless $self, $type;  
}

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

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

# Here is the main program using above classes.
package main;

print "Invoke MyClass method\n";

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

print "Invoke MySubClass method\n";

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

print "Create a scoped object\n";
{
   my $myObject2=MyClass->new();
}
# Destructor is called automatically here

print "Create and undef an object\n";
$myObject3=MyClass->new();
undef $myObject3;

print "Fall off the end of the script...\n";
# Remaining destructors are called automatically here

当我们执行以上程序时,它产生以下输出-

Invoke MyClass method
MyClass::new called
MyClass::MyMethod called!
Invoke MySubClass method
MySubClass::new called
MyClass::new called
MyClass::MyMethod called!
MySubClass::MyMethod called!
Create a scoped object
MyClass::new called
MyClass::DESTROY called
Create and undef an object
MyClass::new called
MyClass::DESTROY called
Fall off the end of the script...
MyClass::DESTROY called
MySubClass::DESTROY called

Perl - 面向对象 - 无涯教程网无涯教程网提供 Perl中的面向对象概念很大程度上基于引用以及匿名数组和哈希。让我们开始学习面向对...https://www.learnfk.com/perl/perl-object-oriented.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/836161.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java-day05(面向对象-1)

面向对象 面向对象与面向过程的区别: 面向过程,强调功能行为;面向对象,强调功能的对象。 Java类及类成员 类:对一类事物描述,是抽象的,概念上的定义对象:实际存在的该类事物的每…

(自控原理)线性系统的频域分析法

目录 一、频率特性 1、频率特性的基本概念 2、频率特性的几何表示方法 二、典型环节与开环系统的频率特性 1、典型环节 2、开环对数的频率特性曲线 三、稳定裕度 1、相角裕度 2、幅值裕度 一、频率特性 1、频率特性的基本概念 2、频率特性的几何表示方法 二、典型环节…

<van-empty description=““ /> 滚动条bug

使用 <van-empty description"" /> 时&#xff0c;图片出现了个滚动条&#xff0c;图片可以上下滑动。 代码如下&#xff1a; <block wx:if"{{courseList.length < 0}}"><van-empty description"" /> </block> <…

跨境电商怎么做?Live Market教你创业及做大生意

随着全球化的不断深入和互联网技术的迅猛发展&#xff0c;跨境电商成为了一个蓬勃发展的行业。根据eMarketer的数据&#xff0c;2021年全球跨境电商销售额将达到4.5万亿美元&#xff0c;预计到2025年将增长至6.3万亿美元。这表明&#xff0c;跨境电商行业将继续保持强劲增长的趋…

uni-app:分页实现多选功能

效果 代码解析 一、标签-列表 <view class"item_all" v-for"(item, index) in info" :key"index"><view class"position parameter-info text-over" :class"{checked_parameter: item.checked}" :data-id"i…

EditPlus取消自动.bak备份

Tools->Preferences->File 将√取消

Java正则校验密码至少包含:字母数字特殊符号中的2种

一、语法 字符说明\将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如&#xff0c; n匹配字符 n。\n 匹配换行符。序列 \\\\ 匹配 \\ &#xff0c;\\( 匹配 (。^匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性&#xff0c;^ 还会与"\n…

如何开发一个企业ERP系统

企业ERP系统是一种针对企业管理和运营的综合性管理软件&#xff0c;旨在提高企业的效率和生产力。随着信息化时代的发展&#xff0c;越来越多的企业意识到引入ERP系统的重要性。本文将详细介绍如何开发一个企业ERP系统&#xff0c;为读者提供丰富、详细的信息。 一、需求分析 …

基于SpringBoot+Vue的地方美食分享网站设计与实现(源码+LW+部署文档等)

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架…

SQL SERVER ROW_NUMBER、RANK、DENSE_RANK 分页应用

** ROW_NUMBER 、RANK、DENSE_RANK** ROW_NUMBER () over( order by 列) # 不论【列】是否存在重复&#xff0c; 序号都不会重复的&#xff0c;通常用唯一个标识的列 RANK() over(order by 列) # 列 存在重复&#xff0c; 则 顺序号一致&#xff0c; 两个人并列第一&#xff0c…

SpringBoot Plus+代码生产器

0目录 1. Mybatis Plus 2.代码生产器 1.Mybatis Plus 创建数据库和表&#xff08;id没有设置主键和自增长&#xff09; 创建springBoot导入依赖 安装lombok 配置yml 实体类加入注解 无参构造和有参构造 Mapper接口 扫描接口 测试 加入日志 添加 数据库…

Springboot 多数据源 dynamic-datasource动态添加移除数据源

0.前言 上一篇文章我们讲了如何通过多数据源组件&#xff0c;在Spring boot Druid 连接池项目中配置多数据源&#xff0c;并且通过DS注解的方式切换数据源&#xff0c;《Spring Boot 配置多数据源【最简单的方式】》。但是在多租户的业务场景中&#xff0c;我们通常需要手动的…

Python:Spider爬虫工程化入门到进阶(2)使用Spider Admin Pro管理scrapy爬虫项目

Python&#xff1a;Spider爬虫工程化入门到进阶系列: Python&#xff1a;Spider爬虫工程化入门到进阶&#xff08;1&#xff09;创建Scrapy爬虫项目Python&#xff1a;Spider爬虫工程化入门到进阶&#xff08;2&#xff09;使用Spider Admin Pro管理scrapy爬虫项目 目录 1、使…

排序算法(九大)- C++实现

目录 基数排序 快速排序 Hoare版本&#xff08;单趟&#xff09; 快速排序优化 三数取中 小区间优化 挖坑法&#xff08;单趟&#xff09; 前后指针法&#xff08;单趟&#xff09; 非递归实现&#xff08;快排&#xff09; 归并排序 非递归实现&#xff08;归并&am…

小程序https域名校验文件放在根目录

1. 下载校验文件 微信公众号平台 - 开发管理 - 开发设置 - 业务域名 2. 将校验文件放在服务器nginx - html 目录下 3. 修改nginx.conf 我这里配置的https主要是用来转发后台接口路径的 4. 验证 https://域名/校验文件名.txt&#xff0c;有返回即配置成功

OpenMesh 网格数据读取写入

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 通常,网格读取器和写入器例程是直接根据它们支持的数据结构和各自的文件格式编写的。这种方法的主要缺点是针对不同的数据结构或添加另一种文件格式会导致代码重复。因此OpenMesh提供了另一种做法,添加一个中间者…

java序列化框架全集讲解

一、简介 Java序列化框架是一种用于在Java应用程序中将对象转换为字节流或从字节流反序列化为对象的工具。序列化是将对象的状态转换为字节流的过程&#xff0c;以便可以将其存储在文件中、通过网络传输或在不同的系统之间共享。反序列化是将字节流转换回对象的过程。 Java序列…

【JS】前端编程8个小技巧(一)

文章目录 1.判断两个数是不是符号相同函数书写运算结果 2.判断一个数n是不是2的整数次幂函数书写运算结果 3.倒序遍历简写函数书写运算结果 4.快速得到一个星级评分函数书写运算结果 5.在程序抛出异常时快速切换搜索引擎stackoverflow的人机验证界面函数书写示例检索结果stacko…

发现全新TNAS Mobile 3,畅享铁威马NAS的乐趣!

千呼万唤始出来&#xff0c;铁威马全新TNAS mobile 3.2.18正式上线啦&#xff01;新增超实用的功能&#xff0c;搭配全新的更合理美观的 UI。往下看&#xff0c;给大家带来全新的移动存储管理体验&#xff01; 注意事项 目前TNAS mobile 3.2.18仅限于在安卓手机上运行&#xf…

MyBatis源码剖析之Configuration、SqlSession、Executor、StatementHandler细节

文章目录 概述源码剖析-初始化ConfigurationMappedStatement 源码剖析-执行SQL流程SqlSessionSqlSessionFactoryDefaultSqlSession 源码剖析-ExecutorBaseExecutorSimpleExecutor 源码剖析-StatementHandlerParameterHandlerStatementHandlerResultSetHandler 概述 MyBatis是一…