Reputation: 21
The top answer given there states that the protected constructor can be called using super()
but cannot be instantiated using new
? Why so? And if that is the reason then what is the difference between package-private(no modifier) and protected constructor?
The following code is not getting me any difference.
package pack1;
public class Rr {
protected Rr() {
System.out.println("Rello");
}
}
package pack2;
class Tt extends pack1.Rr {
Tt() {
super(); //works
pack1.Rr r = new pack1.Rr(); //error
}
}
class Uu {
public static void main(String args[]) {
Tt t = new Tt();
}
}
Upvotes: 2
Views: 1318
Reputation: 14999
A "default constructor" is a constructor that Java generates if you don't provide one yourself; it's always has the same access as the class itself and has no arguments. Ie when you define
class YourClass {}
the system makes it
class YourClass {
YourClass() {} // default constructor
}
If you create a any other constructor - even a public
one with no arguments - it is not a default constructor. The second code piece above would prevent the system from generating one, because you already declared it.
The same is true if you create a protected
constructor. Compare:
public class Class1 {}
public class Class2 {
protected Class2() {}
}
you can instantiate Class1, but not Class2:
// invokes autogenerated default constructor
Class1 c1 = new Class1();
// compile error: default constructor is not generated because you declared a protected one
Class2 c2 = new Class2();
As @Turing85 states in a comment, the protected
modifier only means that the declared constructor can only be invoked within the proper access scope - from subclasses or classes in the same package.
For completeness' sake: you can call both super()
and the constructor explicitly from a subclass:
class Class3 extends Class2() {
public Class3() {
// call to protected constructor of Class2
super();
// explicit call to constructor by creating new instance
Class2 o = new Class2();
}
}
EDIT: I just tried it out, and the last sample is only valid if the two classes are in the same package. I don't know and would like to know.
Upvotes: 1
Reputation: 2045
A protected
method can be accessed via its sub-class objects.
Note, "sub-class" here is very important, which means "via a sub-class way", not "anywhere within a sub-class".
Let's look at an example.
Following are 2 classes:
package one;
public class A {
protected A() {} // protected constructor
public A(int i) {} // public constructor
protected void foo() {} // protected method
}
package two;
import one.A;
public class B extends A {
public void bar() {
this.foo(); // correct
A a = new A(0); // call A's public constructor to construct an A instance.
a.foo(); // compiler error: the method foo from the type A is not visible.
}
}
The first invocation is permitted, but the second not, why?
Like I said, the first one is accessing via "a sub-class way", in which this
is A's sub-class instance; however the second just "within a sub-class" (here B is no meaning to A, it's just an ordinary class, so it can not access A's protected method).
Another example is Object.clone
. This is a protected method of root class Object
. You might likely say it can be accessed from any object created from any class, but the answer is capital "NO": only those codes which are using "sub-classes way" can access it.
The following illustrates this:
this.clone(); // ok
Object o = new Object();
o.clone(); // compiler error: the method clone from the type Object is not visible.
Upvotes: 1
Reputation: 1938
protected
gives access to subclasses, in addition to the classes in the same package.
When you call the constructor directly, e.g. new A()
you can think of it as calling a static method. There is no instance of the class yet, thus inheritance rules cannot apply. Therefore, static access rules apply: if the constructor is protected, then it must be in the same package in order to be accessible.
Once you are inside a constructor code and you call super()
, then you already have an instance, so if you are in a subclass and call the protected constructor it will work.
Upvotes: 0