客观的说,Perl和Python都是支持面向对象的语言,不同的是Perl的面向对象是以『包(package)』为基础组织代码,而Python则是以『类(class)』为基础组织代码——二者有相同,也有不同,下面就让我们一起看看它们的具体区别
所谓面向对象(OO),是指『以对象实例核心思考问题、解决问题』
这句话有点抽象,还是看代码比较实在
[Person.java]
/**功能演示:实现Java的OO编程*/
public class Person{
/**Person类的属性字段,被protected修饰表示对当前包内、整个工程中子类可见*/
protected String name;
protected int age;
/**Person类的构造函数,被public修饰表示在整个工程中可见*/
public Person(String name, int age){
this.name=name;
this.age=age;
}
/**Person类的成员方法,通常方法都用public修饰*/
public void show_info(){
System.out.println("My name is "+name+" and I am "+age+" years old");
}
}
在上面的例子中,我们创建了一个Person类,用来抽象描述具有Person属性和方法的一类事物;之后可以使用new关键字来实例化一个Java对象,再通过这个对象访问它具有的属性和方法
可以看到,Java的面向对象比较传统,和C++、Python一样,都是用class
关键字来显式表明这是一个类
Perl的面向对象有点古怪,它的通过一个包一个包来组织代码的
我们说,不管具体是怎么实现面向对象的,只要成功实现了面向对象编程,那么就必然满足以下四点OOP的特点:
· 抽象(Abstract)
· 封装(Encapsulation)
· 继承(Inheritance)
· 多态(Polymorphism)
这四点要谨记,当我们说一个语言满足OOP的特性实际上表明满足以上四点特性
肤浅的理论记忆部分搞定了,让我们开始深入理解
避免走题之嫌,我决定将Perl和Python分别列出来作为两个子标题
演示一:
#!/bin/perl
package Person;
sub new {
my ($class, $name, $age) = @_; #第一个参数为类名
my $_obj = {
"name" => $name;
"age" => $age;
};
return $obj;
}
sub change_name {
my ($slef, $new_name) = @_; #第一个参数为对象名
$self -> {name} = $new_name;
}
my $obj_person = Person->new("Albert",18);
print "$obj_person->{name}\n"; #Albert
print "$obj_person->{age}\n"; #18
Person::change_name(obj_person, "Martin");
print "obj_person->{name}\n"; #Martin
演示二(bless关键字的使用):
#!/bin/perl
#filename:Person.pm
package Person;
sub sleep() {
my $(self) = @_;
my $name = self->{"name"};
print "$name is a person, he is eating...\n";
}
sub study {
my $(self) = @_;
my $name = $self->{"name"};
print "$name is a person, he is studying...\n";
}
#!/bin/perl
#filename:Dog.pm
package dog;
sub eat {
my $(self) = @_;
my $name = $self->{"name"};
print "$name is a dog, he is eating...\n";
}
sub bark {
my $(self) = @_;
my $name = $self->{"name"};
print "$name is a dog, he is barking...\n";
}
#!/bin/perl
#filename:main.pl
package Main;
sub main() {
my $obj = {"name"=>"Tom"};
#先把Tom变成人
bless($object, "Person");
$obj->eat();
$obj->study();
#再把Tom变成狗
bless($obj, "Dog");
$obj->eat();
$obj->bark();
}
小结下:1)bless
关键字可以用来将实例对象和对应的类进行绑定(赋予该变量以相应的类信息)
2)bless
关键字的位置是灵活的,既可以放在new函数(new不是Perl的关键字,但是约定俗成我们用new来表示初始化函数,即Java的构造方法)中——如果放在new中就是最后来一句return $obj
、return $file(file为配置文件,类似的)
或者bless \$file, $class(class是包名)
也可以在new函数中不出现什么bless
,这样的话当我们创建一个新的对象时就要手动调用bless
函数
3)Perl的bless
函数可以用C++的写法来理解:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct object{
char name[16];
};
struct Person{
char name[16];
void eat(){printf("%s is a person, he is eating...\n", this->name);}
void study(){printf("%s is a person, he is studing...\n", this->name);}
};
struct Dog{
char name[16];
void eat(){printf("%s is a dog, he is eating...\n", this->name)}
void bark(){printf("%s is a dog, he is barking...\n", this->name)}
};
#define bless(object, type) ((type*)object)所谓bless,实质上就是强制类型cast!
int main()
{
struct object *o = (struct object*)malloc(sizeof(struct object));
strcpy(o->name, "Tom");
//先把Tom变成人
bless(o, Person)->eat();
bless(o, Person)->study();
//再把Tom变成狗
bless(o, Dog)->eat();
bless(o, Dog)->bark();
return 0;
}
演示三:完整代码
#!/bin/perl
=pod 功能演示:实现Perl的OO编程 =cut
package Person; #定义包名,同时也定义了Person类
sub new #new方法同Java的构造方法 {
print "Person::new called\n";
my $type = shift;#new方法默认第一个参数是类名
my $self = {};#引用空哈希
return bless $self, $class;
}
sub DESTROY #析构函数以及垃圾回收 {
print "Person::DESTROY called\n";
}
sub my_method {
print "Person::my_method called\n";
}
package Student; #继承实现(package的作用域在两个package之间,或者为当前整个文件)
@ISA=wq(Person); #使用内置的ISA数组可以实现多继承
sub new {
print "Student::new called\n";
my $type = shift; #包名
my $self = Person->new; #引用空哈希
return bless $self, $type; #bless关键字把类型信息赋予实例变量,这里也可以不写bless,当以后需要的时候再使用bless调用
}
sub DESTROY {
print "Student::SESTROY called\n";
}
sub my_method #方法覆写 {
my $self = shift;
$self = SUPER::my_method();
print "Student::my_method called\n";
}
package main; #调用以上类的主程序
print "调用Person方法";
$my_obj = Person->new();
$my_obj->my_method();
print "调用Student方法";
$my_obj2 = Student->new();
$my_obj2 = my_method();
print "创建一个作用域对象\n";
{
my $my_obj2 = Person->new();
}
#自动调用析构函数
print "创建对象\n";
$my_obj3 = Person->new();
undef $my_obj3;
print "脚本执行结束";
#自动执行析构函数
Perl的面向对象真的比较抽象难懂,暂时先写到这里(以后有时间补上,具体的Perl中类的实现之细节部分)
Python的面向对象,和Perl比起来要好懂得多
演示一:完全依赖于实例对象
对象在创建完成后还可以为它添加额外的属性,我们把这部分属性称为对象属性,对象属性仅属于该对象,不具有继承性
#filename: person.py
class Person(object): #继承自object类(Python关键字小写)
def __init__(slef, name, age): #Python的初始化方法
self.name = name #self不是关键字,相当于Java的this
slef.age = age #self私有变量,只能通过类实例进行访问
slef.food = apple #self私有变量且不用从外界接受参数
def eat(self):
print name+" is eating "+food
def change_food(self, food):
self.food = food
def show_info(slef):
print "My name is "+self.name+" and I am "+age+" years old."
ming = Person("Xiaoming", 6)
ming.eat() #Xiaoming is eating apple
Qiang = Person("Xiaoqiang", 11)
qiang.change_food("banana")
qiang.eat() #Xiaoqiang is eating banana
演示二:使用括号表示继承关系(Python支持多继承)
#filename: student.py
from person import Person
class Student(Person):
def __init__(self, name, age, grade=60): #grade默认为60
super(Student, self).__init__(name, age) #调用父类构造方法
self.grade = grade
def change_grade(self, grade): #定义子类自己的方法
self.grade = grade
def show_info(slef): #覆写父类的方法
print "My name is "+self.name+" and I am "+age+" years old. I got "+grade+" in my recent test."
演示三:类属性和类方法(相当于Java的static关键字)
我们把定义在类中的属性称为类属性,该类的所有对象共享类属性,类属性具有继承性,可以为类动态地添加类属性
在编写程序的时候,千万不要对实例属性和类属性使用相同的名字,因为相同名称的实例属性将屏蔽掉类属性,但是当你删除实例属性后,再使用相同的名称,访问到的将是类属性
class Businessman(object):
id = "Businessman"
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
count +=1;
huang = Businessman("Dahuang", 35)
print "The id of huang is "+Businessman.id
print "The name of huang is "+huang.name+" and he is "+str(huang.age)+" years old"
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。