比较Perl和Python的面向对象


客观的说,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分别列出来作为两个子标题

Perl的面向对象

演示一:

#!/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 $objreturn $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的面向对象

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"
智能推荐

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告