Are the fields or the methods of class with default access inhereted to the subclasses when they both exist in the same package, or should they be still declared as protected?
Example:
package mypackage;
class A{
int x = 3;
}
class B extends A{
}
Has the B class also a field x?
See description:
Hope it will sort things out
[EDIT]
From table for default modifier like in your case:
Accessed only from within the package in witch they are declared.
Means if class A and B stay under the same package, you can for example print out the x:
class B extends A{
public static void main(String[] args) {
new B().init();
}
private void init() {
System.out.println(x);
}
}
However, if we put class B to different package, an error will be thrown: The type mypackage.A is not visible. So here you must set public modifier.
With default access the properties are only visible to classes in same package.
But with protected access they are accessible to all classes in same package and subclasses (regardless of package). Choose what is relevant in your context.
Has the B class also a field x?
Yes B inherits the property x of A
In the case of default sub class [if in the same package] has the privilege to use the methods/data members.
class B extends Class A{
System.out.println(new B().x); //will surely work in your case(Example shown).
}
Yes you can access the public , default(If classes are in same package) and protected data members using inheritance:
public class A {
int a;
}
public class B extends A {
B() {
a = 5;
}
Related
I have a Super-class A in PackageOne and a Sub-class B which is in PackageTwo.
package PackageOne;
public class A {
protected number = 0;
}
Second Class is here
package PackageTwo;
public class B extends A {
public static void main(String args[]) {
A a = new A();
System.out.println(a.number);// Here is the error occurs
}
}
Error is The field Person.name is not visible;
As I know a protected member can be accessed by a super-class reference, but why the error occurs.
If you are in a different package, you can't access the field of another instance. You can only access the field within yourself.
Class A:
package a;
public class A {
protected int i;
}
Class B:
package b;
public class B extends A {
void m() {
A a = new A();
System.out.println(a.i); // error here!
System.out.println(i); // but no error here
}
}
If A and B were in the same package, though, there would be no error whatsoever.
Controlling Access to Members of a Class
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
Because it is protected member. You need to extend (inheritance) the class to access the protected members of a class in another package.
Instead of accessing via A access it via B. Once you extend the class A it becomes the part of class B. You cannot access it using the reference of A.
public class B extends A {
public static void main(String args[]) {
B b = new B(); // create the instance of B.
System.out.println(b.number); // access via the b.
}
}
You are also missing the data type in class A:
public class A {
protected int number = 0;
}
In the same package you can reference the members using the instance reference. Check the below code:
package PackageOne;
public class C {
public static void main(String[] args) {
A a = new A();
System.out.println(a.number); // this works.
}
}
Protected methods can only be accessible through inheritance in subclasses outside the package. And hence the second approach tryMeProtected(); works.
The code below wont compile because we are not calling the inherited version of protected method.
Example
Class1 c = new ClassA();
c.tryMeProtected(); // ERROR: tryMeProtected() has protected access in ClassA
Follow This stack link for more explaination.
That's not how inheritance works. You don't make a class a subclass of another one by creating an instance of it.
You have to extend it.
public class B extends A
This will allow you to access protected fields. However, you will have to import PackageOne.A to do this.
EDIT
See this SO answer by #David Segonds on how these keywords work
| Class | Package | Subclass | World
————————————+———————+—————————+——————————+———————
protected | y | y | y | n
You have to be a subclass or in the same package to access these properties.
From the official documentation:
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
I have some classes, which are visible only in package. After analysis I received issues related with missing documentation on public constructors/methods/types etc.
Is this a bug (false positive)? It seems to me that change from public to not public constructors/methods/types is senseless.
I use SonarQube 5.1.1 and Java Plugin 3.4.
About methods, fields and inner classes:
Having methods (or fields or inner classes) being public in a package-private class implies that if extended with a public class, the public members from the package-private class will be visible from the outside! Consequently, they have to be considered as being public, and therefore documented.
Example:
package-private class A:
package org.foo;
class A {
public int field;
public void method() {}
public class Inner {}
}
public class B:
package org.foo;
public class B extends A {
}
other package, class C:
package org.bar;
public class C {
void test() {
B b = new B();
int f = b.field; // visible
B.Inner = b.new Inner(); // visible
b.method(); // visible
}
}
About constructors:
As constructors of the package-private class are only visible from the same package, and these constructors won't be callable from another package, even through public child class, it's indeed wrong to raise an issue on them and it should be corrected in the SQ rule from the java plugin (see SONARJAVA-1557).
I would however recommend to lower the visibility of that constructor, as having it public is somehow senseless...
A public constructor should be documented, so it is not a false positive.
You don't need to declare the constructor public however :)
Considering the following code:
public abstract class AbstractA
{
public static final class B
{
protected B(){}
}
}
// a class (in another package) that inherits from AbstractA
public class C extends AbstractA
{
B[] arrayOfB=new B[10];
for(byte i=0; i<=arrayOfB.length; i++)
{
arrayOfB[i]=new B();
}
}
In class C I can define arrayOfB because class B is static & public but I cant instanciate an object of this.
Eclipse says: The constructor A.B() is not visible
If class C was in the same package as the class A, I could instantiate it.
How can I keep the constructor B() protected and still create an object of this knowing that the class C inherits from A?
It is nothing to do with inner classes. Your B constructor is protected it means only subclasses could access it, but you define the class as final, it doesn't make sense. Maybe you could add a factory method to the AbstractA which creates B instances, outer class has access to its inner classes, even for private methods.
public abstract class AbstractA
{
protected B newB() {return new B();}
public static final class B
{
private B(){}
}
}
// a class (in another package) that inherits from AbstractA
public class C extends AbstractA
{
B[] arrayOfB=new B[10];
for(byte i=0; i<=arrayOfB.length; i++)
{
arrayOfB[i]=this.newB();
}
}
Public static classes that are nested are the same as public classes in a separate file. So you cannot see B's constructor, because you are not B's descendant, nor are you in the same package.
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.
(The implicit super() call will fail.)
The protected specifier allows access by all subclasses of the class in question, whatever package they reside in, as well as to other code in the same package.
In your case, the class C resides in different package and hence you are not allowed to instantiate A.B() due to above reason.
Please remember, protected specifier permits only inheritance in different package. You cannot access them directly..
As a solution to your problem, move the class C in the same package as that of AbstractA to make B accessible.
Are fields only inherited "one level up"?
By that I mean that if I have a Superclass to a Class, which then has a Subclass, and the Superclass has a field, the Class will inherit it and the Subclass won't. Is this correct?
And if it is, is there a way to make the Subclass automatically inherit the field from the Superclass given that, as I understand it, there's no way to inherit from two classes at once?
Thank you to anyone who takes the time to answer. I realize my question may be impractical and in reality you'd probably just override the field or something, but I'm not trying to do anything specific, just trying to learn how Java works. Thank you.
Here's my code:
public class SuperClass {
protected int entero;
protected void method(){
entero=1;
}
public class SubClass extends Class {
public SubClass(){}
}
public class Class extends SuperClass {
public Class(){}
}
public static void main(String[] args){
Class object= new Class();
SubClass subobject= new SubClass();
/*This is where I get an error, why?*/
subobject.entero=2;
/*This one is fine*/
object.entero=2;
object.method();
System.out.println(object.entero);
}
Any class B than extends a class A, will inherit A's fields. If a class C extends B, C will inherit all non-private instance fields and methods from A and B, ie transitivity holds.
If a field is private, then one cannot directly change it from a subclass; however, you can get around this by using setter/getter methods.
If a field is protected, then a subclass has direct access to it.
EDIT 1:
In a comment you say that the field is protected, but you still can't access it from a subclass. The only thing I can think of is that you have a situation like this:
class A
{
protected int x;
}
class B extends A
{
private int x;
}
class C extends B
{
private int z = x;
}
This would NOT work because by declaring x again in B, you are hiding the x field from A. So, now C sees x as B's private variable x, which you do not have access to.
EDIT 2:
I'm not going to remove the above edit, because it's informative, but now that you posted your code, it's because your SubClass does not actually extend anything (this was later fixed in an edit).
Inheritance in Java is transitive.
If your classes are Superclass < Class < Subclass, then Subclass inherits all the non-private instance fields and methods provided by Superclass not overridden or hidden by Class or Subclass.
One level of inheritance is specified by the Java Language Specification, section 8.4.8: Inheritance, Overriding and Hiding:
A class C inherits from its direct superclass and direct superinterfaces all abstract
and non-abstract methods of the superclass and superinterfaces that are public,
protected, or declared with default access in the same package as C, and are neither
overridden (§8.4.8.1) nor hidden (§8.4.8.2) by a declaration in the class.
If you have classes that are:
public class SuperClass {
public void methodName() {}
//SuperClass's stuff
}
public class MidClass extends SuperClass {
//MidClass's stuff
}
public class SubClass extends MidClass {
//SubClass's Stuff
}
Then it is perfectly valid to have in your main method:
SubClass sc = new SubClass();
sc.methodName();
I have an question which comes under multilevel inheritance in Java. All Three Classes are in Same package
I have class A :
public class A {
protected int x;
}
public class B extends A {
public void doSomething {
// x is visible.agreed, as it is a direct subclass of A
}
}
public class C extends B {
public void doSomething {
// x is still visible, how come? I mean it is at the 2nd level
// I am confused why?
}
}
does it like have any significance? or it is behavior which we have to take it by default?
variable/methods marked with protected modifier are visible to all the classes in the same pacakage and only to subclasses in different packages.
below are the example cases.
package a;
class A{
protected int x;
}
class B extends A{
//x can be accessed from this class
}
class C extends B {
//x can be accessed from this class
}
class D{
//x can be accesed this class but you will have to create A's instance
}
package B
class One {
//cannot access x from this class
}
class Two extends A {
//can access x from this class
}
The access level modifiers in Java are:
public - visible to all code
protected - visible to all code in the same package and to subclasses regardless of package
nothing (default) - visible to all code in the same package
private - visible only to code in the same class (including nested classes)
See, for instance, the Java tutorial Controlling Access to Members of a Class or (for lots of technical details) section 6.6 of the Java Language Specification.
Definition of the keyword
Protected
The protected modifier specifies that the member can only be accessed
within its own package (as with package-private) and, in addition, by
a subclass of its class in another package.
I suggest you read this.
The Java protected keyword works its way down to all subclasses (and members of the package). If there was a protected member in Object, any object could access it. By contrast, private is only visible to the local class (and inner classes), and public is accessible by all.
Have a look at this glossary, which shows in-depth how protected members and methods are inherited, and the Java documentation on inheritance.
You cannot restrict access to members in subclasses. This rule applies to methods (you can't override public method and make it private) but you can see analogy here. If the field is protected, it will be protected in every subclass, no matter how deep. Of course you can't override fields in Java, but just to give you an overview.
Please refer this: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.
So if your class C shares the package with A and B, its accessible.
Inheritance is transitive: if class B inherits from class A;
and class C inherits from class B; then C is also a
subclass / child class / descendant of class A.