zoukankan      html  css  js  c++  java
  • 对象(上):

    第十二章 对象(上):
    
    12.1 简单复习一下面向对象的语言:
    
    对象是一个数据结构,带有一些行为。我们通常把这些行为称为对象的直接动作,有时候
    
    可以把这些对象拟人化。
    
    作为一个类的实例,对象从中获益,取得其行为。类定义方法:就是那些应用于类和它的事例的性质。
    
    
    如果需要区分上面两张情况:
    
    1.那么我们就把适用于某一特定对象的方法叫做实例方法
    
    2.而把那些适用于整个类的方法叫做类方法。
    
    不过这样做只是为了方便---对于Perl而言,方法就是方法,只是由其第一个参数的类型来区分。
    
    
    你可以把实例方法看作一个由特定对象执行的某种动作
    
    
    类里面那些生成实例的方法叫构造方法。
    
    
    一个类可以从父类中继承方法,父类也叫基类或者超级类。如果类是这样生成的,那么它叫派生类或者子类
    
    [root@node01 ~]# cat Pkg01.pm 
    package Pkg01;
    sub fun1 {
        my $self=shift;
        my $a=shift;
        my $b=shift;
        print $a * $b +3;};
    1;
    
    
    
    [root@node01 ~]# cat Pkg02.pm 
    package Pkg02;
    sub fun2 {
        my $self=shift;
        my $a=shift;
        my $b=shift;
        print $a * $b +4;};
    1;
    
    
    [root@node01 ~]# cat Pkg03.pm 
    package Pkg03;
    sub fun3 {
        my $self=shift;
        my $a=shift;
        my $b=shift;
        print $a * $b + 4;};
    1;
    
    [root@node01 ~]# cat Scan.pm 
    package Scan;
    use base qw(Pkg01 Pkg02 Pkg03);
    sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = {
    };
    bless $self, $class;
     return $self;
    };
    
    sub fun4 {
     my $self=shift;
     my $a=shift;
     my $b=shift;
     print $a + $b;
    };
    1;
    
    [root@node01 ~]# cat p1.pl 
    use Scan;
    $ua=Scan->new();
    $ua->fun1(4,5);
    print "
    ";
    $ua->fun2(6,7);
    print "
    ";
    $ua->fun3(8,5);
    print "
    ";
    $ua->fun4(3,6);
    print "
    ";
    [root@node01 ~]# perl p1.pl 
    23
    46
    44
    9
    
    
    
    12.2 Perl 的对象系统
    
    Perl 没有为定义对象,类或者方法提供任何特殊的语法。
    
    相反,它使用现有的构造器来实现这三种概念。
    
    一个对象只不过是一个引用 嗯,就是引用
    
    因为引用令独立的标量代表大量的数据,所以我们不应该把引用用于所有对象 感到奇怪。
    
    一个类只是一个包
    
    12.3 方法调用:
    
    方法是对象系统的核心,意味它们为实现所有魔术提供了抽象层。
    
    你不是直接访问对象里的一块数据区,而是调用一个实例方法,
    
    你不是直接调用某个包里的子过程,而是调用一个类的方法。
    
    
    不管使用哪种方法调用的形式,Perl总是会给构成这个方法的子过程传递一个额外的初始化参数。
    
    
    如果用一个类调用该方法,那么参数将会是类的名字
    
    如果用一个对象调用方法,那么参数就是对象的引用
    
    12.3.1 使用箭头操作符的方法调用:
    
    我们说挂有两种风格的方法调用,第一种调用的方法的风格看起来像下面这样:
    
    INVOCANT->METHOD(LIST)
    
    INVOCANT->METHOD
    
    
    而当INVOCANT 是一个包的名字的时候,我们把那个调用的METHOD看作类的方法。
    
    比如,使用类方法summon 的构造一个类,然后再生成的对象上调用实例方法speak,你可以这么说:
    
    $mage = Wizard->summon("Gandalf"); # 类方法
    $mage->speak("friend"); # 实例方法
    
    
    
    
    [root@node01 perl]# cat Wizard.pm 
    package Wizard;
    sub summon {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    print "$class==$class
    ";
    my $self = {
    };
    bless $self, $class;
     return $self;
    };
    
    
    sub speak {
      my $self=shift;
      print "freend*5";
    };
    1;
    
    [root@node01 perl]# cat Wizard.pm 
    package Wizard;
    sub summon {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    print "$class==$class
    ";
    my $self = {
    };
    bless $self, $class;
     return $self;
    };
    
    
    sub speak {
      my $self=shift;
      print "freend*5";
    };
    1;
     
    [root@node01 perl]# cat a2.pl 
    use Wizard;
    $mage = Wizard->summon("Gandalf"); # 类方法
    $mage->speak("friend"); # 实例方法
    [root@node01 perl]# perl a2.pl 
    $class==Wizard
    freend*5[root@node01 perl]# 
    
    12.3.2 使用间接对象的方法调用;
    
    第二种风格的方法调用起来像这样:
    
    METHOD INVOCANT (LIST)
    
    METHOD INVOCANT LIST
    
    METHOD INVOCANT
    
    
    
    12.3.4 引用包的类;
    
    12.4 构造对象
    
    所有对象都是引用,但不是所有引用都是对象
    
    一个引用不会作为对象运转,除非引用它的东西有特殊标记告诉Perl它属于哪个包。
    
    bless 函数接收一个或者两个参数,第一个参数是引用,而第二个是要把引用赐福(bless)成的包。
    
    如果忽略第二个参数,则使用当前包:
    
    [root@node01 perl]# cat Luo.pm 
    package Luo;
    sub new {
     my $invocant = shift;
     my $class = ref($invocant) || $invocant;
     print "$class==$class
    ";
     my $obj = {
     } ;
     bless $obj, $class;
     return $obj;
    };
    
    sub fun1 {
      my $self=shift;
      my $a=shift;
      my $b=shift;
      return $a + $b;
    };
    1;
    [root@node01 perl]# cat a4.pl 
    use Luo;
    my $ua=Luo->new();
    print $ua->fun1(44,33);
    [root@node01 perl]# perl a4.pl 
    $class==Luo
    77[root@node01 perl]# 
    
    
    12.4.1 可继承构造器:
    
    和所有方法一样,构造器只是一个子过程,但是我们不把它看作一个子过程。
    
    在这个例子里,我们总是把它当作一个方法调用---一个类方法,因为调用者是一个包的名字。
    
    
    方法调用:
    
    [root@node01 perl]# cat Luo.pm 
    package Luo;
    sub new {
     my $invocant = shift;
     my $class = ref($invocant) || $invocant;
     print "$class==$class
    ";
     my $obj = {
     } ;
     bless $obj, $class;
     return $obj;
    };
    
    sub fun1 {
      my $self=shift;
      my $a=shift;
      my $b=shift;
      return $a + $b;
    };
    1;
    [root@node01 perl]# cat a4.pl 
    use Luo;
    my $ua=Luo->new();
    print $ua->fun1(44,33);
    
    [root@node01 perl]# perl a4.pl 
    $class==Luo
    $self==Luo=HASH(0x14af160)
    77[root@node01 perl]# 
    
    
    子过程调用:
    [root@node01 perl]# cat a5.pl 
    use Luo;
    print Luo::fun1(44,33);
    [root@node01 perl]# perl a5.pl 
    $self==44
    33[root@node01 perl]# 
    
    
    
    $type = "Spider";
    $shelob = $type->spawn; # 和 "Spider"->spawn 一样
    这些仍然是类方法,不是实例方法,因为它的调用者持有的是字串而不是一个引用。
    
    
    [root@node01 perl]# cat Luo.pm 
    package Luo;
    sub new {
     my $invocant = shift;
     print "$invocant==$invocant
    ";
     my $class = ref($invocant) || $invocant;
     print "$class==$class
    ";
     my $obj = {
     } ;
     bless $obj, $class;
     return $obj;
    };
    
    sub fun1 {
      my $self=shift;
      print "$self==$self
    ";
      my $a=shift;
      my $b=shift;
      return $a + $b;
    };
    1;
    [root@node01 perl]# cat a4.pl 
    use Luo;
    my $ua=Luo->new();
    my $xx=$ua->new();
    print $ua->fun1(44,33);
    [root@node01 perl]# perl a4.pl 
    $invocant==Luo
    $class==Luo
    $invocant==Luo=HASH(0xdb3160)
    $class==Luo
    $self==Luo=HASH(0xdb3160)
    77[root@node01 perl]# 
    
    
    
    
    
    
    
    
    
    
    12.4.2 初始器:
    
    大多数对象维护的信息是由对象的方法间接操作的,到目前为止我们的所有构造器都创建了空散列,
    
    但是我们没有理由让它们这么空着。
    
    [root@node01 perl]# cat Horse.pm 
    package Horse;
    sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = { @_ }; # 剩下的参数变成属性
    bless($self, $class); # 给予对象性质
    return $self;
    };
    
    sub fun1 {
      my $self=shift;
      print $self->{'name'}."xxxx"."
    ";;
      print $self->{'color'}."yyyy"."
    ";
    };
    1;
    
    [root@node01 perl]# cat a6.pl 
    use Horse;
    my $ua=Horse->new(name => "shadowfax", color => "white");
    $ua->fun1();
    [root@node01 perl]# perl a6.pl 
    shadowfaxxxxx
    whiteyyyy
    
    
    你可以把你的构造器命名为任意的东西,任何碰巧创建和返回一个对象的方法都是实际上的构造器。
    
    
    [root@node01 perl]# cat Horse.pm 
    package Horse;
    sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = {
    color => "bay",
    legs => 4,
    owner => undef,
    @_, # 覆盖以前的属性
    };
    return bless $self, $class;
    };
    sub fun1 {
      my $self=shift;
      print $self->{'name'}."xxxx"."
    ";;
      print $self->{'color'}."yyyy"."
    ";
    };
    1;
    
    
    
    [root@node01 perl]# cat Horse.pm 
    package Horse;
    sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = {
    color => "bay",
    legs => 4,
    owner => undef,
    @_, # 覆盖以前的属性
    };
    return bless $self, $class;
    };
    sub fun1 {
      my $self=shift;
      print $self->{'name'}."xxxx"."
    ";;
      print $self->{'color'}."yyyy"."
    ";
    };
    1;
    
    [root@node01 perl]# cat a6.pl 
    use Horse;
    my $ua=Horse->new(name => "shadowfax", color => "white");
    $ua->fun1();
    [root@node01 perl]# perl a6.pl 
    shadowfaxxxxx
    whiteyyyy
    
    12.5 类继承
    
    对Perl的对象系统剩下的内容而言,从一个类继承另外一个类并不需要给这门语言增加特殊的语法。
    
    当你调用一个方法的时候,如果Perl在调用者的包里找不到这个子过程,
    
    packge Mule;  
    use base ("Horse", "donkey"); # 声明一个超类  
    
    它是下面东西的缩写:  
    package Mule;  
    BEGIN {  
    our @ISA = ("Horse", "Donkey");  
    require Horse;  
    require Donkey;  
    }  
    
    
    
    
    /***************************************************
    [root@node01 zhao]# cat Mule.pm 
    package Mule;
    use base ("Horse", "donkey");
    sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = { @_ }; # 剩下的参数变成属性
    bless($self, $class); # 给予对象性质
    return $self;
    };
    
    sub fun3 {
     my $self=shift;
     my $a=shift;
     my $b=shift;
     return $a + $b +33;
    };
    1;
    
    [root@node01 zhao]# cat Horse.pm 
    package Horse;
    sub fun1 {
      my $self=shift;
      my $a=shift;
      my $b=shift;
      return $a + $b +11;
    
    };
    1
    
    
    [root@node01 zhao]# cat donkey.pm 
    package donkey;
    sub fun2 {
      my $self=shift;
      my $a=shift;
      my $b=shift;
      return $a + $b +22;
    };
    1
    
    
    [root@node01 zhao]# cat a1.pl 
    use  Mule;
    
    my $ua=Mule->new();
    print $ua->fun1(11,22);
    print "
    ";
    print $ua->fun2(11,22);
    print "
    ";
    print $ua->fun3(11,22);
    print "
    ";
    
    
    [root@node01 zhao]# perl a1.pl 
    44
    55
    66
    
    
    
    等价于:
    [root@node01 zhao]# cat Mule.pm
    package Mule;
    BEGIN {  
    our @ISA = ("Horse", "donkey");  
    require Horse;  
    require donkey;  
    }; 
    sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = { @_ }; # 剩下的参数变成属性
    bless($self, $class); # 给予对象性质
    return $self;
    };
    
    sub fun3 {
     my $self=shift;
     my $a=shift;
     my $b=shift;
     return $a + $b +33;
    };
    1;
    [root@node01 zhao]# cat a1.pl 
    use  Mule;
    
    my $ua=Mule->new();
    print $ua->fun1(11,22);
    print "
    ";
    print $ua->fun2(11,22);
    print "
    ";
    print $ua->fun3(11,22);
    print "
    ";
    
    
    [root@node01 zhao]# perl a1.pl 
    44
    55
    66
    
    
    
    
    
    package Mule;
    BEGIN {  
    our @ISA = ("Horse", "donkey");  
    require Horse;  
    require donkey;  
    };
    
    表示 Mule 继承了Horse类和donkey类
    


    
                                        
    
  • 相关阅读:
    HAproxy 1.5 dev14 发布
    IBM/DW 使用 Java 测试网络连通性的几种方法
    Skype 4.1 Linux 发布,支持微软帐号登录
    Dorado 7.1.20 发布,Ajax的Web开发平台
    Aspose.Slides for Java 3.0 发布
    开发版本 Wine 1.5.18 发布
    BitNami Rubystack 开始支持 Ruby 2.0
    XWiki 4.3 正式版发布
    Silverlight实例教程 Out of Browser的Debug和Notifications窗口
    Silverlight实例教程 Out of Browser与Office的互操作
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13350744.html
Copyright © 2011-2022 走看看