2

I understand why this code below doesn't work. That's because convolusion will call Base, not Derived. This code is soooo simple, and have self-referencing. I extended 'self-referencing class' and I stucked with that problem.

class Base
{
    public    int  important_data;
    protected Base child;

    public int sum()
    {
        if(child != null)
        {
            return important_data + child.sum();
        }
        else
        {
            return important_data;
        }
    }
}

class Derived extends Base
{
    public int more_important;

    public int convolusion()
    {
        if(child != null)
        {
            return more_important*important_data + child.convolusion();
        }
        else
        {
            return more_important*important_data;
        }
    }
}

Then, is there any available method to do that?

Phryxia
  • 139
  • 9
  • 1
    How can you be sure that the child will be of Derived type when calling convolusion ? – xlecoustillier Dec 22 '14 at 11:15
  • 1
    `child` don't know about `convolusion()` method. – Braj Dec 22 '14 at 11:16
  • @Braj Well actually I'm working Tree with self referencing class. I want to do some iteration using kind of DFS- And I want to extend original Tree class. And also, there is sentinel with null, so when reached no child it will stop. – Phryxia Dec 22 '14 at 11:20
  • create an empty or abstract method `public int convolusion()` in `Base` class and override in `Derived` class. – Braj Dec 22 '14 at 11:22
  • @X.L.Ant That's the point. I can't sure that is 'Derived'. So I wonder another way. I can't override field of course. – Phryxia Dec 22 '14 at 11:22
  • @Braj Well, that is very straight forward but it seems to spoil capsulize – Phryxia Dec 22 '14 at 11:23
  • @user3811223 You can't be sure, but you can check that at runtime, and process accordingly. – xlecoustillier Dec 22 '14 at 11:24
  • how it will spoil capsulize? please explain a bit more. – Braj Dec 22 '14 at 11:24
  • @Braj You can't feel capsulize in this fool example, but in pratical situation, I heard that inheritance is a way to "Extend" the base class. Base can be extended with any other classes that doesn't contain convolusion(), I think. – Phryxia Dec 22 '14 at 11:31

3 Answers3

2

Or, you can use a generic base class:

class Base<T extends Base> {
    private T child;
    private int importantData;

    Base(T child) {
        this.child = child;
    }

    Base() {
        this(null);
    }

    public int sum() {
        if (child != null && child != this) {
            return importantData + child.sum();
        } else {
            return importantData;
        }
    }

    protected T child() {
        return child;
    }

    protected int importantData() {
        return importantData;
    }
}

class Derived extends Base<Derived> {
    private int moreImportant;

    public int convolusion() {
        if (child() != null && child() != this) {
            return moreImportant * importantData() + child().convolusion();
        } else {
            return moreImportant * importantData();
        }
    }
}

This way you get type safe handling, no casting is needed.

wassgren
  • 18,651
  • 6
  • 63
  • 77
  • That really makes sense with the safety(Especially != this)! But, because I don't know the generic class, I should study more about it. – Phryxia Dec 22 '14 at 12:18
1

You don't show where you initialize the child member. In order to call child.convolusion(), you have to make sure that child is of type Derived, and cast it to Derived.

public int convolusion()
{
    if(child != null && child instanceof Derived)
    {
        Derived d = (Derived) child;
        return more_important*important_data + d.convolusion();
    }
    else
    {
        return more_important*important_data;
    }
}
Eran
  • 387,369
  • 54
  • 702
  • 768
0

You can ensure the type of the child, trying something like:

if(child != null && child instanceof Derived)
{
    return more_important * important_data + ((Derived)child).convolusion();
}
xlecoustillier
  • 16,183
  • 14
  • 60
  • 85