View mode: basic / threaded / horizontal-split · Log in · Help
December 01, 2011
Abstract functions in child classes
Ok, starting to feel like I'm missing something obvious...

The abstract keyword in the language reference states:
"Functions declared as abstract can still have function bodies. This
is so that even though they must be overridden, they can still
provide ‘base class functionality.’"

So, "they must be overridden." Does the compiler do *anything* to
verify this for a child class?

This compiles:

   import std.stdio;

   public abstract class Parent {
       public void hasDefinition() {
           writeln("I have a definition");
       }

       public abstract void noDefinition();
   }

   public class Child : Parent {
       public void unRelated() {
           writeln("Unrelated");
       }
   }

   void main() {
       Child child;
   }

However, if I change main() to:

   void main() {
       Parent instance = new Child();
   }

I get "cannot create instance of abstract class Child | function
noDefinition is abstract"

Why is a reference / use of child in the context of a parent
required just to validate that the class is a valid extension of the
parent? More to the point, why does the first case even compile?
December 01, 2011
Re: Abstract functions in child classes
On Thu, 01 Dec 2011 17:50:48 -0000, Adam <Adam@anizi.com> wrote:
> Ok, starting to feel like I'm missing something obvious...

This:

    void main() {
        Child child = new Child;
    }

also produces the (expected) error.  Basically dmd was letting you get  
away with the abstract class because you never instantiated it.

Child child;

is just a reference to a Child class.

You could argue the compiler should error in either case, in fact, I  
would.  But perhaps there is a good generic programming reason not to...  
someone more experienced might be able to shed some light on it.

Regan

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
December 01, 2011
Re: Abstract functions in child classes
I saw that a few minutes after posting as well, but if the only time
it's going to actually check the definition is if I instantiate it,
well... that's not so good for me if I'm writing implementations to be
used at a later date.

Hm. Guess we'll see. :)
December 01, 2011
Re: Abstract functions in child classes
On Thu, 01 Dec 2011 18:50:48 +0100, Adam <Adam@anizi.com> wrote:

> Ok, starting to feel like I'm missing something obvious...
>
> The abstract keyword in the language reference states:
> "Functions declared as abstract can still have function bodies. This
> is so that even though they must be overridden, they can still
> provide �base class functionality.�"
>
> So, "they must be overridden." Does the compiler do *anything* to
> verify this for a child class?
>
> This compiles:
>
>     import std.stdio;
>
>     public abstract class Parent {
>         public void hasDefinition() {
>             writeln("I have a definition");
>         }
>
>         public abstract void noDefinition();
>     }
>
>     public class Child : Parent {
>         public void unRelated() {
>             writeln("Unrelated");
>         }
>     }
>
>     void main() {
>         Child child;
>     }
>
> However, if I change main() to:
>
>     void main() {
>         Parent instance = new Child();
>     }
>
> I get "cannot create instance of abstract class Child | function
> noDefinition is abstract"
>
> Why is a reference / use of child in the context of a parent
> required just to validate that the class is a valid extension of the
> parent? More to the point, why does the first case even compile?

Child is an abstract class because it has abstract methods. One of
these is the original hasDefinition, the other is noDefinition. Child
itself is under no obligation to override them, because there could be
a class GrandChild : Child, which does override them.

Declaring a variable of type Child, where Child is abstract class,
should of course not be an error. That child could be either a Son or
a Daughter (or a transvestite child, I guess, but let's not get too
carried away), both of whom override these abstract methods.

That said, it would be a lot clearer if the language gave an error
when a class with abstract methods is not marked abstract.
December 01, 2011
Re: Abstract functions in child classes
On Thu, 01 Dec 2011 12:58:24 -0500, Regan Heath <regan@netmail.co.nz>  
wrote:

> On Thu, 01 Dec 2011 17:50:48 -0000, Adam <Adam@anizi.com> wrote:
>> Ok, starting to feel like I'm missing something obvious...
>
> This:
>
>      void main() {
>          Child child = new Child;
>      }
>
> also produces the (expected) error.  Basically dmd was letting you get  
> away with the abstract class because you never instantiated it.
>
> Child child;
>
> is just a reference to a Child class.
>
> You could argue the compiler should error in either case, in fact, I  
> would.  But perhaps there is a good generic programming reason not to...  
> someone more experienced might be able to shed some light on it.

A Child reference could be for a further derived GrandChild type that does  
actually implement the required functions.  In fact, Child is also  
abstract, it just isn't required to be marked as such.

All marking a class as abstract does is make it uninstantiable, just like  
having an abstract method does.  However, you can mark a class abstract to  
prevent it from being instantiated, even when none of its methods are  
abstract (could be useful in some situations).

However, I have no idea why you'd mark a concrete function as abstract.   
That seems like a "just because we could" feature.

-Steve
December 01, 2011
Re: Abstract functions in child classes
I can see the case for a grand-child, but if a class does not provide
a definition for an abstract member, is that class not, by
association, abstract?

"Classes become abstract if they are defined within an abstract
attribute, or if any of the virtual member functions within it are
declared as abstract."

I *assume* that by extending Parent, Child inherits the abstract
function. If inheriting an abstract member transitively makes Child an
abstract, then I find that the abstract keyword at the class level is
little more than explicit documentation.
December 01, 2011
Re: Abstract functions in child classes
Because the function in this case has no definition in the base
abstract class (Parent), but is referenced / called by Parent's
members. I did not want Parent to provide a default definition for the
function precisely because a large point of the abstract was that
method.
December 01, 2011
Re: Abstract functions in child classes
On Thu, 01 Dec 2011 19:19:49 +0100, Adam <Adam@anizi.com> wrote:

> I can see the case for a grand-child, but if a class does not provide
> a definition for an abstract member, is that class not, by
> association, abstract?

Of course. That's what I said. Or meant, at any rate.


> "Classes become abstract if they are defined within an abstract
> attribute, or if any of the virtual member functions within it are
> declared as abstract."
>
> I *assume* that by extending Parent, Child inherits the abstract
> function. If inheriting an abstract member transitively makes Child an
> abstract, then I find that the abstract keyword at the class level is
> little more than explicit documentation.

Indeed. But I'm not one to argue that explicit documentation is bad.
December 02, 2011
Re: Abstract functions in child classes
On 2011-12-01 19:18, Steven Schveighoffer wrote:
> On Thu, 01 Dec 2011 12:58:24 -0500, Regan Heath <regan@netmail.co.nz>
> wrote:
>
>> On Thu, 01 Dec 2011 17:50:48 -0000, Adam <Adam@anizi.com> wrote:
>>> Ok, starting to feel like I'm missing something obvious...
>>
>> This:
>>
>> void main() {
>> Child child = new Child;
>> }
>>
>> also produces the (expected) error. Basically dmd was letting you get
>> away with the abstract class because you never instantiated it.
>>
>> Child child;
>>
>> is just a reference to a Child class.
>>
>> You could argue the compiler should error in either case, in fact, I
>> would. But perhaps there is a good generic programming reason not
>> to... someone more experienced might be able to shed some light on it.
>
> A Child reference could be for a further derived GrandChild type that
> does actually implement the required functions. In fact, Child is also
> abstract, it just isn't required to be marked as such.
>
> All marking a class as abstract does is make it uninstantiable, just
> like having an abstract method does. However, you can mark a class
> abstract to prevent it from being instantiated, even when none of its
> methods are abstract (could be useful in some situations).
>
> However, I have no idea why you'd mark a concrete function as abstract.
> That seems like a "just because we could" feature.
>
> -Steve

The method in the super class could provide a partial implementation 
that sub class can call. But that might be better divided in two methods.

-- 
/Jacob Carlborg
December 02, 2011
Re: Abstract functions in child classes
On 2011-12-01 19:14, Simen Kjærås wrote:
> On Thu, 01 Dec 2011 18:50:48 +0100, Adam <Adam@anizi.com> wrote:
>
>> Ok, starting to feel like I'm missing something obvious...
>>
>> The abstract keyword in the language reference states:
>> "Functions declared as abstract can still have function bodies. This
>> is so that even though they must be overridden, they can still
>> provide �base class functionality.�"
>>
>> So, "they must be overridden." Does the compiler do *anything* to
>> verify this for a child class?
>>
>> This compiles:
>>
>> import std.stdio;
>>
>> public abstract class Parent {
>> public void hasDefinition() {
>> writeln("I have a definition");
>> }
>>
>> public abstract void noDefinition();
>> }
>>
>> public class Child : Parent {
>> public void unRelated() {
>> writeln("Unrelated");
>> }
>> }
>>
>> void main() {
>> Child child;
>> }
>>
>> However, if I change main() to:
>>
>> void main() {
>> Parent instance = new Child();
>> }
>>
>> I get "cannot create instance of abstract class Child | function
>> noDefinition is abstract"
>>
>> Why is a reference / use of child in the context of a parent
>> required just to validate that the class is a valid extension of the
>> parent? More to the point, why does the first case even compile?
>
> Child is an abstract class because it has abstract methods. One of
> these is the original hasDefinition, the other is noDefinition. Child
> itself is under no obligation to override them, because there could be
> a class GrandChild : Child, which does override them.
>
> Declaring a variable of type Child, where Child is abstract class,
> should of course not be an error. That child could be either a Son or
> a Daughter (or a transvestite child, I guess, but let's not get too
> carried away), both of whom override these abstract methods.
>
> That said, it would be a lot clearer if the language gave an error
> when a class with abstract methods is not marked abstract.

There's also the possibility to have the declarations in one object file 
and the implementation in another, if I recall correctly. This allows to 
use a .di and .d file, similar to .c and .h in C/C++.

-- 
/Jacob Carlborg
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home