0
<?php
  /*
  * class: C_QUESTION_MULTIPLE_CHOICE_SINGLE_ANSWER
  * properties:
  * functions:
  */

  class C_QUESTION_MULTIPLE_CHOICE_SINGLE_ANSWER extends C_QUESTION {
    protected $q_type = 'T_MULTIPLE_CHOICE_SINGLE_ANSWER';

    protected $q_type_info;
    /*
    * $choices:
    * choices['A'] = array(answer = 'Y', description = '')
    * choices['B'] = array(answer = 'N', description = '')
    */      
    protected $choices; 

    public $output_info = '';
    public $count = 0;


    function __construct($q_content, $option = 'load') {
        // call parent's construct function to handle question base class information
        // in parent construct function, it will call parent's load or save function by itself.

        parent::__construct($q_content, $option);
        if (! $this->op_status) {
            // call function failed
            return;
        }   


        // handle multiple choice part
        switch ($option) {    
            case 'save':
            // $option = false, don't call parent::save() function
            // parent construct function will call parent save function
              $this->save($q_content, false); 
              break;
        }
    } // end of construct function

    function save($q_content, $option = true) {
        $this->count++;
        $this->output_info .= '</br>'.$this->count.'</br>';
    } // end of save function


  }

In the above code, the sub-class function save is performed twice. If I don't call parent construct function:

/* don't call parent construct function
        parent::__construct($q_content, $option);
        if (! $this->op_status) {
            // call function failed
            return;
        }  
*/

The function save() will be performed once.

In the parent construct function, the parent class QUESTION will cal it's own save() function. The sub-class C_QUESTION_MULTIPLE_CHOICE_SINGLE_ANSWER override the parent function save(). So in the sub-class construction function, I manually call parent::__construct() function. But I don't why the sub-class save() function is called twice. I debug this by sub-class properties
public $output_info = ''; public $count = 0;

Please help me.

Thanks a lot.

=========================================================================================

I debuged several times after post the above question, found:

parent class QUESTION: __construct() function:

function __construct($q_content, $option = 'load') {
// set the operation status to true. If this operation fails, this will be set to false $this->op_status = true;

switch ($option) {
    case 'load':
      if (!$q_content['qid']) {
        $this->op_status = false;
        drupal_set_message(t('question id :qid not exist. Please contact site administrator!', array(':qid' => $q_content['qid'])), 'error');

        break;
      }

      $this->basic['qid'] = $this->extra['qid'] = $q_content['qid'];
      $this->load($this->basic['qid']);

      break;

    case 'save':
      **//$this->save($q_content);
      self::save($q_content);**

      break;
}       

}

if I use $this->save to call parent itself save function, this statement not only call parent::save function, but also will call sub class::save function. It's very funny and confuse.

If I use self::save statement in the parent class QUESTION, then it won't call sub class::save function.

My question is, since I've already overrided parent::save function in the sub class, I should call parent::save, then call $this->save in the sub-class do something for subclass. Why when I call parent::save, it will perform both parent::save and sub-class::save. It really confuse me.

I tried to find answer in the php manual and internet, but I didn't find the relevant article can make me clear. They only say, self::function() is used for the static member function, and $this->function() is used for other member and function. But my function and member are not static. Or the default function and member are static?

Really appreciate for who can help me.

Thanks a lot.

user28506
  • 3
  • 4

1 Answers1

1

In php OOP, $this-> referrer to the current instant of the class, whereas self:: referrer to the class where self:: is declared.self:: is also use to referrer to static functions and properties.

So, in your case, you have to change the call to your parent's save() function as self::save() within the parent's construct function.

Also, within your child class, you can call $this->save() to call the save function of the child, because you are overriding the parent's save function.you can also use self::save() within the child class.if you want to call parent's save function from a child class then you can use parent::save() in your child class.

No, default functions aren't static.to make them static you have to add static keyword in front of the function declaration.note that you can't declare __construct(),__deconstruct() as static.

Since your functions aren't static, when you referrer to them as self:: you are referring to the current class.it's called Scope Resolution Operator (::). also read this SO answer

Himal
  • 1,351
  • 3
  • 13
  • 28
  • It's really confuse. Say, if I use $this->save in the parent construction function, when I call parent::__construct function, it will perform parent::save and child class::save function. What I expect is when I call parent::__construct function, it only perform parent::save function. – user28506 Apr 28 '14 at 00:15
  • @user28506 If you use `$this->save()` in parent's construct and when you call it as `parent::__construct()` it should only call the overridden method(child's method).can you update the post with the codes you are using to initialize the class and invoke those methods ? also make sure to update the codes of classes to reflect what you have now. – Himal Apr 28 '14 at 00:55