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

      对象(上):
    
    对象是一个数据结构,带有一些行为。
    
     如果需要区分上面两种情况, 那么我们就把适用于某一特定对象的方法叫做实例
    方法,而把那些适用于整个类的方法叫做类方法。不过这样做只是为了方便——对于 Perl
    而言,方法就是方法,只是由其第一个参数的类型来区分。
    
    类方法 第一个参数为类
    
    对象方法 第一个参数为对象
    
    类里面那些生成对象实例的方
    法叫构造方法
    
     Perl的对象系统:
    
    一个对象只不过是一个引用...恩,就是引用。
    因为引用令独立的标量代表大量的数据, 所以我们不应该对把引用用于所有对象 感到奇怪。 
    
    
    方法调用:
    不管使用哪种方法调用的形式,Perl 总是会给
    构成这个方法的子过程传递一个额外的初始化参数。
    
    如果用一个类调用该方法, 那个参数将
    会是类的名字。如果用一个对象调用方法,那个参数就是对象的引用。
    
    
    OO 的核心是下面这样简单的逻辑:一旦得知调用者,则可以
    知道调用者的类,而一旦知道了类,就知道了类的继承关系,一旦知道了类的继承关系,那
    么就知道实际调用的子过程了。
    
    
    使用箭头操作符的方法调用:
    
    我们说过有两种风格的方法调用。第一种调用方法的风格看起来象下面这样:
    
    INVOCANT->METHOD(LIST)
    INVOCANT->METHOD
    
    
    当 INVOCANT 是一个
    包的名字的时候,我们把那个被调用的 METHOD 看作类方法。
    
    
    比如,使用类方法 summon 的构造一个类,然后在生成的对象上调用实例方法 speak,
    你可以这么说:
    
    $mage = Wizard->summon("Gandalf"); # 类方法  类方法的参数是类 Wizard
    $mage->speak("friend"); # 实例方法
    
    
    
    使用间接对象的方法调用:
    
    
    间接对象的句法障碍:
    
     引用包的类:
    
    构造对象
    
    可继承构造器:
    
    和所有方法一样, 构造器只是一个子过程, 但是我们不把它看作一个子过程。 在这个例子里,
    我们总是把它当作一个方法来调用——一个类方法, 因为调用者是一个包名字。
    
    
    
    [root@wx03 5]# cat hui.pm 
    package hui;
    
     sub new {
    my $class=shift;
    my $self = { };
    bless ($self, $class);
    return $self;
    };
    
    sub spawn {
    my $invocant = shift;
    print "$invocant is $invocant
    ";
    my $class = ref($invocant) || $invocant; # 对象或者类名字 如果是对象 取类的名字
    print "$class is $class
    ";
    my $self = { };
    bless ($self, $class);
    return $self;
    };
    1;
    [root@wx03 5]# cat a2.pl 
    use hui;
    $ua=hui->new();
    print $ua;
    print "
    ";
    $ua->spawn;
    [root@wx03 5]# perl a2.pl 
    hui=HASH(0xd8d160)
    $invocant is hui=HASH(0xd8d160)
    $class is hui
    
    
    
    
    
    
    
    
    初始器:
    
    sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = { @_ }; # 剩下的参数变成属性
    bless($self, $class); # 给予对象性质
    return $self;
    }
    
    
    更灵活一些,你可以用缺省键字/数值对设置你的构造器,这些参数可以由用户在使用的时
    候通过提供参数而覆盖掉:
    
    [root@wx03 5]# 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;
    };
    1;
    [root@wx03 5]# cat a3.pl 
    use Horse;
    $ed = Horse->new;
    use Data::Dumper;
    $str=Dumper($ed);
    print "$str is $str
    ";
    
    $stallion = Horse->new(color => "black"); # 四腿黑马
    $str=Dumper($stallion);
    print "$str is $str
    ";
    [root@wx03 5]# perl a3.pl 
    $str is $VAR1 = bless( {
                     'owner' => undef,
                     'legs' => 4,
                     'color' => 'bay'
                   }, 'Horse' );
    
    $str is $VAR1 = bless( {
                     'owner' => undef,
                     'legs' => 4,
                     'color' => 'black'
                   }, 'Horse' );
    
    
    当把这个 Horse 构造器当作实例方法使用的时候,它忽略它的调用者现有的属性。
    
    
    任何碰巧创建和返回一个对象的方法都是实际上的构造器
    
    
    perl 把对象转换成散列:
    
    [root@wx03 5]# cat a4.pl 
    use Horse;
    use Data::Dumper;
    
    $steed = Horse->new(color => "dun");
    $str=Dumper($steed);
    print "$str is $str
    ";
    
    print "111111111111
    ";
    print %$steed;
    
    print "
    ";
    
    print "2222222222
    ";
    
    %hash=%$steed;
    print $hash{color};
    print "
    ";
    
    [root@wx03 5]# perl a4.pl 
    $str is $VAR1 = bless( {
                     'legs' => 4,
                     'owner' => undef,
                     'color' => 'dun'
                   }, 'Horse' );
    
    111111111111
    legs4ownercolordun
    2222222222
    dun
    
    
    //**********
    
    sub new {
    my $invocant = shift;
    my $class = ref($invocant) || $invocant;
    my $self = {
    color => "bay",
    legs => 4,
    owner => undef,
    @_, # 覆盖以前的属性
    };
    return bless $self, $class;
    }
    
    
    sub clone {
    my $model = shift;
    my $self = $model->new(%$model, @_);  ##把$model对象转成hash,@_ 是传入的参数 这里是owner => "EquuGen Guild, Ltd."
    
    #$model 作为new的第一个参数,会提取类名
    
    return $self; # 前面被 ->new 赐福过了
    }
    
    
    类继承:
    
    
    Perl 是这样实现继承的:一个包的@ISA 数组里的每个元素都保留另外一个包的名字,
    
    当缺失方法的时候就搜索这些包。
    
    比如,下面的代码把Horse类变成Critter类的子类。
    
    (我们用our声明@ISA,因为它必须是一个包变量,而不能是my声明的词法作用域变量)。
    
    package Horse;
    our @ISA = "Critter";
    
    你现在应该可以在原先Critter使用的任何地方使用Horse类或者对象了。
    
    如果你的新类通过了这样的空子类测试,那么你就可以认为Critter是一个正确的基类,
    
    可以用于继承。
    
    [root@wx03 5]# cat Critter.pm 
    package Critter;  
    sub new {  
        my $self = {};  
        my $invocant = shift;      
    my $class = ref($invocant) || $invocant;  
        my ($name)=@_;      
          my $self = {      
             "name" =>$name      
                     };    
        bless $self, $class; # Use class name to bless() reference  
        return $self;  
      
    };  
      
    sub sum2 {  
           $self=shift;  
           my $a=shift;  
           my $b=shift;  
           return $a + $b;  
    };  
      
      
    sub fun1 {  
           $self=shift;  
           my $a=shift;  
           my $b=shift;  
           return $a / $b;  
    }  
    1;  
    [root@wx03 5]# cat a4.pl 
    use Horse;
    use Data::Dumper;
    
    $steed = Horse->new(color => "dun");
    print $steed->fun1(10,2);
    print "
    ";
    [root@wx03 5]# perl a4.pl 
    5
    
    
    
    
    你现在应该可以在原先 Critter 使用的任何地方使用 Horse 类或者对象了。
    
    
    
    
    
    
    
    
    
    
    

  • 相关阅读:
    记录一次阿里云服务器被攻击的经历
    post字符 特殊字符处理【转】
    forkjoin框架疑问记录
    centos7 安装 maven 和ant git 以及 rocketmq 4.2安装过程(安装成功,调用失败)
    IntelliJ Idea编译报错:javacTask: 源发行版 1.8 需要目标发行版 1.8
    记录一次json转换的经历
    maven项目在idea下右键不出现maven的解决办法
    Mac系统查看端口占用和杀死进程
    委托所想
    win8中的参数传递
  • 原文地址:https://www.cnblogs.com/zhaoyangjian724/p/6199954.html
Copyright © 2011-2022 走看看