Saturday, February 21, 2015

C# vs Java : access modifiers

Both C# and Java provide ways to control which fields or methods another class may access. The type and number of these access modifiers, however, differs between the two languages. Listed below are the access modifiers each language provides, from least to most restrictive.

Java has four access modifiers:
  • public
  • protected
  • (package)
  • private
Note: You can't actually label a field or method as having package access. Instead what you do is leave the access modifier off.

C# has five access modifiers:
  • public
  • protected internal
  • internal
  • protected
  • private

Although C#'s namespace feature is similar to packages in Java, there really isn't a way to limit the scope of a field or method to just classes that are in a particular namespace.

Java doesn't really have a way to create dlls. Therefore it doesn't have an equivalent internal access modifier.

Something else that's different between the two languages is the way protected access behaves. In Java, protected access limits the visibility of a field or method to just subclasses and classes that are in the same package. So, for example, let's say you had the following:
package Earth;
 
public class Earthling {
   protected String str = "Hello World";
}
You could then access this String from any class that's in the same package as Earthling:
package Earth;

public class Dog {
   public Dog() {
      Earthling earthling = new Earthling();
      System.out.println("earthling.str = " + earthling.str);
   }
 
   public static void main(String[] args) {
      new Dog();
   }
}
You can even access it from subclasses that are in a different package:
package Mars;
 
import Earth.Earthling;
 
public class Explorer extends Earthling {
   public Explorer() {
      System.out.println("str = " + str);
   }
 
   public static void main(String[] args) {
      new Explorer();
   }
}
But you cannot access it from a non-subclass that's in a different package.
package Mars;
 
import Earth.Earthling;
 
public class Martian {
   public Martian() {
      Earthling earthling = new Earthling();

      // compiler error: can't access str field
      // System.out.println("earthling.str = " + earthling.str); 
   }
 
   public static void main(String[] args) {
      new Martian();
   }
}
Protected access in C# limits the visibility to just that class definition and any class that derives from that class. So, for example, let's say you had the following:
public class BaseKlass {
  protected string str = "Hello World";

  public BaseKlass() {
    System.Console.WriteLine("BaseKlass(), str = " + str);
  }

  public static void Main() {
    BaseKlass baseKlass = new BaseKlass();
    System.Console.WriteLine("baseKlass.str = " + baseKlass.str);
    System.Console.WriteLine();
  }
}
As you can see here we can access the str field within the BaseKlass. Now let's see what happens when we derive from that class.
public class DerivedKlass : BaseKlass {
  public DerivedKlass() {
    System.Console.WriteLine("DerivedKlass(), str = " + str);
  }

  public static void Main() {
    // The following lines won't compile
    // BaseKlass baseKlass = new BaseKlass();
    // System.Console.WriteLine("baseKlass.str = " + baseKlass.str);

    DerivedKlass derivedKlass = new DerivedKlass();
    System.Console.WriteLine("derivedKlass.str = " + derivedKlass.str);
  }
}
Notice that although DerivedKlass inherits from BaseKlass because we're not accessing BaseKlass' str field within the class itself we are not able to access that field. Java, on the other hand, will allow you to access it.
public class BaseKlass {
   protected String str = "Hello World";

   public BaseKlass() {
      System.out.println("BaseKlass(), str = " + str);
   }
}
public class DerivedKlass extends BaseKlass {
   public DerivedKlass() {
      System.out.println("DerivedKlass(), str = " + str);
   }

   public static void main(String... args) {
      BaseKlass baseKlass = new BaseKlass();
      System.out.println("baseKlass.str = " + baseKlass.str);
      System.out.println();

      DerivedKlass derivedKlass = new DerivedKlass();
      System.out.println("derivedKlass.str = " + derivedKlass.str);
   }
}

Finally when you leave off the access modifier in Java it defaults to package access. So, for example, let's say you had the following:
package Earth;
 
public class Earthling {
   String str = "Hello World";
}
You could then access the str field from any class that's in the same package as Earthling:
package Earth;
 
public class Dog {
   public Dog() {
      Earthling earthling = new Earthling();
      System.out.println("earthling.str = " + earthling.str);
   }
 
   public static void main(String[] args) {
      new Dog();
   }
}
But you cannot access it from classes that are in a different package, even if the class is a subclass.
package Mars;
 
import Earth.Earthling;
 
public class Explorer extends Earthling {
   public Explorer() {
      // compiler error: can't access str field
      // System.out.println("str = " + str);
   }
 
   public static void main(String[] args) {
      new Explorer();
   }
}
When you leave off the access modifier in C# it defaults to private access. Here's a short little program that demonstrates this. The commented out lines indicate a compiler error because the str field could not be accessed.
public class BaseKlass {
  string str = "Hello World";

  public BaseKlass() {
    System.Console.WriteLine("BaseKlass(), str = " + str);
  }
}

public class DerivedKlass : BaseKlass {
  public DerivedKlass() {
    // System.Console.WriteLine("DerivedKlass(), str = " + str);
  }

  public static void Main() {
    BaseKlass baseKlass = new BaseKlass();
    // System.Console.WriteLine("baseKlass.str = " + baseKlass.str);

    // DerivedKlass derivedKlass = new DerivedKlass();
    // System.Console.WriteLine("derivedKlass.str = " + derivedKlass.str);
  }
}
There's only one access modifier in C# that limits the scope of a member to just within that class and that's the private access modifier. So the above BaseKlass is equivalent to the following:
public class BaseKlass {
  private string str = "Hello World";

  public BaseKlass() {
    System.Console.WriteLine("BaseKlass(), str = " + str);
  }
}

See Also: Java's Access Modifiers

See Also: C# : Access Modifiers

2 comments:

  1. It is really a great work and the way in which u r sharing the knowledge is excellent.
    Thanks for helping me to understand basic concepts. As a beginner in java programming your post help me a lot.Thanks for your informative article.java training in chennai | chennai's no.1 java training in chennai

    ReplyDelete
  2. perfect explanation about java programming .its very useful.thanks for your valuable information.java training in chennai | java training in velachery

    ReplyDelete