Is this good OOP?

  • Thread starter Thread starter Ward Bekker
  • Start date Start date
W

Ward Bekker

Consider the following class structure:

public class A
{
private X _x;

public X ProperyName { get { return _x;}}

public A()
{
_x = new X();
}
}


public class ASub : A
{
private XSub _xy;

public new XSub ProperyName { get { return base.X as XSub;}}

public ASub() : base()
{
_base.X = new XSub();
}
}

public class X {}
public class XSub: X
{
public string XsubVariable = "hello world";
}


As you can see there is a base class (A) and an derived class (ASub).
They both have a property (PropertyName), only ASub uses a property
type (XSub) derived from type (X), because the XsubVariable isn't
relevant for use by class A.

Although this works, i'm not certain if this is the right way to do
this, as _base.X is set two times, once in the constructor of A, and
once in the constructor ASub.

So, is this good OOP?

Bye,

Ward
 
Ward,

I would say no, only because of the "new" construct. Personally, I
think that it is pretty abhorrent (from a design perspective). I don't like
the fact that it hides the base class definition, and allows me to get
around it with a cast to the base type. Basically, it throws consistency
out the window.

I would not shadow the property with new, rather, I would just have the
PropertyName property be virtual, and keep the field X as type X, only
overriding the constructor in ASub to create an instance of XSub.

In .NET 2.0, I would actually use generics to do this, if I wanted
something more strongly typed, like so:

public class A<T> where T : X, new
{
private X _x;

public A()
{
_x = new T();
}

public T PropertyName { get { return (T) _x }}
}

Hope this helps.
 
public new XSub ProperyName { get { return base.X as XSub;}}

I assume you meant that to be
public new XSub ProperyName { get { return base.ProperyName as XSub;}}

Also, note that as the classes are defined now, ASub.PropertyName (above)
will alwayws return null, as base._x is really a X object and cannot be
transforms into an XSub object.

--
Truth,
James Curran
Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
(note new day job!)
 
James said:
I assume you meant that to be
public new XSub ProperyName { get { return base.ProperyName as XSub;}}

Yes, you're right, another small mistake: the constructor of ASub should
read:

public ASub() : base()
{
base.PropertyName = new XSub();
}

Doesn't change the issue though.
Also, note that as the classes are defined now, ASub.PropertyName (above)
will alwayws return null, as base._x is really a X object and cannot be
transforms into an XSub object.

Yes it can, as class XSub is derived from X. Because the constructor of
ASub sets it with an instance of XSub. This upcast is valid.

Bye,

Ward
 
Ward Bekker said:
public ASub() : base()
{
base.PropertyName = new XSub();
}

This will require a setter on A.PropertyName, which, until the release
of C# 2.0, must have the same visibility ("public") as the getter. And
now, you're creating an X object in the A ctor, then throwing it away and
creating a XSub object to replace it in the ASub ctor. That's messy and
wasteful, and not particularly good OO.

Let's see if we can clean this up a bit:

public class A
{
private X _x;

public X ProperyName { get { return _x;}}


protected A(X x) // only called by this class or subclasses.
{
_x = x;
}

public A() : this(new X())
{
}
}

public class ASub : A
{
private XSub _xy;

public new XSub ProperyName { get { return base.X as XSub;}}

public ASub() : base(new XSub())
{
}
}

Because the constructor of
ASub sets it with an instance of XSub. This upcast is valid.

You're right... I missed the assignment in the ctor..

--
Truth,
James Curran
Home: www.noveltheory.com Work: www.njtheater.com
Blog: www.honestillusion.com Day Job: www.partsearch.com
(note new day job!)
 
Back
Top