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类
    


    
                                        
    
  • 相关阅读:
    java环境变量配置
    单文档中自定义文件打开对话框和保存对话框
    汇编小知识(二)
    汇编指令
    汇编小知识(一)
    data directory(数据目录)之 引出表
    data directory(数据目录)之 引入表
    PE Header中的Optional Header中的最后一个成员变量data directory(数据目录)
    紧跟在PE Header后面的Section Table(节表)
    PE Header中的OptionalHeader
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13350744.html
Copyright © 2011-2022 走看看