I have this piece of code
public class Base {
private int x=10;
void show(){
System.out.println(x);
}
}
public class Child extends Base {
public static void main(String[] args) {
Child c1=new Child();
c1.show();
}
}
This piece of code is working fine and output is 10.Can anyone please
Elaborate how this private data member is access in child class..
It isn't. The show() method is accessed. That method of the parent then accesses the field x. The show() method has default access, which includes access by the Child as it is in the same package.
Related
I want to give a method an access that only the child classes and the current class can call.
For example:
public class Parent{
something void mySetterMethod(int input){
this.something = input;
}
}
public class Child extends Parent{
mySetterMethod(otherInput);
}
but this should not be able to work for:
public class SomeClassInSamePackage(){
public static void main(String[] args){
Parent parent = new Parent();
parent.mySetterMethod(input);
}
As a general piece of advice prefer composition over inheritance.
public class Parent {
public void mySetterMethod(int input){
this.something = input;
}
}
public class Child {
private final Parent parent = new Parent();
...
parent.mySetterMethod(otherInput);
...
}
You could just not call it from the same package.
As a historical note, Java 1.0 had private protected, although apparently it was buggy.
Today a fellow learner came up with an interesting query. We know that this keyword is used to refer to the current object. But I could not explain to him how this keyword behaves as seen in the following snippet. I know what inheritance is: allows access to parent class variables and methods. But are they copied into the memory area of child instance?, because I am able to use this keyword to access the parent class property.
I was able to refer to parent class variable. I searched and found that nothing gets copied virtually to child class, but why the following behavior happens? Please explain this case of using this.
class Parent {
int a=10;
}
public class Child extends Parent{
void m1(){
System.out.println(a);
System.out.println(this.a);
System.out.println(super.a);
}
public static void main(String[] args){
new Child().m1();
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The property a is inherited by Child. Therefore, you can use this.a in child to reference it.
Where was the problem supposed to be?
I searched and found that nothing gets copied virtually to child class
You have the wrong example to illustrate that statement.
The way to understand that is (roughly): "instance variables are not overridden when re-declared in subclasses, so you can't declare an instance as Parent and expect to get Child.a if the instance was created with new Child()". Here's an example of the problematic case:
class Parent {
int a = 10;
}
public class Child extends Parent{
int a = 12; //not overridden
public static void main(String[] args){
Parent child = new Child();
System.out.println(child.a); //This will print 10, not 12
}
}
System.out.println(child.a); will print 10 because variables instance fields don't get overridden. You get the value based on the declared type (Parent in this case)
When you instantiate a class Child it contains all members of itself and of Parent. However, private members of Parent are not accessible from Child:
class Parent {
private int p = 10;
}
public class Child extends Parent{
void m1(){
System.out.println(p); // compilation error
}
}
Another interesting case is when one instance of Parent tries to access a private field of another instance of Parent. What do you think happens?
public class Parent {
private int p = 11;
public boolean same(Parent other) {
return other.p == p;
}
}
You might think other.p will result in a compilation error since p is a private field. However, since privacy does not pertain to object instances, but to classes. So all private fields in Parent are visible within all Parent instances, so this works!
Consider below Code:
this is a reference variable which will point to the current object.
super is used to refer to Parent's property in case you have created
the same in the child.
class Product{
String color;
public Product() {
color = "Black";
}
}
class Mobile extends Product{
String color;
Mobile(){
color = "White";
}
void showMobileData(){
System.out.println("this hashCode is "+this.hashCode());
System.out.println("super hashCode is: "+super.hashCode());
System.out.println("color is: "+color);
System.out.println("this.color is: "+this.color);
System.out.println("super.color is: "+super.color);
}
}
public class Test {
public static void main(String[] args) {
//new Mobile().showMobileData();
Mobile mRef = new Mobile();
System.out.println("mRef HashCode: "+mRef.hashCode());
mRef.showMobileData();
}
}
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.
I want some discussions about this, but I could not infer the answer for my case. Still need help.
Here is my code:
package JustRandomPackage;
public class YetAnotherClass{
protected int variable = 5;
}
package FirstChapter;
import JustRandomPackage.*;
public class ATypeNameProgram extends YetAnotherClass{
public static void main(String[] args) {
YetAnotherClass bill = new YetAnotherClass();
System.out.println(bill.variable); // error: YetAnotherClass.variable is not visible
}
}
Some definitions following which, the example above seems to be confusing:
1. Subclass is a class that extends another class.
2. Class members declared as protected can be accessed from
the classes in the same package as well as classes in other packages
that are subclasses of the declaring class.
The question: Why can't I access the protected member (int variable = 5) from a subclass YetAnotherClass instance (bill object)?
Classes in other packages that are subclasses of the declaring class can only access their own inherited protected members.
package FirstChapter;
import JustRandomPackage.*;
public class ATypeNameProgram extends YetAnotherClass{
public ATypeNameProgram() {
System.out.println(this.variable); // this.variable is visible
}
}
... but not other objects' inherited protected members.
package FirstChapter;
import JustRandomPackage.*;
public class ATypeNameProgram extends YetAnotherClass{
public ATypeNameProgram() {
System.out.println(this.variable); // this.variable is visible
}
public boolean equals(ATypeNameProgram other) {
return this.variable == other.variable; // error: YetAnotherClass.variable is not visible
}
}
bill is not part of the subclassed YetAnotherClass. bill is a separate YetAnotherClass.
Try int bill = this.variable; (inside a constructor) to access the subclass' members.
Your code will work if YetAnotherClass will be in the same package as ATypeNameProgram. As others wrote it won't work in other cases. Here is the working example.
package my.example;
public class MainClass extends MyAnotherClass {
public static void main(String[] args) {
MyAnotherClass bill = new MyAnotherClass();
System.out.println(bill.value); // this will work
}
}
package my.example;
public class MyAnotherClass {
protected int value = 5;
}
A class Foo can only access the protected instance members of type Bar if and only if Bar is assignable to Foo. I.e., if we can write:
Foo foo = new Bar();
For example, say we have:
package a;
public class Base {
protected int protectedField;
}
Then we can have this:
package b;
import a.Base;
public class Parent extends Base {
void foo() {
int i = this.protectedField;
}
void foo(Parent p) {
int i = p.protectedField;
}
void foo(Child c) {
int i = c.protectedField;
}
}
class Child extends Parent { }
This will compile because all protectedFields are accessed via instances of Parent. Note that because a Parent reference can be a Child instance (i.e., we can write Parent p = new Child();), we can access c.protectedField.
The following will not compile:
package b;
import a.Base;
public class Parent extends Base {
void foo(Stepchild sc) {
int i = sc.protectedField; // ERROR
}
}
class Stepchild extends Base {}
because an instance of Stepchild is not an instance of Parent.
Somewhat confusingly, this won't compile either:
package b;
import a.Base;
public class Parent extends Base {}
class Child extends Parent {
void foo(Parent p) {
p.protectedField; // ERROR
}
}
this is because a Parent object isn't a superclass or superinterface of Child, and so Child can't access its protected members.
If you ever have trouble remembering, just think of whether or not the type can be written to a reference of the type of the class. E.g., we can write:
Parent p = new Child();
but cannot write
Child c = new Parent(); // ERROR
Parent p = new Stepchild(); // ERROR
so Child won't have access to Parent's protected members, and Parent won't have access to Stepchild's protected members.
A couple final points:
Remember that protected access allows visibility among the package. In my experience, people forget this.
Finally, protected static members are always visible among the inheritance hierarchy.
You aren't creating an instance of the class that extend it, but of the parent class. Check the code below:
public class ATypeNameProgram extends YetAnotherClass{
public static void main(String[] args) {
YetAnotherClass bill = new YetAnotherClass();
System.out.println(bill.variable); // error: YetAnotherClass.variable is not visible
ATypeNameProgram a = new ATypeNameProgram();
System.out.println(a.variable); //this will work
}
}
Lets say I have a class
public class Base {}
and a child class
public class Derived extends Base {
public void Foo(Object i){
System.out.println("derived - object");
}
}
and main class
public class Main {
public static void main(String[] args) {
Derived d = new Derived();
int i = 5;
d.Foo(i);
}
}
In console we will see
derived - object
Some time later I want to modify my superclass like this :
public class Base {
public void Foo(int i) {
System.out.println("base - int");
}
}
Now if I run my programm I will see:
base - int
So can I make a method in superclass not avaliable in my child class?
In result I want to see derived - object.
I see some don't understand what I want so I'll try to explain:
I want to modify only superclass and I don't want to modify my child class.. for example if I will make jar with my superclass and jar with my childs. I don't want to change all jars.. I want to add method into superclass and make it avaliable for superclass..
And such code
public class Main {
public static void main(String[] args) {
Derived d = new Derived();
int i = 5;
d.Foo(i);
Base b = new Base();
b.Foo(i);
}
}
give me
derived - object
base - int
You should use following signature for Foo method in base class:
public void Foo(Object i) {
System.out.println("base - int");
}
This way you can override method Foo from base class. Now you do not override this method but overload it instead.
If you want to use public void Foo(int i) signature in your base class then you can define Foo method in base class as private.
PS: I hope that I've understood you.
private members are limited to the class scope.
default (no keyword for this one) are limited to other members of the same package.
protected are limited to hierarchy.
public are not limited.
So if you don't want your child class to access a member of the superclass (member means methods, enum, variables ...) you should declare your foo like this :
public class Base {
private void Foo(int i) {
System.out.println("base - int");
}
}
Edit from my comment :
if you dont want child class to access a parent's member at compile time I can't see any way to still allow external classes to access it.
You want to block access from close scope while allowing broader scope. This can only be done by overriding the method and throwing an exception for accessviolation or something which is not at compile time but at runtime. Although you could make it work with a custom annotations but I don't know how to do this.
You can make a method final, which means, that the child class cannot override it.
If you do not do that and the child class overrides the method, you cannot call the super classes method from your main.
A Convention note: Please use lowercase method names in java.
package com.abc;
public class TestParentChild {
public static void main(String[] asd) {
Base b = new ChildB();
b.foo(5);
}
}
class Base {
public void foo(int i) {
System.out.println("derived - int");
}
}
class ChildB extends Base {
public void foo(int i) {
System.out.println("derived - object");
}
}
This might help you