Thursday, February 9, 2012

Java access modifiers from a C# developer perspective

C#'s internal...

Great/TheRoot.cs:
namespace Great 
{
 // internal is the class' default access.
 // it's optional to explicitly state if the class is internal
 class TheRoot 
 {
  // private is the default access of a class member, 
  // it's a must to explicitly state if a member is internal
  internal void DoSomething() 
  {   
  }
 }
}



…to Java's internal:

great/TheRoot.java:
package great;

// internal is the class' default access,
// and there is no Java keyword to explicitly state so
class TheRoot
{
 // internal is the default access of a class member, 
 // and there is no Java keyword to explicitly state so
 void doSomething() 
 { 
 }
}



C#'s private member…

Great/TheRoot.cs:

namespace Great
{
 class TheRoot
 { 
  // private is the default access of a class' member, 
  // it's optional to explicitly state if a member is private  
  void DoSomething()
  {
  }
 }
}


…to Java's private member:

great/TheRoot.java:
package great;

class TheRoot
{
 // internal is the default access of a class' member,
 // so it's a must to explicitly state if a member is private
 private void doSomething() 
 {
 }
}



C#'s internal protected member...


Great/TheRoot.cs:
namespace Great
{
 class TheRoot
 {
  // private is the default access of a class' member.
  // internal makes a member accessible to a non-deriving class that are in the same assembly as the member
  internal protected void DoSomething()
  {
  }
 }
}

Great/MainClass.cs:
namespace Great
{
 // non-deriving class
 class MainClass
 {
  public static void Main(string[] args) 
  {
   TheRoot b = new TheRoot();

   // accessible if this class is compiled in the same assembly(i.e. all, exe) as TheRoot class.
   // not accessible when this MainClass is compiled in different assembly
   b.DoSomething(); 
  }
 }
}

Ball/MainClass.cs:
namespace Ball
{
 // non-deriving class
 class MainClass
 {
  public static void Main(string[] args)
  {
   Great.TheRoot b = new Great.TheRoot();
   
 
   // as long as this class is compiled in the same assembly as TheRoot class, 
   // even this class is in different namespace, the DoSomething method will still be accessible.   
   b.DoSomething(); 
  }
 }
}



…to Java's internal protected member:

great/TheRoot.java:
package great;

class TheRoot
{
 // internal is the default access of a class' member in java, adding protected keyword doesn't cancel it.
 // there's no Java keyword to explicitly state internal access
 protected void doSomething() 
 {
 }
}

great/MainClass.java:
package great;

// non-deriving class
class MainClass
{
 public static void main(String[] args) 
 {
  TheRoot b = new TheRoot();

  // accessible
  b.doSomething(); 
 }
}



ball/MainClass.java:
package ball;

// non-deriving class
class MainClass
{
 public static void main(String[] args) 
 {
  great.TheRoot b = new great.TheRoot();

  // not accessible anymore. this class reside in different package
  b.doSomething(); 
 }
}



C#'s protected member...

Great/TheRoot.cs:
namespace Great
{
 class TheRoot
 {
  // private is the default access of a class' member.
  // protected makes a member accessible to the deriving class only
  protected void DoSomething()
  {
  }
 }
}

Great/MainClass.cs:
namespace Great
{
 // non-deriving class
 class MainClass
 {
  public static void Main(string[] args) 
  {
   TheRoot b = new TheRoot();

   // not accessible. protection works. similar to C++
   b.DoSomething();  
  }
 }
}


…to Java's protected member:


great/TheRoot.java:
package great;

class TheRoot
{
 // internal is the default access of a class' member in Java, 
 // adding protected keyword doesn't cancel it.
 // there's no Java keyword to cancel internal access on a protected member
 protected void doSomething() 
 {
 }
}


great/MainClass.java:
package great;

// non-deriving class
class MainClass
{
 public static void main(String[] args) 
 {
  TheRoot b = new TheRoot();

  // accessible, protection doesn't work. Java is the odd one out, whereas C#'s protected is same as C++'s protected semantics
  b.doSomething(); 

  // Note: if doSomething is accessed outside of package, protection works as intended.
  // In this example, the accessing method is in the same package as the accessed method, 
  // protection doesn't work.
 }
}




No comments:

Post a Comment