inner class scope issues

  • Follow


Hi all,
[SSCCE at end of post]

I don't understand the scope of attributes & methods for an inner
static class. Although I learnt a lot doing the research to write this
message! :-)

I'll describe not only what I don't understand, but also what I came
to understand, so it may be of help to others.

I came upon this while defining a different behavior for each instance
of an enum, using methods and attributes from the enum class. I
encountered strange error messages from the compiler.

I reduced the problem to an SSCCE, distinguishing access to private &
protected, and static & non-static, methods of the enum (see SSCCE).
After that I reproduced the SSCCE replacing the enum with a class with
"public static final" attributes. Finally, I reproduced again the
SSCCE without any anonymous class, using an inner class. To my great
satisfaction, I obtained the same results! :-)

In that way I eliminated one misinderstanding that I had: I had
overlooked the fact that enums with specialized behavior are
implicitely static anonymous classes. This explained the static access
issues, as well as explaining why I had problems accessing private
stuff: I was in an anonymous sub-class, not in the enum class itself.

A google search has shown my problem is more or less described here:
http://stackoverflow.com/questions/581450/static-context-in-enum-definition
(in particular, in mentions the error messages that bothered me
initially)
BTW, I've also read this
http://java.sun.com/docs/books/jls/third_edition/html/classes.html

I'm providing several SSCCEs. One is with enum, the other is the same
without enums, the last one illustrates the same with only a static
inner class.

There remains one question though:
How come I can access a private method of the super-class using
super.method instead of this.method?
I would have thought I shouldn't be able to access it at all...

For those who wonder (I know this NG!), this is the usage I'm after:
I'm defining a simple command-line interface. The commands are
provided as an enum, which has an abstract "execute" method,
implemented (in an anonymous way) by each instance. Of course, some
commands are simple, but others require help from other classes, and
that's where I started having problems.
The advantage is that I can use all enum utilities, and also that
adding a new command is one step (no switch to modify).

Here's an idea of the code:
public enum MyCommand {
    doSomething {
        public void execute() {
            // ... do something
        }
    },
    doOtherwise {
        public void execute() {
            // ... do otherwise
        }
    };
    public abstract void execute();
}

Does anyone else use enumerates with behavior to implement command-
line interfaces?
Most examples I've seen use enums for command-line instructions... but
still do a switch. This seems like a shame, when it's possible to
directly code the behavior into the enum!
(in general I tend to regard switching as an bad thing, because it can
be replaced with specialized behavior, aka overriding)

SSCCE (3 of 'em!):
===================================
package enumTests;

/**
 * compiler error:
 * "The method somePrivateMethod() from the type MyPeople is not
 * visible"
 *
 * previous compile error (for attribute):
 * "Cannot make a static reference to the non-static field
 * somePrivateAttribute"
 * previous compile error (for method):
 * "Cannot make a static reference to the non-static method
 * somePrivateMethod() from the type EnumTests"
 */
public enum MyPeople {
    bob {
        private void bobsJob() {
            somePrivateStaticMethod();
            this.somePrivateMethod(); // compile error
            super.somePrivateMethod(); // works fine!
            this.someProtectedMethod();
        }
    };
    private void somePrivateMethod() {}
    static private void somePrivateStaticMethod() {}
    protected void someProtectedMethod() {}
}
===================================
package enumTests;

public class NotAnEnum {
    public static final NotAnEnum bob = new NotAnEnum() {
        private void bobsJob() {
            somePrivateStaticMethod();
            this.somePrivateMethod(); // compile error
            super.somePrivateMethod(); // works fine!
            this.someProtectedMethod();
        }
    };
    private void somePrivateMethod() {}
    static private void somePrivateStaticMethod() {}
    protected void someProtectedMethod() {}
}
===================================
package enumTests;

public class SomeSuperClass {

    public static class SomeInnerClass extends SomeSuperClass {
        private void someInnerMethod() {
            somePrivateStaticMethod();
            this.somePrivateMethod(); // compile error
            super.somePrivateMethod(); // works fine!
            this.someProtectedMethod();
        }
    }
    private void somePrivateMethod() {}
    static private void somePrivateStaticMethod() {}
    protected void someProtectedMethod() {}
}
0
Reply julien.robinson2 (36) 3/23/2009 2:28:44 PM

jrobinss wrote:
> There remains one question though:
> How come I can access a private method of the super-class using
> super.method instead of this.method?
> I would have thought I shouldn't be able to access it at all...

� 6.6.1:
Otherwise, if the member or constructor is declared private, then access 
is permitted if and only if it occurs within the body of the top level 
class (�7.6) that encloses the declaration of the member or constructor.

You can't do the this.method because the subclass doesn't have a copy of 
the private method, as private methods are not inherited.

> For those who wonder (I know this NG!), this is the usage I'm after:
> I'm defining a simple command-line interface. The commands are
> provided as an enum, which has an abstract "execute" method,
> implemented (in an anonymous way) by each instance. Of course, some
> commands are simple, but others require help from other classes, and
> that's where I started having problems.

I think my current option setup uses service providers.

-- 
Beware of bugs in the above code; I have only proved it correct, not 
tried it. -- Donald E. Knuth
0
Reply Pidgeot18 (1393) 3/23/2009 3:02:53 PM


jrobinss wrote:
> Hi all,
> [SSCCE at end of post]
> 
> I don't understand the scope of attributes & methods for an inner
> static class. Although I learnt a lot doing the research to write this
> message! :-)


I followed the previous conversation and I learned a lot also.  I hadn't 
really consider that enums might be a static class.  Wild, but 
apparently true.

However, I think there's still one little thing you are hung up on. 
Taking your last SSCCE:


> package enumTests;
> 
> public class SomeSuperClass {
> 
>     public static class SomeInnerClass extends SomeSuperClass {
>         private void someInnerMethod() {
>             somePrivateStaticMethod();
>             this.somePrivateMethod(); // compile error
>             super.somePrivateMethod(); // works fine!
>             this.someProtectedMethod();
>         }
>     }
>     private void somePrivateMethod() {}
>     static private void somePrivateStaticMethod() {}
>     protected void someProtectedMethod() {}
> }


Now compare with this:


public class SomeSuperClass {

     private void somePrivateMethod() {}

     static class StaticNested {
         public void staticNestedMethod( SomeSuperClass x ) {
             x.somePrivateMethod();
         }
     }
     class InnerClass {
         public void innerMethod() {
             somePrivateMethod();
         }
     }
     class InnerChildClass extends SomeSuperClass {
         public void innerMethod() {
             somePrivateMethod();
         }
     }
     static class StaticNestedChildClass extends SomeSuperClass {
         public void staticNestedMethod() {
             super.somePrivateMethod();
         }
     }
}

First, all nested (inner classes and static nested classes) have access 
to all private members of their enclosing class.  This means variables 
as well as methods.  So where I've written somePrivateMethod() I could 
have just as easily put a variable from SomeSuperClass.

The first class, StaticNested, accesses somePrivateMethod through an 
instance of SomeSuperClass.  Note that this is ANY instance, not just an 
enclosing one.  Static classes have no enclosing instance, they're 
really just two disjoint classes in every way, except that they can 
access each other's private members (sounds naughty, eh?).  This is a 
lot like the friend keyword in C++.  Something to keep in mind.

The second class, InnerClass, just accesses somePrivateMethod(). It uses 
no qualifiers.  Normal scope resolution rules means that the compiler 
first checks InnerClass for any matching methods, and finding none 
proceed outwards to SomeSuperClass, where it finds the match.  This 
could cause confusing if field or method names where close in spelling 
between an InnerClass and it's outer class.  I prefer to design the 
names so they are different enough that no confusion occurs.

Next, look at InnerChildClass.  Again, no qualifiers are needed. 
somePrivateMethod is in scope, and can be called directly without 
resorting to the super keyword.

Finally, observe that the StaticNestedChildClass follows much the same 
pattern as InnerChildClass.  I do find it surprising that super is 
allowed here.  However, since the private method is in scope (just like 
the above three examples) I don't think it should be too surprising.

You can add super to the method call in InnerChildClass:

     class InnerChildClass extends SomeSuperClass {
         public void innerMethod() {
             super.somePrivateMethod();
         }
     }

And this changes nothing.  The "super" is redundant.  For 
StaticNestedChildClass, the super is required, but otherwise the pattern 
is the same.  It's a bit like adding "this" whenever a class calls its 
own instance methods: redundant, but the compiler accepts it.


Anyway, hopefully approaching it from this direction has helped out 
somebody besides me. :)
0
Reply markspace (954) 3/23/2009 3:25:15 PM

jrobinss wrote:
>> I don't understand the scope of attributes & methods for an inner
>> static class. Although I learnt a lot doing the research to write this
>> message! :-)
>

There is no such thing in Java as an "inner static class".
JLS s. 8.5.2
<http://java.sun.com/docs/books/jls/third_edition/html/
classes.html#8.5.2>
> The static keyword may modify the declaration of a member
> type C within the body of a non-inner class T. Its effect
> is to declare that C is not an inner class.
>

Mark Space wrote:
> I followed the previous conversation and I learned a lot also. =A0I hadn'=
t
> really consider that enums might be a static class. =A0Wild, but
> apparently true.
>

JLS s. 8.9:
<http://java.sun.com/docs/books/jls/third_edition/html/
classes.html#8.9>
> Nested enum types are implicitly static. It is permissable [sic]
> to explicitly declare a nested enum type to be static.
>

Mark Space wrote:
> First, all nested (inner classes and static nested classes) have access
> to all private members of their enclosing class. =A0This means variables
> as well as methods. ...
>

There is a subtle consequence of this that came up in another thread.
Consider an inner class that extends its outer class, as it might if
the outer class is abstract with a factory method.  An inner-class
method with the same signature as one in its inherited containing
class only overrides the outer/super method if the outer/super method
has at least package-private access.  If the outer method has private
access, the inner method does not override it.

--
Lew
0
Reply lew (2143) 3/23/2009 4:28:16 PM

Lew wrote:

> There is a subtle consequence of this that came up in another thread.
> Consider an inner class that extends its outer class, as it might if
> the outer class is abstract with a factory method.  An inner-class
> method with the same signature as one in its inherited containing
> class only overrides the outer/super method if the outer/super method
> has at least package-private access.  If the outer method has private
> access, the inner method does not override it.


That is a good point.  But it also makes sense, I think.  Private 
methods are never overridden by child classes.  It's good to know that 
using an inner class doesn't create a loop-hole in this rule.  There 
could be some bad (thread-safety) consequences if inner classes broke 
the rule.


0
Reply markspace (954) 3/23/2009 4:37:18 PM

Lew wrote:
> There is a subtle consequence of this that came up in another thread.
> Consider an inner class that extends its outer class, as it might if
> the outer class is abstract with a factory method.  An inner-class
> method with the same signature as one in its inherited containing
> class only overrides the outer/super method if the outer/super method
> has at least package-private access.  If the outer method has private
> access, the inner method does not override it.

You're right, this is subtle.  The rule is

    1. Private methods are not virtual and thus can't be overridden.

It's somewhat tempting to think that the rule is

    2. Private methods are not visible to descendent classes and thus can't 
be overridden.

The fact that inner and nested classes, which *can* see the private methods, 
still can't override them demonstrates that the correct rule is 1, not 2. 


0
Reply mscottschilling (1976) 3/24/2009 2:10:55 AM

Mike Schilling wrote:
> Lew wrote:
>> There is a subtle consequence of this that came up in another thread.
>> Consider an inner class that extends its outer class, as it might if
>> the outer class is abstract with a factory method.  An inner-class
>> method with the same signature as one in its inherited containing
>> class only overrides the outer/super method if the outer/super method
>> has at least package-private access.  If the outer method has private
>> access, the inner method does not override it.
> 
> You're right, this is subtle.  The rule is
> 
>     1. Private methods are not virtual and thus can't be overridden.
> 
> It's somewhat tempting to think that the rule is
> 
>     2. Private methods are not visible to descendent classes and thus can't 
> be overridden.
> 
> The fact that inner and nested classes, which *can* see the private methods, 
> still can't override them demonstrates that the correct rule is 1, not 2. 

The exact statement in the JLS, s. 8.2, is
> Members of a class that are declared private are not inherited 
> by subclasses of that class. Only members of a class that are 
> declared protected or public are inherited by subclasses 
> declared in a package other than the one in which the class is 
> declared.
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.2>

Also, s. 8.4.8.1
<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.8.1>

Your summary (#1) is accurate and succinct.

-- 
Lew
0
Reply noone7 (3512) 3/24/2009 4:07:42 AM

On Mon, 23 Mar 2009 07:28:44 -0700 (PDT), jrobinss
<julien.robinson2@gmail.com> wrote, quoted or indirectly quoted
someone who said :

>I don't understand the scope of attributes & methods for an inner
>static class. Although I learnt a lot doing the research to write this
>message! :-)

see http://mindprod.com/jgloss/nestedclasses.html
http://mindprod.com/jgloss/scope.html
-- 
Roedy Green Canadian Mind Products
http://mindprod.com

"Nature provides a free lunch, but only if we control our appetites."
~ William Ruckelshaus, America�s first head of the EPA
0
Reply see_website (4858) 3/24/2009 5:36:34 AM

Thanks for the long answer, thanks also to Lew. To summarize, the only
question that remained was:
How come I can call a method with super.method() when it's private in
the superclass?
(I had never seen before an access difference between super.method()
and this.method())

Here are my thoughts on the subject...

> public class SomeSuperClass {
>
>     public static class SomeInnerClass extends SomeSuperClass {
>        private void someInnerMethod() {
>            somePrivateStaticMethod();

This works because it's in a static context, so all is ok, and it's a
nested class calling a private member, which is also ok.

>            this.somePrivateMethod(); // compile error

This doesn't work because it's trying to reach a private method of the
superclass *as though it were inherited*, which it is not. The method
being private, it can't be accessed by a subclass. Of course, the
result is the same without "this.".
(note: there's no overriding here)
More discussion about this case later.

>            super.somePrivateMethod(); // works fine!

This is the interesting part.

This is ok because...
#1) we need access: SomeInnerClass is a nested class, so access to
private members is ok
#2) we need an instance, because the method is not static (and the
nested class is static): we have super, which is an instance.
So we see that if it wasn't a subclass *and* nested, this wouldn't
work.

I think what gets me wondering is that to understand this, I need to
see SomeInnerClass not as "being a" SomeSuperClass (which is the OO
way of thinking generally advocated), but rather see SomeInnerClass
has having a pointer, called "super", to an instance of
SomeSuperClass.

Let's say it differently: I used to see a subclass as "being a"
superclass, but with no access to superclass's private members. If I
keep this point of view, the access should be ok because it's nested.
So I need to see a subclass as being a superclass, but *without* the
superclass's private members (not with them but with no access). Which
is quite different.

This makes it work out: this.somePrivateMethod() is not ok, because
although I could call somePrivateMethod() on SomeSuperClass, the
method doesn't exist in SomeInnerClass, and being nested doesn't
change anything about its existence.

Note that this works:
  ((SomeSuperClass)this).somePrivateMethod(); // works fine!

I'm still left wondering if the compiler couldn't have said ok for
this.somePrivateMethod()... #1 and #2 above are both true after all,
I've got an instance, and I've got access to this method because of
nesting.

Still pondering...
--
JRobinss
0
Reply julien.robinson2 (36) 3/24/2009 2:46:03 PM

Joshua Cranmer answered
> jrobinss wrote:
> > There remains one question though:
> > How come I can access a private method of the super-class using
> > super.method instead of this.method?
> > I would have thought I shouldn't be able to access it at all...
>
> =A7 6.6.1:
> Otherwise, if the member or constructor is declared private, then access
> is permitted if and only if it occurs within the body of the top level
> class (=A77.6) that encloses the declaration of the member or constructor=
..
>
> You can't do the this.method because the subclass doesn't have a copy of
> the private method, as private methods are not inherited.

This doesn't answer the question: why *can* I access it with
super.method()?

> > For those who wonder (I know this NG!), this is the usage I'm after:
> > I'm defining a simple command-line interface. [...]
>
> I think my current option setup uses service providers.

I have no idea what this means. :-)
(what do you mean by service providers?)

--
JRobinss
0
Reply julien.robinson2 (36) 3/24/2009 2:46:46 PM

jrobinss wrote:
> Thanks for the long answer, thanks also to Lew. To summarize, the 
> only
> question that remained was:
> How come I can call a method with super.method() when it's private 
> in
> the superclass?
> (I had never seen before an access difference between super.method()
> and this.method())

The access doesn't differ at all.  The point is that the private 
method isn't a member of the subclass, but is a member of the 
superclass.  Conside the following:

class HasInner
{
    private String className;

    HasInner()
    {
        className = "HasInner";
    }

    HasInner(String cn)
    {
        className = cn;
    }

    public static void main(String[] args)
    {
        IsInner ii = new HasInner().new IsInner();
        ii.doStuff();
    }

    private void method()
    {
        System.out.println(className);
    }

    class IsInner extends HasInner
    {
        IsInner()
        {
            super("IsInner");
        };

        void doStuff()
        {
            method();
            //this.method();
            super.method();
            HasInner.this.method();
        }
    }
}



The output from running this is

HasInner
IsInner
HasInner

The first and third calls use the special access to call the private 
method "method" on "this".  The second call calls use the special 
access to call the private method "method" on the containing instance. 
The way to think of "super" is that it it's the same reference as 
"this", but it tells the compiler to resolve field and method access 
as if it were an instance of the superclass.  Except in this odd case 
of nested classes, "super" can't access private superclass members, 
but neither could any other reference to the superclass. 


0
Reply mscottschilling (1976) 3/24/2009 3:15:28 PM

jrobinss wrote:
> This doesn't answer the question: why *can* I access it with
> super.method()?

Why wouldn't you be able to? The use of |super| in the method call is 
about the selection of the class in the name lookup; in this case, it's 
saying, "I want to call the enum's method()." Since you have the access 
to do so, the compiler doesn't complain.

>> I think my current option setup uses service providers.
> 
> I have no idea what this means. :-)
> (what do you mean by service providers?)

java.util.ServiceLoader.


-- 
Beware of bugs in the above code; I have only proved it correct, not 
tried it. -- Donald E. Knuth
0
Reply Pidgeot18 (1393) 3/24/2009 3:21:55 PM

jrobinss wrote:
> How come I can call a method with super.method() when it's private in
> the superclass?

Because 'super' means "get at the members through my core that is of
the super-type."  Nested classes have access to outer private members,
so the 'super' invocation works.  What the nested class instance is
accessing is *its own* code for 'method()', not some other instance's.

> Here are my thoughts on the subject...
>
>> public class SomeSuperClass {
>
>> =A0 =A0 public static class SomeInnerClass extends SomeSuperClass {

It is contradictory to name a static nested class with the word
"Inner".  In Java, "inner classes" are non-static member classes.

>> =A0 =A0 =A0 =A0private void someInnerMethod() {
>> =A0 =A0 =A0 =A0 =A0 =A0somePrivateStaticMethod();
>
> This works because it's in a static context, so all is ok, and it's a
> nested class calling a private member, which is also ok.
>

Correct.

>> =A0 =A0 =A0 =A0 =A0 =A0this.somePrivateMethod(); // compile error
>
> This doesn't work because it's trying to reach a private method of the
> superclass *as though it were inherited*, which it is not.
>

Correct.

> The method being private, it can't be accessed by a subclass.
>

Wrong.  It can be accessed if the subclass is nested, as it is here.

> Of course, the result is the same without "this.".

Wrong, sort of.  The reason it fails without 'this' is that the method
call does not have an owning instance.

>> =A0 =A0 =A0 =A0 =A0 =A0super.somePrivateMethod(); // works fine!
>
> This is the interesting part.
>
> This is ok because...
> #1) we need access: SomeInnerClass is a nested class, so access to
> private members is ok

Correct.

> #2) we need an instance, because the method is not static (and the
> nested class is static): we have super, which is an instance.

Not completely correct.  'super' is this instance, not just any
instance.  'super' means "'this' taken as an instance of the
supertype".

> So we see that if it wasn't a subclass *and* nested, this wouldn't
> work.
>
> I think what gets me wondering is that to understand this, I need to
> see SomeInnerClass not as "being a" SomeSuperClass (which is the OO
> way of thinking generally advocated), but rather see SomeInnerClass
> has having a pointer, called "super", to an instance of
> SomeSuperClass.
>

Not really.  It's not "an instance", it's "this instance".

> Let's say it differently: I used to see a subclass as "being a"
> superclass, but with no access to superclass's private members.
>

A subtype still "is-a" supertype.  It is also still true that a nested
subtype does not inherit its supertype's private members.

> If I keep this point of view, the access should be ok because it's nested=
..
> So I need to see a subclass as being a superclass, but *without* the
> superclass's private members (not with them but with no access).

Not true.  The subclass still does have those private superclass
members, it just doesn't inherit them.

The question of access to private members of an outer class is
orthogonal to inheritance, unrelated.

> This makes it work out: this.somePrivateMethod() is not ok, because
> although I could call somePrivateMethod() on SomeSuperClass, the
> method doesn't exist in SomeInnerClass, and being nested doesn't
> change anything about its existence.
>

Wrong.  The method does exist in the misnamed 'SomeInnerClass'.

> Note that this works:
> =A0 ((SomeSuperClass)this).somePrivateMethod(); // works fine!
>

That's semantically equivalent to calling 'super.somePrivateMethod()'.

> I'm still left wondering if the compiler couldn't have said ok for
> this.somePrivateMethod()...
>

No.

> #1 and #2 above are both true after all, I've got an instance,
> and I've got access to this method because of nesting.
>

Not enough.  You need inheritance, which does not apply to private
members.

--
Lew
0
Reply lew (2143) 3/24/2009 3:59:42 PM

Joshua Cranmer answered me:
> java.util.ServiceLoader.

Oh I see, "since Java 6".

I'm with Java 5 (which often leads to an ob-question around these
parts :-) )

Thanks for the tip anyway! I'll look into it. For the time being, I
had written myself my own utility CLI class, just to do the output-
input and also the "help" and "exit" commands.

--
JRobinss
0
Reply julien.robinson2 (36) 3/25/2009 9:14:32 AM

Thanks for taking time to answer, Lew. Even though I must say I'm
still struggling.

Lew answered:
> >> =A0 =A0 public static class SomeInnerClass extends SomeSuperClass {
>
> It is contradictory to name a static nested class with the word
> "Inner". =A0In Java, "inner classes" are non-static member classes.

I know, and I expected your remark. But I wanted to stay consistent
with my first (erroneous) SSCCE.

> > Of course, the result is the same without "this.".
>
> Wrong, sort of. =A0The reason it fails without 'this' is that the method
> call does not have an owning instance.

This is subtly misleading (I didn't say incorrect, mind you!).
You don't have an instance when you're in a static context. Here there
is an instance which is "this", because the method is not static (even
though the nested class is).
Only, the present instance is an instance of the subclass.
I said your remark wasn't incorrect; indeed, the method doesn't have
an "owning instance" because this particlar instance does not own the
method... but I just wanted to point out the difference with "no
instance at all".
You know, to keep things clear for all the lurkers. :-)

> > #2) we need an instance, because the method is not static (and the
> > nested class is static): we have super, which is an instance.
>
> Not completely correct. =A0'super' is this instance, not just any
> instance. =A0'super' means "'this' taken as an instance of the
> supertype".

Yes, I expected to be corrected on this. After writing this I tried
out the explicit cast version below, just to verify to myself that I
was going down the wrong path. But I was searching for different
mindsets.

The correct mindset seems to be to think about inheritance of private
members. So, to reformulate...
> super.somePrivateMethod(); // works fine!
works because we are first accessing an instance of the nesting class,
then calling a private method upon it.
> somePrivateMethod(); // compiler error
doesn't work because we're calling a method that doesn't exist ("this"
does not have this method, so this.somePrivateMethod() doesn't exist).

If this is correct, it means that the compiler error is misleading: it
speaks about an access issue, which taken at face value should be
resolved by nesting. I suppose the compiler simply provides the most
helpful message it can, and the scope-based message is generally the
most helpful.
In this particular case, it's not that helpful to say "you can't
access a private member" when on every other line you are! :-)

> > If I keep this point of view, the access should be ok because it's nest=
ed.
> > So I need to see a subclass as being a superclass, but *without* the
> > superclass's private members (not with them but with no access).
>
> Not true. =A0The subclass still does have those private superclass
> members, it just doesn't inherit them.

That doesn't help me. It's got them, but doesn't inherit them???
Confusing.
Either a class has a method, or it doesn't.
If it doesn't declare a method, the only way to have it is by
inheritance.

OTOH, it may be just a question of words. Do we really care if some
say...
"it doesn't have a method"
....and others say...
"it has a method but doesn't declare it and can't access it"?

> The question of access to private members of an outer class is
> orthogonal to inheritance, unrelated.

Well, that's more or less what the whole thread is about. :-)

--
JRobinss
0
Reply julien.robinson2 (36) 3/25/2009 9:44:10 AM

Lew answered:
>> Not true.  The subclass still does have those private superclass
>> members, it just doesn't inherit them.

jrobinss wrote:
> That doesn't help me. It's got them, but doesn't inherit them???

Correct.

> Confusing.

But correct.

> Either a class has a method, or it doesn't.

Correct.

> If it doesn't declare a method, the only way to have it is by
> inheritance.

Incorrect.

> OTOH, it may be just a question of words.

It's just a question of words that either accurately describe reality or don't.

> Do we really care if some say...
> "it doesn't have a method"
> ...and others say...
> "it has a method but doesn't declare it and can't access it"?

Yes.  It's a difference that accounts for observed behavior.

If the nested subclass instance didn't have the method, then it wouldn't be 
able to invoke 'super.method()'.  If it inherited the method, then it would be 
able to invoke 'this.method()'.

-- 
Lew
0
Reply noone7 (3512) 3/25/2009 1:14:30 PM

Lew wrote:
>> If it doesn't declare a method, the only way to have it is by
>> inheritance.
>
> Incorrect.

Here's another semi-obscure case (not compiled, so forgive any typos)

    interface Persistent
    {
            Persistent read(InputStream strm);
            void write(OutputStream strm);
    }

    abstract class DocumentBase implements Persistent
    {
        protected void writeToFile(String fname) throws IOException
        {
            FileOutputStream fos = new FileOutputStream(fname);
            try
            {
                write(fos);
            }
            finally
            {
                fos.close();
            }
    }

Observe that DocumentBase has the abstract methods read and write just 
as if it had explicitly declared them or inherited them from a 
superclass.  Obviously, it "inherited" them from the interface, but 
that's not usually how we use that word.
 


0
Reply mscottschilling (1976) 3/25/2009 3:17:59 PM

On Mar 25, 11:17=A0am, "Mike Schilling" <mscottschill...@hotmail.com>
wrote:
> Lew wrote:
> >> If it doesn't declare a method, the only way to have it is by
> >> inheritance.
>
> > Incorrect.
>
> Here's another semi-obscure case (not compiled, so forgive any typos)
>
> =A0 =A0 interface Persistent
> =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 Persistent read(InputStream strm);
> =A0 =A0 =A0 =A0 =A0 =A0 void write(OutputStream strm);
> =A0 =A0 }
>
> =A0 =A0 abstract class DocumentBase implements Persistent
> =A0 =A0 {
> =A0 =A0 =A0 =A0 protected void writeToFile(String fname) throws IOExcepti=
on
> =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 FileOutputStream fos =3D new FileOutputStream(fna=
me);
> =A0 =A0 =A0 =A0 =A0 =A0 try
> =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 write(fos);
> =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 =A0 =A0 =A0 =A0 finally
> =A0 =A0 =A0 =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 fos.close();
> =A0 =A0 =A0 =A0 =A0 =A0 }
> =A0 =A0 }
>
> Observe that DocumentBase has the abstract methods read and write just
> as if it had explicitly declared them or inherited them from a
> superclass. =A0Obviously, it "inherited" them from the interface, but
> that's not usually how we use that word.

Yes, it is actually.  It is precisely how we use that word.

--
Lew
0
Reply lew (2143) 3/25/2009 3:20:49 PM

Mike Schilling wrote:
> > Observe that DocumentBase has the abstract methods read and write just
> > as if it had explicitly declared them or inherited them from a
> > superclass. =A0Obviously, it "inherited" them from the interface, but
> > that's not usually how we use that word.
>

Lew wrote:
> Yes, it is actually. =A0It is precisely how we use that word.

JLS s. 8.2
<http://java.sun.com/docs/books/jls/third_edition/html/
classes.html#8.2>
> The members of a class type are all of the following: ...
> Members inherited from any direct superinterfaces (=A78.1.5)

Where s. 8.1.5 tells us:
> the direct superinterfaces of the class type (=A74.5) C<F1,...,Fn> are th=
e
> types given in the implements clause of the declaration of C if an
> implements clause is present.

--
Lew
0
Reply lew (2143) 3/25/2009 3:32:32 PM

Lew wrote:
> Mike Schilling wrote:
>>> Observe that DocumentBase has the abstract methods read and write
>>> just as if it had explicitly declared them or inherited them from 
>>> a
>>> superclass. Obviously, it "inherited" them from the interface, but
>>> that's not usually how we use that word.
>>
>
> Lew wrote:
>> Yes, it is actually. It is precisely how we use that word.
>
> JLS s. 8.2
> <http://java.sun.com/docs/books/jls/third_edition/html/
> classes.html#8.2>
>> The members of a class type are all of the following: ...
>> Members inherited from any direct superinterfaces (�8.1.5)

Yes, it's how the word is used *there*.


0
Reply mscottschilling (1976) 3/25/2009 4:23:46 PM

On Mar 25, 12:23=A0pm, "Mike Schilling" <mscottschill...@hotmail.com>
wrote:
> Lew wrote:
> > Mike Schilling wrote:
> >>> Observe that DocumentBase has the abstract methods read and write
> >>> just as if it had explicitly declared them or inherited them from
> >>> a
> >>> superclass. Obviously, it "inherited" them from the interface, but
> >>> that's not usually how we use that word.
>
> > Lew wrote:
> >> Yes, it is actually. It is precisely how we use that word.
>
> > JLS s. 8.2
> > <http://java.sun.com/docs/books/jls/third_edition/html/
> > classes.html#8.2>
> >> The members of a class type are all of the following: ...
> >> Members inherited from any direct superinterfaces (=A78.1.5)
>
> Yes, it's how the word is used *there*.

To start with.

--
Lew
0
Reply lew (2143) 3/25/2009 6:37:13 PM

20 Replies
25 Views

(page loaded in 0.284 seconds)


Reply: