abstract baseClass {
List
List
virtual add(BaseClass class) {
list.Add(class);
if (class.Type is "Two" also do.......)
list_two.Add(class); //here error, because class hasn't same type of list_two...
}
}
class One : baseClass {
override void add(BaseClass class) {
// do something
base.add(class);
}
}
class Two : baseClass{
//constructor and the rest
}
main {
Two two;
One one;
one.add(new two() );
}
Must I have refactor the classes or how can I do this things?
thanks...
AlanPosted Oct 6, 2007, 5:41 PM
Hi Marco,
I built the 'Id' stuff into the code because it's an easy way to keep track of how many objects of a given class have been created and to distinguish between those objects.
'lastId' has to be a static field because this records the total number of objects that have been created so far for the class as a whole. The 'id' instance field records the number of a particular instance.
The code should still work fine when you add a ConcreteNode child node to a ConcreteNode. For example, if you add this line to the Main() method:
concreteNode2.AddChildNode (new ConcreteNode());
the new node (#3) will be listed as a child of ConcreteNode #2. However, the list of children for ConcreteNode #3 itself will, of course, be empty.
MarcoPosted Oct 6, 2007, 4:52 PM
thanks.
AlanPosted Oct 1, 2007, 6:52 AM
Not sure whether it's quite what you want but try this:
using System;
using System.Collections.Generic;
abstract class Node
{
public abstract int Id { get; }
}
class ConcreteNode : Node
{
static List
public static List GetNodes()
{
return list;
}
List childList = new List();
public List GetChildNodes()
{
return childList;
}
static int lastId = 0;
int id;
public override int Id
{
get{ return id; }
}
public ConcreteNode()
{
id = ++lastId;
list.Add(this);
}
public void AddChildNode(Node node)
{
childList.Add(node);
}
}
class ContentNode : Node
{
static int lastId = 0;
int id;
public override int Id
{
get{ return id; }
}
public ContentNode()
{
id = ++lastId;
}
}
class SomeOtherNode : Node
{
static int lastId = 0;
int id;
public override int Id
{
get {return id; }
}
public SomeOtherNode()
{
id = ++lastId;
}
}
class Program
{
static void Main()
{
ConcreteNode concreteNode1 = new ConcreteNode();
concreteNode1.AddChildNode (new ContentNode());
concreteNode1.AddChildNode (new SomeOtherNode());
ConcreteNode concreteNode2 = new ConcreteNode();
concreteNode2.AddChildNode (new ContentNode());
concreteNode2.AddChildNode (new SomeOtherNode());
Console.Clear();
foreach(ConcreteNode parent in ConcreteNode.GetNodes())
{
Console.WriteLine("Child list for ConcreteNode #{0}\n", parent.Id);
int count = 0;
foreach(Node node in parent.GetChildNodes())
{
Console.WriteLine(" Node #{0} is {1} #{2}", ++count, node.GetType(), node.Id);
}
Console.WriteLine();
}
Console.ReadKey();
}
}
MarcoPosted Sep 28, 2007, 2:25 PM
List <Node> child = new List<Node>();
List
virtual add(Node node) {
child.Add(node);
}
}
class NodeContent : Node {
}
}
class ConcreteNode : Node{
override void add(Node node) {
// DO SOMETHING
if (class.Type is "NodeContent" )
base.list_node_content.Add((NodeContent) node);
base.add(node);
}
main {
ConcreteNode concreteNode;
ConcreteNode.appendNode (new NodeContent());
}
As you can see a Node can be or a ConcreteNode (with childs) either a ContentNode (witout childs this last); if I add a ContentNode I want it in the child list and also in the list_node_content. Then could be others node that inherit from Node but they'll be silmilar ContentNode (i.e. without childs);
COuld you refactor this, please?
AlanPosted Sep 28, 2007, 11:59 AM
Generally speaking, it's not a good idea for a base class to rely on code which involves a derived class. This is what you've got here because baseClass depends on its derived class Two.
Also I couldn't see why you'd made baseClass abstract when its only method 'add' is concrete.
If you could explain exactly what you're trying to achieve here, then I might be able to suggest a better design.
With regard to your edit, a derived class can create or reference objects of its base class but there's seldom much point in doing so because it inherits all the base class's members in any case. It follows from this that a derived class's members are a superset of the base class's members and so, when a derived class object is assigned to a base class variable, you do lose something in that you can only access the derived object's inherited members via that variable.
MarcoPosted Sep 28, 2007, 11:33 AM
--EDIT --
the base class can point to a derived class for what I know. But the opposite? Isn't there the danger of lose something to convert base to derived and viceversa?
AlanPosted Sep 28, 2007, 10:51 AM
As the List.Add() method can only accept objects of type Two, you need to cast the baseClass argument to Two, so that the compiler knows the object will be of the right type:
abstract class baseClass{
List list = new List(); list_two=new List();
List
public virtual void add(baseClass obj){
list.Add(obj);
if (obj is Two)
list_two.Add((Two)obj); // cast used here
}
}