(Probably) easy question about inheritance

Z

Zerex71

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
 
J

Joshua Cranmer

Zerex71 said:
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];

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.
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:

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.
private double x;
private double y;
private double z;

Are these in the Matrix class or Vector class?
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?

Use set/get encapsulation. But no, x, y, and z cannot be aliased to
members of the array.
2. Is there a way that I can avoid duplicating data members between
instances of both classes?

Use protected fields instead of private.
3. Or in inheritance, will I just wind up with six doubles, and have
to deal with it?

Gracious use of protected helps.
 
P

Patricia Shanahan

Joshua Cranmer wrote:
....
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.
....

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
 
F

Frederick Polgardy

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
 
F

Frederick Polgardy

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

}

class Vector extends Matrix {
public int getX() { return getElement(0); }

}


Fred
 
P

Patricia Shanahan

Frederick said:
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


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
 
F

Frederick Polgardy

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?

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
 
P

Patricia Shanahan

Frederick said:
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?

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


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
 
M

Manivannan Palanichamy

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

Its a design issue actually. see,
when I say Vector.x, it automatically reads/writes array[0]. Is this possible?
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;
}
}
 
L

Lew

Manivannan said:
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.

I suggest a few changes to your suggestion:

public class Matrix
{
private double [] array = new double[3];
// change the scope to be protected.
/*
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.
 
R

Roedy Green

Vector class which subclasses from Matrix

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.
 
L

Lasse Reichstein Nielsen

If Vec extends Matrix then Vec has MORE fields and methods than
Matrix.

Not necessarily. It can also have more restrictions.
You might want to think about having Matrix extend Vec.

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
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Roedy said:
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.

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
 
Z

Zerex71

Zerex71wrote:
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];

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.
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:

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.
private double x;
private double y;
private double z;

Are these in the Matrix class or Vector class?
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?

Use set/get encapsulation. But no, x, y, and z cannot be aliased to
members of the array.
2. Is there a way that I can avoid duplicating data members between
instances of both classes?

Use protected fields instead of private.
3. Or in inheritance, will I just wind up with six doubles, and have
to deal with it?

Gracious use of protected helps.


Thanks,
Mike

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
 
Z

Zerex71

Joshua Cranmer wrote:

...> Think carefully before you have a Vector subclass Matrix -- is there

...

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,

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
 
Z

Zerex71

Frederick said:
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.

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


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
 
Z

Zerex71

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

Its a design issue actually. see,> when I say Vector.x, it automatically reads/writes array[0]. Is this possible?

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;

}
}

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
 
Z

Zerex71

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,

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
 
P

Patricia Shanahan

Zerex71 wrote:
....
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.

....

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
 
P

Patricia Shanahan

Patricia said:
Zerex71 wrote:
...
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.


...

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.

....

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
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top