I did a little web search and came to know that default constructor's access modifier is same as the access level of class, but take a look.
Here is one class
package package2;
public class TestClass1 {
TestClass1()
{
System.out.println("In parent's contructor");
}
}
and here is another which inherits from the previous one
package package2;
public class TestClass2 extends TestClass1 {
TestClass2()
{
System.out.println("In TestClass2's contructor");
}
}
But when i try to create the object of TestClass2
import package2.*;
class MainClass {
public static void main(String[] args)
{
TestClass2 t2 = new TestClass2(); //Says the constructor TestClass2() is not visible.
}
}
I don't understand, both classes TestClass1 and TestClass2 have public access so their constructors must also be implicitly public. Which concept am I missing here ? o.O
I did a little web search and came to know that default constructor's
access specifier is same as the access level of class
There is a difference between default constructor and the one which you've declared. The default constructor is the one which you don't declare inside the class.
The current one in your code is not a default constructor. And, it has default(package-private --- no explicit modifier) acccess as you've omitted any access modifier from it.
Which concept am I missing here ?
So, your class from other package is not able to find it, because of the limitation of default access.
Oh they are public, but to the package only (we call it the default-access-modifier)!
The access-modifiers make no difference between constructors and methods and fields.
Move MainClass to the same package like this:
package package2; // <-- !
import package2.*;
class MainClass {
public static void main(String[] args)
{
TestClass2 t2 = new TestClass2(); //OK!
}
}
Or make the Constructors real public
public TestClass2()
...
Implicit constructor is the constructor when you do not write any constructor. In your code you have explicitly written the constructor, so they are not implicit.
Implicit constructor is provided by Java internally and it is not visible. For Example:
package package2;
public class TestClass1 {
}
In the above class we have not written any constructor.
package main;
class MainClass {
public static void main(String[] args)
{
TestClass1 t2 = new TestClass1(); //Although we have not written any constructor for TestClass1, but we are able to create object for it. This object creation is done by calling TestClass1's costructor, which is an implicit, invisible constructor provided by java when we explicitly do not write any constructor.
}
}
Above, although we have not written any constructor for TestClass1, but we are able to create object for it. This object creation is done by calling TestClass1's costructor, which is an implicit, invisible constructor provided by java when we explicitly do not write any constructor.
In your example, you have explicitly written the constructor and made it default(default means not making public or private), which means it will only be accessible in the same package. If you try to call this constructor from any class which is outside the package, you'll get the error that the constructor is not visible as in your case:
import package2.*;
class MainClass {
public static void main(String[] args)
{
TestClass2 t2 = new TestClass2(); //Says the constructor TestClass2() is not visible.
}
}
Related
Why its saying
error No enclosing instance of type Demo is available due to some intermediate constructor invocation
class Demo {
class DemoInner{
DemoInner(){
System.out.println("DemmoInner");
}
}
}
public class Noding extends Demo.DemoInner{
Noding(){
super();
System.out.println("Noding");
}
public static void main(String[] args) {
new Noding();
}
}
Noding is a child of Demo.DemoInner and Demo.DemoInner is an instance thing of Demo class.
So while creating Child class Noding instance, calling super should not be giving a problem becasue parent should be in existence before creating child. And in this case parent is Demo.DemoInner for Noding and Demo.DemoInner can't exist without Demo.
So why its giving error while calling super() in Noding constructor ?
The call to the inner class is called like this:
class Noding extends Demo {
public static void main(String[] args) {
Demo demo = new Demo();
Demo.DemoInner inner = demo.new DemoInner();
System.out.println(inner);
}
}
Unless it is declared as static, it is dynamic, that is the object needs to be instantiated.
If you declared DemoInner like this:
class Demo {
class DemoInner{}
}
It means DemoInner class is one of the instances of Demo. So when you use DemoInner class, you need to instantiate Demo class first. And access DemoInner as the Demo instance's member object (see #AlexeyKonovalov's answer).
Or a workaround is to make DemoInner static (as #RobOhRob commented). Once declared static, it is no longer a member object of the outer class Demo object. You can access DemoInner class whether the outer class is instantiated or not.
class Demo {
static class DemoInner{}
}
Making DemoInner as a static class shall make the code run. DemoInner is a non-static inner class and hence it is associated with the instance of Demo class.
You can't call its constructor from Noding without making the class static.
class Demo {
static class DemoInner{
DemoInner(){
System.out.println("DemmoInner");
}
}
}
public class Noding extends Demo.DemoInner{
Noding(){
super();
System.out.println("Noding");
}
public static void main(String[] args) {
new Noding();
}
}
I'm new to JAVA and im trying to understand how inheritance works.
I have 3 classes:
package dziedziczenie2;
public class Kobieta {
protected Oczy Eyes = new Oczy();
public static void main(String[] args) {
Kobieta x = new Kobieta();
System.out.println(x.Eyes); // blue
x.Eyes.kolor = "red";
System.out.println(x.Eyes); // red
}
}
class Oczy{
public String kolor = "blue";
public String toString(){
return kolor;
}
}
other package:
package dziedziczenie;
import dziedziczenie2.Kobieta;
public class Ania extends Kobieta{
public static void main(String[] args) {
Ania x = new Ania();
System.out.println(x.Eyes); // blue
x.Eyes.kolor = "red"; // type Oczy not visable
}
}
My questiong is, why i cant change Eye.kolor in Ania class simply my typing x.Eyes.kolor.
I know that Oczy is not public, but i can use its toString method somehow.
EDIT: Why i can use its toSting method and i cant use its member?
Do I have to make a method in Kobieta that will interact with Oczy member for me every time i want to interact with Oczy member from other package?
Thanks in advance
The class Oczy has access modifier "default" which is accessible only in the package "dziedziczenie2" n not in package "dziedziczenie".
1) Option:
You may simply create a file Oczy.java with declaring public class Oczy and u r done.
2) Option:
You may declare public static class Oczy in the class Kobieta like this.
public class Kobieta {
// ur code
public static class Oczy {
// ur code
}
}
Eyes is of type Oczy which has default visibility, since it has no access modifier. You can only access its members in the same package it's declared in, even if those are public.
Do I have to make a method in Kobieta that will interact with Oczy
member for me every time i want to interact with Oczy member from
other package?
You can do that or you can move the Oczy to its own compilation unit (.java file) and make it public.
If I understand correctly you are expecting Eyes to be inherited to Ania class.
Because in inheritance attributes are not inherited like methods. Eyes is attribute of Kobieta class so when Ania extends Kobieta it dont inherit it.
Can anybody explain me why do we need "protected" word?
If I understand correctly,
default access: available in classes within the same package.
protected access: default access in same package + available to inherited classes
(sub-classes) in any package. Basically, we get the same
default access in same package.
So when should I use it? Just for the style of your code? To mark it that you are going to work with it from perspective of inheritance?
Thank you.
package firstPack;
public class First {
protected int a;
protected void Chat(){
System.out.println("Here I am");
}
}
package secondPack;
import firstPack.First;
public class Second extends First{
public static void main(String [] args){
First f=new First();
// f.Chat();
// System.out.println(f.a);
}
}
I used this code to test it. It didn't work.
protected means visible to all sub-classes, not just those in the same package.
Problem with your test code is that you ware trying to access protected members of First class instance and via First class reference. Notice that since Second class is not in the same package as First one it doesn't have access to protected fields of any instance of base class, but have access to its own fields inherited from First class (which includes protected ones). So something like
First f = new First();
f.chat();//chat is protected in base class.
will not compile in Second class, but something like
public void test() {
a = 1; // have access to inherited protected field or
chat(); // methods of base class
}
public static void main(String[] args) {
Second f = new Second();
f.chat();
System.out.println(f.a);
}
is OK since Second class have access to its inherited members.
Notice that code in main method works only because it is placed inside Second class since only derived classes or classes in the same package as First have access to its protected members. So if this code will be placed inside other class like
class Test{
public static void main(String[] args) {
Second f = new Second();
f.chat();
System.out.println(f.a);
}
}
it will not compile (no access to protected members because Test doesn't extend or is not in same package as First).
The protected modifier: Accessed by other classes in the same package or any
subclasses of the class in which they are referred (i.e. same package or different package).
Reference
The following is my ProtectedConstructor.java source code:
package protectCon;
public class ProtectedConstructor{
public int nothing;
ProtectedConstructor(){
nothing = 0;
}
}
And following is the UsingProtectedCon.java source:
package other;
import protectcon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{ //**Line 4**
public static void main(String... a) {
}
}
When I compile UsingProtectedCon.java, I get error at Line 4 shown above. It says that ProtectedConstructor() is not public ; so cannot be accessed outside package.
However, since my class is public, shouldn't I be able to extend it outside package. I am anyway not creating any instance of it.
Now, if I make the constructor of ProtectedConstructor class as public or protected then the code compiles fine with no error.
So then why is it necessary even for the constructor to be public or protected, and not just have default access?
If you want to extends a class outside its package it must have a constructor that is public or protected because in Java every constructor must call a constructor from its superclass.
Because of this there is an implied super() call in every constructor which does not have this() or an explicit call to super() as its first statement. And if you don't specify a constructor at all Java will add a default parameterless constructor, so in effect your code looks like this:
public class UsingProtectedCon extends ProtectedConstructor {
public UsingProtectedCon() {
super();
}
public static void main(String... a) {
}
}
So in other words your code is failing to compile because the call to super() in the default constructor cannot be resolved.
constructor is a member of class like field and method so access modifier applies to it in the same manner it apples to all the member of class
when you extend the class A in B , A's its default constructor will get called from B's constructor implicitly (if you don't call any of the overloaded constructor)
in your class ProtectedConstructor is defined with Package-Private access
This means that outside the package its not seen even by the classes that extend from your ProtectedConstructor class
Define your constructor with 'protected' access modifier instead and you'll be done:
package protectCon;
public class ProtectedConstructor{
public int nothing;
protected ProtectedConstructor(){
nothing = 0;
}
}
Your constructor is not public. Default scope is package-private.
JLS 6.6.7 answers your question. A subclass only access a protected members of its parent class, if it involves implementation of its parent. Therefore , you can not instantiate a parent object in a child class, if parent constructor is protected and it is in different package.Since the default constructor of the subclass would try to call parent class constructor ,you got this error.
See this SO Post for details
to avoid all confusion do it like this.
package protectCon;
public class ProtectedConstructor{
public int nothing;
public ProtectedConstructor(){
nothing = 0;
}
}
package other;
import protectCon.ProtectedConstructor;
public class UsingProtectedCon extends ProtectedConstructor{ //**Line 4**
public UsingProtectedCon(){
super();
}
public static void main(String... a){
}
}
You can have constructors which are public, protected (for internal used) and even private.
A simple example is String which has public constructors for general use and package-local constructors for internal use.
The ObjectOutputStream class has a public constructor which takes an OutputStream and a protected constructor which can only be used by a sub-class.
BTW: if you have an abstract class, does it make sense to make the constructor public as if often the case. ;) hint: it is the same as protected.
If child will have constructor which is private in parent,we can make child's instance with that constructor and cast it to parent's type.
So to prevent this java compiler is not allowing constructor to have constructor which is private in parent.
I can create Main class with Access specifier "public" or default.
But why can't I create with protected. As default itself allowed why not protected.
Public:
public class MainClass {
public static void main(String[] args) {
}
}
Default:
class MainClass {
public static void main(String[] args) {
}
}
Protected:
protected class MainClass {
public static void main(String[] args) {
}
}
Its showing error:
Illegal modifier for the class MainClass; only public, abstract & final are permitted MainClass.java SCJP/src line 1 Java Problem
protected relates to giving subclasses of the containing type access to a member. There's no containing type here, so what would it mean?
Note that this has nothing to do with main as such... it applies to any top-level class. It is valid for a nested type to be protected though:
public class Foo {
protected static class Bar{}
}
This allows subclasses of Foo to access Bar.
protected or private class has no sense - as a top level class, not the inner one. Such class wouldn't be usable. Protected mean, that elements in the class can be visible by children. But what if the whole class would be package. In this case any other class could even see such class (even in the same package) until it extends such class. It would be strange and that is why it is forbidden.
Aren't you compromising on the visibility of your main method by having the enclosing class as protected?
As far as I know, for a main method to be accessible there are two things you need to ensure:
The enclosing class is public. (I think it can be default also)
The enclosing class and the parent file have the same name.
Hope this helps :)