Initialize child before parent - do not call parent contructor

房东的猫 提交于 2019-12-25 03:21:34

问题


In MatLab, i have a superclass A that takes some parameters, x and y

classdef A < handle
properties
   x;
   y;
   z;
end
methods
   function this = A(x, y)
      this.x = x;
      this.y = y;
      this.initialize();
   end
   function initialize(this)
      this.z = this.x + this.y;
   end
end
end

The initialize method is supposed to do some initial calculations to fasten computation later.

Now i want to create a child class B of A, with it's own inialization, but B should be initialized before A.

classdef B < A
properties
   p
end
methods
   % B takes another parameter p
   function this = B(p)
      % Since B is a subclass of A, and A takes some parameters we have to 
      % call the constructer of A as the first thing.
      this = this@A([], []);
      this.p = p;
   end
   function initialize(this)
      this.x = this.p(1);
      this.y = this.p(2);
      % This is when initialize of A should be called.
   end
end
end

Basically i just want to initialize B before A, but because the constructer of the parent have to be called as the first thing, i cannot figure out how to do this.

In PHP I would do something like this

class A {
   public function __construct($x, $y) {
      $this->x = $x;
      $this->y = $y;
      $this->initialize();
   }
   public function initialize() {
      $this->z = $this->x + $this->y;
   }
}
class B extends A {
   public function __construct($p) {
      // Does not call the parent constructor.
      $this->p = $p;
      $this->initialize();
   }
   public function initialize() {
      $this->x = $this->p[0];
      $this->y = $this->p[1];
      parent::initialize(); // Now we are ready to initialize A
   }
}

Is there a smart way to design what i want in MatLab? Do i have to give up the inheritance of A in class B?


回答1:


The complication arises since:

If you create a subclass object, MATLAB® calls the superclass constructor to initialize the superclass part of the subclass object. By default, MATLAB calls the superclass constructor without arguments. [src]

You can get around explicitly calling the superclass constructor by wrapping its work in an if-statement dependent on how many arguments it was passed (nargin):

function this = A(x, y)
    if (nargin ~= 0)  % or (nargin == 2) in this case
        this.x = x;
        this.y = y;
        this.initialize();
    end
end

And then B's methods would look like:

function this = B(p)
    this.p = p;
    this.initialize();
end
function initialize(this)
    this.x = this.p(1);
    this.y = this.p(2);
    initialize@A(this);
end

It may just be error in the post, but A's initialize method is referencing undefined variables x and y and not their properties. It should be:

function initialize(this)
    this.z = this.x + this.y;
 end



回答2:


This goes against the principles of OOP. What you are trying to achieve basically rules out that B should be derived from A. From what I can tell, you really want to overload the constructor of A. Either do this using a nargin check in A, or if you really want to have a B for whatever reason, just use: this = this@A(p(1), p(2); in the constructor of B instead, to properly call the constructor of A (and get rid of the property p).

This is how you would simulate to overload the constructor by using nargin:

classdef A < handle
    properties
        x;
        y;
        z;
    end
    methods
        function this = A(x, y)
            if nargin==1 % 'p' was passed as 'x'
                this.x = x(1);
                this.y = x(2);
            else
                this.x = x;
                this.y = y;
            end
            this.initialize();
        end

        function initialize(this)
            this.z = this.x + this.y;
        end
    end
end

This is how you would derive B from A, with a proper call of A's constructor:

classdef B < A
    methods
        function this = B(p)
            this = this@A(p(1), p(2));
        end
    end
end


来源:https://stackoverflow.com/questions/28626730/initialize-child-before-parent-do-not-call-parent-contructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!