What is the example of indirect access to private member of superclass from subclass?
A nested class has access to all the private members of its enclosing
class—both fields and methods. Therefore, a public or protected nested
class inherited by a subclass has indirect access to all of the
private members of the superclass.
Quote from http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
In the quote, we talk about "nested" class
here is an example of how an inner class can access private fields of the outer class.
class OuterClass {
private int x = 7;
public void makeInner(){
InnerClass in = new InnerClass();
in.seeOuter();
}
class InnerClass {
public void seeOuter() {
System.out.println("Outer x is " + x);
}
}
public static void main(String[] args) {
OuterClass.InnerClass inner = new OuterClass().new InnerClass();
inner.seeOuter();
}
}
Finally, if you extend a class with the InnerClass, they will also access the private fields of the OuterClass if your InnerClass is public or protected
It is to be supposed (but the compiler does not enforce it, only warns), that a private method will end being used by a public, protected or default method (otherwise it is useless).
So, the extending class can "indirectly" call the private method by calling the public, protected or default method that ends calling the private method.
Yes, we can access private members of a superclass in the child class through the public method of the superclass which can be invoked from the child class's reference variable heaving the reference id of child class.
for example:-
class Base
{
private int x=10;
void show()
{
System.out.println(x);
}
}
class Child extends Base
{
public static void main(String... s)// public static void main(String[] args)
{
//rom jdk 1.7 main can be defined like above
Child c=new Child();
c.show();
}
}
The output will be 10
Related
I'm currently reading Effective Java by Joshua Bloch and I love it! But on page 112 (Item 24) Bloch writes:
A static member class is the simplest kind of nested class. It is best
thought of as an ordinary class that happens to be declared inside
another class and has access to all of the enclosing class’s members,
even those declared private.
And that really confuses me. I would rather say:
A static member class is the simplest kind of nested class. It is best
thought of as an ordinary class that happens to be declared inside
another class and has access to all of the enclosing class’s static members,
even those declared private.
Here is a snippet that illustrates my understanding of the quote:
public class OuterClass {
public void printMessage(String message) {
System.out.println(message);
}
private static class InnerClass {
public void sayHello() {
printMessage("Hello world!"); //error: Cannot make a static reference to the non-static method printMessage(String)
}
}
}
You can see that InnerClass's sayHello method does not have access to OuterClass's printMessage method as it is declared in a static inner class while the printMessage method is an instance method. It looks like the author suggests that a static member class can access nonstatic fields of the enclosing class. I am convinced that I have misunderstood something in his last sentence but I cannot figure out what. Any help will be appreciated!
edit: I changed the visibility of the two methods because it is irrelevant to my question. I'm interested in static members, not private members.
Just because InnerClass is static, doesn't mean it couldn't obtain a reference to an instance of OuterClass through other means, most commonly as a parameter, e.g.
public class OuterClass {
private void printMessage(String message) {
System.out.println(message);
}
private static class InnerClass {
private void sayHello(OuterClass outer) {
outer.printMessage("Hello world!"); // allowed
}
}
}
If InnerClass had not been nested inside OuterClass, it would not have had access to the private method.
public class OuterClass {
private void printMessage(String message) {
System.out.println(message);
}
}
class InnerClass {
private void sayHello(OuterClass outer) {
outer.printMessage("Hello world!"); // ERROR: The method printMessage(String) from the type OuterClass is not visible
}
}
Note the error message. It's not saying you don't have access. It's saying the method cannot be called. Instance methods don't mean anything without an instance to
call them on. What the error message is telling you is that you don't have that instance.
What Bloch is telling you is that if that instance existed, code in the inner class could call private instance methods on it.
Say we have the following class:
public class OuterClass {
public void publicInstanceMethod() {}
public static void publicClassMethod() {}
private void privateInstanceMethod() {}
private static void privateClassMethod() {}
}
If we try to call those private methods from some random class, we can't:
class SomeOtherClass {
void doTheThing() {
OuterClass.publicClassMethod();
OuterClass.privateClassMethod(); // Error: privateClassMethod() has private access in OuterClass
}
void doTheThingWithTheThing(OuterClass oc) {
oc.publicInstanceMethod();
oc.privateInstanceMethod(); // Error: privateInstanceMethod() has private access in OuterClass
}
}
Note that those error messages say private access.
If we add a method to OuterClass itself, we can call those methods:
public class OuterClass {
// ...declarations etc.
private void doAThing() {
publicInstanceMethod(); // OK; same as this.publicInstanceMethod();
privateInstanceMethod(); // OK; same as this.privateInstanceMethod();
publicClassMethod();
privateClassMethod();
}
}
Or if we add a static inner class:
public class OuterClass {
// ...declarations etc.
private static class StaticInnerClass {
private void doTheThingWithTheThing(OuterClass oc) {
publicClassMethod(); // OK
privateClassMethod(); // OK, because we're "inside"
oc.publicInstanceMethod(); // OK, because we have an instance
oc.privateInstanceMethod(); // OK, because we have an instance
publicInstanceMethod(); // no instance -> Error: non-static method publicInstanceMethod() cannot be referenced from a static context
privateInstanceMethod(); // no instance -> Error: java: non-static method privateInstanceMethod() cannot be referenced from a static context
}
}
}
If we add a non-static inner class, it looks like we can do magic:
public class OuterClass {
// ...declarations etc.
private class NonStaticInnerClass {
private void doTheThing() {
publicClassMethod(); // OK
privateClassMethod(); // OK
publicInstanceMethod(); // OK
privateInstanceMethod(); // OK
}
}
}
However, there's trickery going on here: a non-static inner class is always associated with an instance of the outer class, and what you're really looking at is:
private class NonStaticInnerClass {
private void doTheThing() {
publicClassMethod(); // OK
privateClassMethod(); // OK
OuterClass.this.publicInstanceMethod(); // still OK
OuterClass.this.privateInstanceMethod(); // still OK
}
}
Here, OuterClass.this is special syntax for accessing that outer instance. But you only need it if it's ambiguous, e.g. if the outer and inner classes have methods with the same name.
Note too that the non-static class can still do the things the static one can do:
private class NonStaticInnerClass {
private void doTheThingWithTheThing(OuterClass oc) {
// 'oc' does *not* have to be the same instance as 'OuterClass.this'
oc.publicInstanceMethod();
oc.privateInstanceMethod();
}
}
In short: public and private are always about access. The point Bloch is making is that inner classes have access that other classes don't. But no amount of access allows you to call an instance method without telling the compiler what instance you want to call it on.
The way you showed it requires inheritance. But methods and fields could be access in this way:
public class OuterClass {
private void printMessage(String message) {
System.out.println(message);
}
private static class InnerClass {
private void sayHello() {
OuterClass outer = new OuterClass();
outer.printMessage("Hello world!");
}
}
}
But, that the static inner class doesn't have access to the printMessage function doesn't have to do with that it is an inner class, but that it is static and can't invoke a non-static method. I think that the use of the word "static" you proposed was implicit in the first sentence. What he is pointing out, or chose to emphasize, is just that the inner class can still access private methods of its parent class. He might have just though it unnecessary or confusing to make the static/non-static distinction in the same sentence, too.
The way I see it, the text is absolutely right. Static member classes can access the private members of the enclosing classes (sort of). Let me show you an example:
public class OuterClass {
String _name;
int _age;
public OuterClass(String name) {
_name = name;
}
public static OuterClass CreateOuterClass(String name, int age) {
OuterClass instance = new OuterClass(name);
instance._age = age; // Notice that the private field "_age" of the enclosing class is visible/accessible inside this static method (as it would also be inside of a static member class).
return instance;
}
}
when you extend a private class. Are the public and protected members of class become private. if not any explanation.
if you extend a nested private class, it wont change public/protected modifiers of the members. Here is an example :
public class Clazz {
private static class NestedClazz {
public int value = 123;
}
public static class NestedClazzExt extends NestedClazz {
}
}
you can now access the inherited member: value from outside
public static void main(String[] args) {
NestedClazzExt nestedClazz = new Clazz.NestedClazzExt();
System.out.println(nestedClazz.value);
}
you can create private class in side a class . We call it as Nested classe. Means a class inside a class. The Concept itself is saying that you can create private class in side another class. The private class will act like as data member to the outer class.
So, You can't extend the private class.
Based on your query I tried to prepare a simple class.
public class pvtClass {
private class As {
public String abc = "private attribute";
public void print(){
System.out.println("privateClass");
}
}
class Ab extends As{
public String ab = "extended attribute";
public void printAb(){
System.out.println("extended class");
print();
System.out.println(abc);
}
}
public static void main(String as[]){
Ab ab1 = (new pvtClass()).new Ab();
As as1 = (new pvtClass()).new As();
ab1.printAb();
as1.print();
System.out.println(as1.abc);
}
}
If you have a look at this class, I have a private class named "As" which has public attribute and public methods. I have another class named "Ab" which extends "As". I have written a main method to invoke the private attribute and methods.
below is the output for the code snippet:
extended class
privateClass
private attribute
privateClass
private attribute
There is a difference between the access of the members of a class and the access to the type itself.
public class C {
private class InnerP1 {
public void m() {
System.out.println("InnerP1.m()");
}
}
private class InnerP2 extends InnerP1 {
public void p() {
this.m();
System.out.println("InnerP2.p()");
}
}
public InnerP1 strange() {
return new InnerP2();
}
}
In this example, the interface I is visible from outside class C. The classes InnerP1 and InnerP2 are not visible from outside C. Jave itself makes not restrictions to the visibility of types you use in your public interface. The method strange() of class C returns a result of class InnerP1. Since outside of C we do not know anything about the class InnerP1 other than it is subtype of Object, the only thing we can do is use the result of strange() as an Object.
public class D {
public static void main(String[] args) {
C c = new C();
Object o = c.strange();
if(o.equals(c.strange())) {
System.out.println("Strange things are going on here!");
}
}
}
As #KnusperPudding pointed out already, the visiblity of public members is not changed, we might just not have enough knowledge of the type itself to access them.
Access to members cannot be restricted by sub-classing. When you mark a class as private then access via the class name is restricted i.e. to the same .java file, however once you have an instance of this class it can be accessed at least as easily as the super class.
As I understand the inherited class should also inherit variables, so why doesn't this code work?
public class a {
private int num;
public static void main(String[] args) {
b d = new b();
}
}
class b extends a {
public b() {
num = 5;
System.out.println(num);
}
}
num variable's access modifier is private and private members are not accessible out of own class so make it protected it will accessible from subclass.
public class a {
protected int num;
...
}
Reference of Controlling Access to Members of a Class
As i understand the inherited class should inherit also variables,
you got it wrong, instance variables are not overriden in sub-class. inheritence and polymorphism doesnt apply for instance fields. they are only visible in your sub-class if they are marked protected or public. currently you have super class variable marked private. no other class can access it. mark it either protected or public in-order for other class's to access it.
public class A{
public int num=5;
public static void main(String[] args) {
b d = new b();
d.c();
}
}
class b extends A
{
public void c()
{
System.out.println(num);
}
}
definitely this is what you need i think
private scope can only be accessed by the containing class.
For this to work num would need to be declared protected scope.
However this would also make it accessible to other classes in the same package. My recommedation would be to create a get / set method in order to maintain proper encapsulation.
you could then access num in class b by calling getNum()
Because you are using the private access modifier. If you use private to a instance variable or to a method it only can access inside the class only(even several classes include one source file). We can expose private variable to outside by using getters and setters. Following code will compile without an error
public class A {
private int num;
public void setNum(int num)
{
this.num = num;
}
public int getNum()
{
return num;
}
public static void main(String[] args)
{
B d = new B();
}
}
class B extends A
{
public B()
{
SetNum(5);
System.out.println(getNum());
}
}
You don't have access to private members of the base classes from the subclass. Only the members with modifiers of private/protected
I have code like this I need to access the mysample variable of static class InnerClass in the getInnerS() method which is inside the the NestedClass. I tried accessing it by creating a new object for InnerClass but i am getting java.lang.StackOverflowError.
public class NestedClass{
private String outer = "Outer Class"; //NestedClass instance variable
NestedClass.InnerClass innerClass = new NestedClass.InnerClass();
void getOuterS(){
System.out.println(outer);
}
void getInnerS(){
System.out.println(innerClass.mysample);
}
static class InnerClass{
private String mysample = "Inner Class"; //InnerClass instance variable,
NestedClass a = new NestedClass();
void getIn(){
System.out.println(mysample);
}
void getOut(){
System.out.println(a.outer);
}
}
public static void main(String[] args){
NestedClass nestedClass = new NestedClass();
NestedClass.InnerClass nestedInner = new NestedClass.InnerClass();
nestedClass.getOuterS();
nestedClass.getInnerS();
nestedInner.getIn();
nestedInner.getOut();
}
}
In InnerClass constructor:
NestedClass a = new NestedClass();
So, you create a new NestedClass, which creates a new InnerClass, which creates itself its own NestedClass, with the corresponding InnerClass.... No wonder the stackoverflow.
If you want to access the enclosing class, you should use (inside InnerClass methods)
NestedClass.this
NestedClass a = new NestedClass();
in static InnerClass class creates an instance of the NestedClass and as InnerClass is static this is a loop.
InnerClass does not need to be static, this should work
public class NestedClass {
private String outer = "Outer Class"; //NestedClass instance variable
NestedClass.InnerClass innerClass = new NestedClass.InnerClass();
void getOuterS(){
System.out.println(outer);
}
void getInnerS(){
System.out.println(innerClass.mysample);
}
class InnerClass{
private String mysample = "Inner Class"; //InnerClass instance variable,
NestedClass a = NestedClass.this;
void getIn(){
System.out.println(mysample);
}
void getOut(){
System.out.println(a.outer);
}
}
public static void main(String[] args){
NestedClass nestedClass = new NestedClass();
NestedClass.InnerClass nestedInner = nestedClass.innerClass;
nestedClass.getOuterS();
nestedClass.getInnerS();
nestedInner.getIn();
nestedInner.getOut();
}
}
With this solution member class is static. For better comparison you might read
Static class declarations
Static nested classes (description)
Static nested classes do not have access to non-static fields and methods of the outer class, which in some ways similar to the static methods defined within the class. Access to non-static fields and methods can only be done through an instance reference of the outer class. In this regard, static nested classes are very similar to any other top-level classes.
In addition, static nested classes have access to any static methods of the outer class, including to private.
The benefits of these classes is mainly in logical groupings of entities to improve encapsulation, as well as saving class-space.
public class NestedClass{
private static String outer = "Outer Class"; //NestedClass instance variable
InnerClass innerClass = new InnerClass();
void getOuterS(){
System.out.println(outer);
}
void getInnerS(){
System.out.println(InnerClass.mysample);
}
InnerClass getInner(){
return innerClass;
}
static class InnerClass{
private static String mysample = "Inner Class"; //InnerClass instance variable,
void getIn(){
System.out.println(mysample);
}
void getOut(){
System.out.println(outer); //access a static member
}
}
public static void main(String[] args){
NestedClass nestedClass = new NestedClass();
NestedClass.InnerClass nestedInner = nestedClass.getInner();
nestedClass.getOuterS();
nestedClass.getInnerS();
nestedInner.getIn();
nestedInner.getOut();
}
}
Why java compiler is not restricting from accessing a private attribute from other class?
I have inner class which has a attribute 'a' with modifier 'private'. I can able to access this variable with its instance variable out side the class. see the code below.
package com.test;
public class Test {
public Test() {
}
public static void main(String[] args) {
new Test().execute(); // test method
}
public void execute() {
InnerClass innerClassInstance = new InnerClass();
// accessing private member from other class instance, HOW?
System.out.println(innerClassInstance.a);
InnerStaticClass innerStaticClassInstance = new InnerStaticClass();
// accessing private member from other class instance, HOW?
System.out.println(innerStaticClassInstance.a);
}
private final class InnerClass {
private int a; // accessible only in InnerClass??
}
private final static class InnerStaticClass {
private int a; // accessible only in InnerClass??
}
}
A nested class is a member of its enclosing class. Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
Sorry, I misread the question.
Looks at JLS http://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.1
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
So, a field in inner-class (which is obviously inside class body) can be accessed by outer class even if it's private.
See the Java language specification:
Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
your Inner class is a member of your Test class so, Test class can access private member of Inner class too.
Try like this it will give compile error
public class Test {
public Test() {
}
public static void main(String[] args) {
new Test().execute(); // test method
}
public void execute() {
InnerClass innerClassInstance = new InnerClass();
// accessing private member from other class instance, HOW?
System.out.println(innerClassInstance.a);
InnerStaticClass innerStaticClassInstance = new InnerStaticClass();
// accessing private member from other class instance, HOW?
System.out.println(innerStaticClassInstance.a);
}
}
class InnerClass {
private int a; // accessible only in InnerClass??
}
final class InnerStaticClass {
private int a; // accessible only in InnerClass??
}
These nested classes are meant for that .When you have private
members in a class ,we write nested class to do unit testing.