The Artima Developer Community
Sponsored Link

Java Answers Forum
Protected Inner Classes

3 replies on 1 page. Most recent reply: Aug 18, 2004 5:21 AM by Varanasi R Pushpeswar

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 3 replies on 1 page
Steve Schooler

Posts: 17
Nickname: zugzwang
Registered: Aug, 2004

Protected Inner Classes Posted: Aug 9, 2004 3:51 PM
Reply to this message Reply
Advertisement
Having difficulty debugging the following:

pkg1;  public interface I1 { void method1(); }
------------------------------------------  
pkg2:   import pgk1.*;
        public class C2 
        {
            protected int i2 = 2;
            protected class C2Inner1 implements I1
            { 
                public void method1() 
                    { System.out.println("This is C2Inner1.method1."); }
            }
        }
------------------------------------------  
pkg3:   import pgk1.*;
        import pgk2.*;
        class C3 extends C2
        {
            I1 createC2Inner1() 
            { 
                C3 z = new C3();              
                return z.new C2Inner1();                // Line 1
                //  return new C2Inner1();              // Line 2
                //  return new C3.C2Inner1();           // Line 3
                //  return new z.C2Inner1();            // Line 4
            }
            public static void main(String[] args)
            {
                C3 a = new C3();
                a.i2 = 3;                               // Line 5
                I1 x = a.createC2Inner1();
                x.method1();
            }
        }
/*

Line 5 runs okay, which indicates that my understanding of protected is ok.
Lines 1 through 4 all cause the same compile error:

    C2Inner1() has protected access in pkg2.C2.C2Inner1
    
When I change C2Inner1 access to public, Lines 1 through 4 each work okay.
Why can I access i2 but not C2Inner1 (i.e. when both protected)?  Is there
different syntax to handle this specific situation?
    
/*


Kishori Sharan

Posts: 211
Nickname: kishori
Registered: Feb, 2002

Re: Protected Inner Classes Posted: Aug 9, 2004 5:20 PM
Reply to this message Reply
Two things need to be explained to understand the compiler error you are getting.

1. The access modifier supplied by Java compiler for default constructor.

2. Meaning of protected inner class and protected constructor

You may already know both of these. However, I will explain these two things in context of your compiler error.

1. When you define a class then you can have its access modifier as package-level or public for top-level class or private, protected, public or package level for inner class. If you don't specify any constructor for a class (top ort inner) then Java compiler adds a default constructor and the access modifier for the added default constructor is same as the class's access modifier. Therefore, when you defined you class C2 as:

package pkg2: 
  import pgk1.*;
        public class C2 
        {
            protected int i2 = 2;
            protected class C2Inner1 implements I1
            { 
                public void method1() 
                    { System.out.println("This is C2Inner1.method1."); }
            }
        }


then it is same as writing:
package pkg2: 
  import pgk1.*;
        public class C2 
        {
            protected int i2 = 2;
            public C2() {
            }
            protected class C2Inner1 implements I1
            { 
                protected C2Inner() {
                  // Note the protected modifier for this constructor
                }
                public void method1() 
                    { System.out.println("This is C2Inner1.method1."); }
            }
        }



2. The second point to note here is the access to a protected member of a class. A protected member can be accessed inside its descendent or in the same package. Since C2Inner class has protected access, you can use its name i.e. C2Inner anywhere in pkg2 or inside any class which inherits C2. Note that C2Inner class being declared protected gives you access to its name in C3 because C3 extends C2. By the phrase "access to its name", I mean you can declare a reference variable of type C2Inner anywhere inside C3 as;

C2Inner myc2Inner;

So, the above declaration in C3 is fine because C2Inner is inherited by C3 by virtue of its being protected member of C3's ancestor. However, when you try to create an object of C2Inner class then you are trying to use the constructor of C2Inner class. Whether you can use the constructor or not depends on the constructor's access modifier. Since you didn't supply any constructor for C2Inner, its default constructor will have protected modified as shown in above example. Now to write
new C2Inner();

you must have access to C2Inner(), which is C2Inner's constructor. Apply the same logic for accessing the protected member. Since C2Inner() constructor is protected, you can access it only in the same package as pkg2 or in a class, which inherits C2Inner class. Since C2 class satisfies neither of the conditions, you cannot write
new C2Inner(); 

inside C3.

The only way to use the above statement in C3 is to make the C2Inner() constructor public. You may argue that there were some reasons to keep C2Inner protected and so you want to make its constructor public. I don't know your exact requirement. So, I don't want to give you any advice on this one.

However, try this changed definition of C2 and then C3 will compile.
package pkg2;
 
import pkg1.*;
 
public class C2
{
  protected int i2 = 2;
  protected class C2Inner1 implements I1
  {
    
    public C2Inner1() {      
    }
      
     public void method1()  {
      System.out.println("This is C2Inner1.method1."); }
  }
}


To experiment with protected constructor of C2Inner you can also try another way. Don't make any changes in C2 class. That is, leave the default constructor supplied by Java compiler protected. Inside C3, declare an inner class that inherits C2Inner and return an object of that class from C3. This is shown below.
package pkg3;
 
 import pkg1.*;
 import pkg2.*;
 class C3 extends C2
 {
   class C22 extends C2Inner1{
     
   }
   I1 createC2Inner1()
   {
     C3 z = new C3();
     return new C22();                
     //return z.new C2Inner1();                // Line 1
     //  return new C2Inner1();              // Line 2
     //  return new C3.C2Inner1();           // Line 3
     //  return new z.C2Inner1();            // Line 4
   }
   public static void main(String[] args)
   {
     C3 a = new C3();
     a.i2 = 3;                               // Line 5
     I1 x = a.createC2Inner1();
     x.method1();
   }
 }
 


This time C22 was able to access the protected constructor of C2Inner because it inherits C2Inner.

Thanks
Kishori

Steve Schooler

Posts: 17
Nickname: zugzwang
Registered: Aug, 2004

Re: Protected Inner Classes Posted: Aug 13, 2004 9:32 AM
Reply to this message Reply
Thanks for the thorough well written response. Impossible to not understand following your response.

Varanasi R Pushpeswar

Posts: 6
Nickname: ravieswar
Registered: May, 2004

Re: Protected Inner Classes Posted: Aug 18, 2004 5:21 AM
Reply to this message Reply
hi,
the way u have implemented was quite wrong in my opinion.
as in the nested classes, the super class object can never directly creat / assign the object of other..

the way u have implemented is....
class z.....
{
class zz
{
void mth1()
{ }
}
}

z xxx = new z();

xxx.zz.mth1() may be used but u have used like,,,,,

superclassobject.new classname ---> which is wrong isnt it
how could u use in such a way like z.new c2inner1()--> which is a class name which doesnt have '()'.

ok read thoroughly ok===> CR or Daniel Liang
ok dont waste time

Flat View: This topic has 3 replies on 1 page
Topic: Soap Header using Apache soap2.2 Previous Topic   Next Topic Topic: Need Help on order of constructors calls

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use