(Probably) easy question about inheritance

Discussion in 'Java' started by Zerex71, Aug 24, 2007.

  1. Zerex71

    Zerex71 Guest

    Group,

    I'm wondering about the following: Say I have a class called Matrix
    which is essentially an array of three numbers, and I call the data
    member:

    private double array[3];

    to be used for general math matrix operations. However, I am going to
    create a Vector class which subclasses from Matrix, since a vector is
    a matrix. In it, I would like to access three data members:

    private double x;
    private double y;
    private double z;

    1. Is there a way to refer to x, y, and z when using Vector instead of
    array[0..2]? In other words, when I say Vector.x, it automatically
    reads/writes array[0]. Is this possible?
    2. Is there a way that I can avoid duplicating data members between
    instances of both classes?
    3. Or in inheritance, will I just wind up with six doubles, and have
    to deal with it?

    Thanks,
    Mike
     
    Zerex71, Aug 24, 2007
    #1
    1. Advertisements

  2. Typically a matrix uses a two-dimensional array, so it would be private
    double[][]. Even more important, a matrix would have different types
    (complex, double, BigDecimal, float, integer, etc.) so it should be
    generified.
    Even though this quote relates to C++, it's still worth saying:
    "Welcome to the wonderful world of public inheritance, where the
    instincts you've developed in other fields of study -- including
    mathematics -- may not serve you as well as you expect." (Point of
    order: in C++, public inheritance is the same thing as inheritance in Java)

    Think carefully before you have a Vector subclass Matrix -- is there
    anything that a generic matrix can do that a vector can't do? AFAIK, the
    answer is no (well, a transpose of a column vector is a row vector so
    one could make the case that v.transpose().equals(v) should be true, but
    in general usage that is probably not going to be expected), but be
    careful before you make assumptions.
    Are these in the Matrix class or Vector class?
    Use set/get encapsulation. But no, x, y, and z cannot be aliased to
    members of the array.
    Use protected fields instead of private.
    Gracious use of protected helps.
     
    Joshua Cranmer, Aug 24, 2007
    #2
    1. Advertisements

  3. Joshua Cranmer wrote:
    ....
    ....

    If the subsystem involves both matrices and vectors, treating row and
    column vectors as equivalent may not be a good idea. They behave
    differently when interacting with matrix operations.

    For example, for an n by n matrix, m, and a length n vector, v, m*v is
    defined if v is a column vector, but not if it is a row vector.

    It is probably better to take one of two views:

    A. A vector has only one dimension, and is not a matrix. This is
    compatible with having methods to generate a matrix from a vector, or
    turn a row or column of a matrix into a vector.

    B. A vector is a matrix with one dimension equal to 1. In that case, it
    is either a row or a column, depending on which dimension is 1. It
    participates in matrix arithmetic as an n by 1 or a 1 by n matrix.

    Patricia
     
    Patricia Shanahan, Aug 24, 2007
    #3
  4. The most important thing to think about when you're designing
    inheritance (IS-A) relationships is a little guideline called the
    Liskov Substitution Principle. Start by assuming some code that knows
    ONLY about the base class. If you pass an instance of the derived
    class into this code, will its assumptions about the base class hold?
    So, in your example, will code that manipulates a Matrix behave
    correctly (make the correct assumptions, etc.) if a Vector is passed
    in?

    That's the philosophical question.

    It strikes me: if a Vector has 3 dimensions, can it really be said to
    extend a *generic* Matrix if a Matrix can have any number of
    dimensions? A good example of where mathematical IS-A-ness differs
    from programmatic IS-A-ness....

    For your particular question, you can't do what you want with fields,
    but if you have a Matrix accessor getElement(int i), you can provide
    an a Vector accessor getX() that simply delegates to getElement(0):

    class Matrix {
    private int array[];
    public int getElement(int i) { return array; }
    }

    class Vector extends Matrix {
    public int getX() { return array[0]; }
    }

    But again, this strikes me as not being the right fit.

    Fred
     
    Frederick Polgardy, Aug 24, 2007
    #4
  5. Oops.


    Fred
     
    Frederick Polgardy, Aug 24, 2007
    #5


  6. I think you are on the right track with set/get methods rather than
    field access, but isn't an element of a matrix a scalar, not a vector?

    For a mixed vector/matrix system, you could have getRow and getColumn
    that return a vector, and get element that returns an int, double, or
    whatever.

    Patricia
     
    Patricia Shanahan, Aug 24, 2007
    #6
  7. It is; array[] is an array of scalars, and getElement(i) returns
    array.

    But I probably didn't think the example through that well. I've been
    a little sleep-deprived lately. :)

    Fred
     
    Frederick Polgardy, Aug 24, 2007
    #7


  8. As you coded it, yes, your matrix is an array of arrays. However, I
    don't think that is a good representation of the mathematical concept of
    matrix. There is far more row/column symmetry than you seem to be allowing.

    Patricia
     
    Patricia Shanahan, Aug 24, 2007
    #8
  9. Its a design issue actually. see,
    When you want the members Vector.x,y,z 'read from and write into'
    Matrix.array[0,1,2], why should you duplicate them in child class?
    mean, why should you override it?
    If the name x,y,z mandatory in Vector class, then I would suggest this
    design.

    class Matrix
    {
    protected double [] array = new double[3]; // change the scope to be
    protected.
    }

    class Vector extends Matrix
    {
    //use getter and setters to access the parent class vars.
    public double getX()
    {
    return array[0];
    }
    public double getY()
    {
    return array[1];
    }
    public double getZ()
    {
    return array[2];
    }

    public void setX(double x)
    {
    array[0] = x;
    }

    public void setY(double y)
    {
    array[1] = y;
    }
    public void setZ(double z)
    {
    array[2] = z;
    }
    }
     
    Manivannan Palanichamy, Aug 25, 2007
    #9
  10. Zerex71

    Lew Guest

    I suggest a few changes to your suggestion:

    public class Matrix
    {
    private double [] array = new double[3];
    /*
    No, leave it private. This will improve refactoring when you decide an array
    is the wrong type.
    */
    public final double getX()
    {
    return array[0];
    /*
    Indentation is good! Use it. (Spaces, not TABs, for Usenet.)
    */
    }
    public final void setX(double x)
    {
    array[0] = x;
    }
    public final double getY()
    {
    return array[1];
    }
    public final void setY(double y)
    {
    array[1] = y;
    }
    public final double getZ()
    {
    return array[2];
    }
    public final void setZ(double z)
    {
    array[2] = z;
    }
    }

    public class Vector extends Matrix
    {
    }

    It makes more sense to make the implementation private and put the public
    accessor and mutator methods, preferably declared final, in the parent class.
     
    Lew, Aug 26, 2007
    #10
  11. Zerex71

    Roedy Green Guest

    Vector has specific meaning (java.util.Vector) already in Java, only
    loosely related to its meaning in mathematics. I suggest you call
    your new class something else, e.g. Vec so you won't confuse other
    programmers.

    If Vec extends Matrix then Vec has MORE fields and methods than
    Matrix. You might want to think about having Matrix extend Vec.
    I am not at all clear what you are trying to do, so take that just as
    a possible thing to think about, not a recommendation.
     
    Roedy Green, Aug 26, 2007
    #11
  12. Not necessarily. It can also have more restrictions.
    That would not work.

    A vector is, or can be percieved as, a matrix with one row (or column).
    Matrix cannot extend Vec, as not all matrices are vectors

    If anything, you could make the Vector class extend the Matrix class,
    and ensure that the Matrix constructor is only called with 1 as one
    of its dimension arguments.

    I would rather have a separate Vector class with "asRowMatrix" and
    "asColumnMatrix" methods.

    Or perhaps a Vector interface that extends the Matrix interface, but
    has its own implementation optimized for one dimensional data.

    /L
     
    Lasse Reichstein Nielsen, Aug 26, 2007
    #12
  13. packages were invented to solve that.

    It can be rather hard to avoid using classnames already used
    by SUN, Apache etc. - they have grabbed all the good ones.

    Arne
     
    =?ISO-8859-1?Q?Arne_Vajh=F8j?=, Aug 26, 2007
    #13
  14. Zerex71

    Zerex71 Guest

    Joshua,

    1. I want to start simple, and only need three members right now, not
    nine.
    2. I realize I should genericize it by type, but only need doubles for
    the moment.

    Mike
     
    Zerex71, Aug 30, 2007
    #14
  15. Zerex71

    Zerex71 Guest

    Patricia,

    I'd probably go with definition B. A Vector in my case is a special
    form of a matrix. What I also didn't extend my original post to say
    was that I would also subclass a Matrix3x3 from Matrix just as I
    subclassed a Matrix1x3 from Matrix. I have the need to do
    "real" (pure) matrix operations, but saw that in the case of a Vector
    that it is really nothing more than a one-dimensional matrix. My
    question was mainly about whether there was a way to alias the
    underlying members, calling them "array" when accessed via matrix
    and "x,y,z" when accessed via vector.

    Mike
     
    Zerex71, Aug 30, 2007
    #15
  16. Zerex71

    Zerex71 Guest



    Just to reiterate - I made a command decision that my data elements
    will be entirely doubles. I have no need to genericize the Matrix to
    the point where it can hold anything.

    Mike
     
    Zerex71, Aug 30, 2007
    #16
  17. Zerex71

    Zerex71 Guest

    That's the best approach I've seen yet, however, I wanted to have
    explicit x,y, and z in my Vector definition. I wouldn't need them, of
    course, in your solution. I probably shouldn't have them, because "no
    one" should be doing things like MyVector.x = ..., etc.

    Mike
     
    Zerex71, Aug 30, 2007
    #17
  18. Zerex71

    Zerex71 Guest

    Roedy,

    That's a no-go for me on the Vector suggestion. I'm calling them
    Vectors for math purposes because that's what they're called, Java be
    damned. It's not meant to be a collection a la the vector class from
    the STL. It's a math vector, plain and simple.

    Mike
     
    Zerex71, Aug 30, 2007
    #18
  19. Zerex71 wrote:
    ....

    ....

    It is usually a mistake to directly access variables from outside the class.

    If you went with methods, you could provide getX() and setX as part of
    Vector, and array-like access as part of Matrix. You would be free to
    store the data in whatever way made most sense, and to change how the
    data is stored as you develop your system.

    Patricia
     
    Patricia Shanahan, Aug 30, 2007
    #19

  20. ....

    Though I would also add that it is probably a mistake to provide any
    methods in Matrix that treat it as one dimensional. I would expect the
    result of a applying a single index to a Matrix to be a row or column,
    not an element of the Matrix.

    Patricia
     
    Patricia Shanahan, Aug 30, 2007
    #20
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.