Private method and subclasses [duplicate] - java

This question already has answers here:
What is the difference between public, protected, package-private and private in Java?
(30 answers)
Closed 2 years ago.
Suppose i have the following class structure. If i execute the child class, it will print both.
Inside Public method
Inside Private method
Could anyone explain the reason how the private method code is reachable to m1 ?
class Base
{
public void m1()
{
System.out.println("Inside Public method");
m2();
}
private void m2()
{
System.out.println("Inside Private method");
}
}
public class Child extends Base
{
public static void main(String[] args)
{
Child ob = new Child();
ob.m1();
}
}

Private variables/methods are accessible by everything within the class.
Protected variables/methods are accessible by everything within that package and any subclasses.
Public variables/methods are accessible by everything.

A private method is only visible in the class scope. The method m1 is in the same class as the private method m2 even if the m1 method is inherited.

You can do this with a reflection, what you can see here:
Method method = c.getDeclaredMethod("m2", null);
method.setAccessible(true);
method.invoke(obj, null);
Any way to Invoke a private method?

Private methods can be called by any method inside the class it is contained.
You can't call m2 method directly outside of the Base class scope, but you can call it indirectly through less restricted methods like public or protected.
Like you did with m1 method.
The caller class could not call m1 directly, but it will certain execute it. This is known as encapsulation. You use it to hide implementation details that doesn't matter for the caller.

Related

Why is this code calling a private method? [duplicate]

public class Shape
{
final private void print()
{
System.out.println("in class Shape");
}
public static void main(String[] args)
{
Shape shape=new Rectangle();
shape.print();
//calling shape class function
//giving output in class shape
}
}
public class Rectangle extends Shape
{
public void print()
{
System.out.println("in class Rectangle");
//super.print();
}
}
Ques: why private function don't show polymorphic behaviour ?
and we are still overriding final method?
its calling base class funtion why?
A Private function is not visible nor callable from its children; hence these are two completely different functions. There is nothing to overwrite from the perspective of the child class, because it is not aware that the parent even has a print() function.
Making it final private void print() is to prevent it from overriding in sub-classes.
As final prevents overriding and private makes the method invisible to the sub-classes so that it cant be accessed
See also :
Java `final` method: what does it promise?
Overriding private methods in Java
You are not actually over-ridden the print method because of private. They are completely different.
More over you cannot override a final method.
This is the place where #override annotation helps you better. If you try to place the annotation, then you realize the behaviour at compile time itself.
In addition to Eriks answer from the Java Language Specification:
A class C inherits from its direct superclass all concrete methods m (both static and instance) of the superclass for which all of the following are true:
m is a member of the direct superclass of C.
m is public, protected, or declared with package access in the same package as C.
No method declared in C has a signature that is a subsignature (§8.4.2) of the signature of m.
and
An instance method mC declared in or inherited by class C, overrides from C another method mA declared in class A, iff all of the following are true:
[...]
One of the following is true:
mA is public.
mA is protected.
So your subclass doesn't inherit the private methods, hence there is nothing to override.
Polymorphism is the capability of an action or method to do different
things based on the object that it is acting upon. In other words,
polymorphism allows you define one interface and have multiple
implementation. This is one of the basic principles of object oriented
programming.
The method overriding is an example of runtime polymorphism. You
can have a method in subclass overrides the method in its super
classes with the same name and signature. Java virtual machine determines the proper
method to call at the runtime, not at the compile time.
But if you will think as print() is instance method and at runtime why it is not calling from Rectangle print() method.
The reason is as print() of subclass is not a overriden method as parent class method is final which cannot be overriden.
Shape shape=new Rectangle();
shape.print(); // prints in the shape class
((Rectangle)shape).print(); //prints in the rectangle class
As parent's class method is private so it is not visible for outside world and as it is final it cannot be overriden.
In your example it is shown as private final method so this method is not visible out side the class. So Rectangle can't see the method defined inside Shape class.
public class A{
final private method1(){
}
final public method2(){
}
public method3(){
}
}
public class B extends A{
public method1(){
//it is legal. but it is not a override. this method can't see the method1 defined in A
}
public method2(){
//throw error. because final method can't be overriden
}
public method3(){
//legal override method
}
}

Why I am not able to call a.getHello()? [duplicate]

This question already has answers here:
private method in inheritance in Java
(6 answers)
How can a derived class invoke private method of base class?
(7 answers)
Closed 5 years ago.
public class A {
private void getHello(){
System.out.println("Prints A");
}
}
class B extends A {
public void getHello(){
System.out.println("Prints B");
}
}
class Test{
public static void main(String[] args) {
A a = new B();
}
}
I am creating private method in class A
creating public method with same name in class B by extending class A
Even after creating object for B with A reference
why I am not able to call getHello()?
getHello method is private for class A and you may call it only from this class.
Even if create an instance of class A in some other class you will not be able to access getHello() method.
This is also invalid code.
class Test {
public static void main(String[] args) {
A a = new A();
a.getHello();
}
}
Here is Java documentation.
Be declaring it as a type of A you are losing the implementation details of B although there still there.
A a = new B(); // a.getHello() is not accessible because it looks it up in A
B b = new B(); // a.getHello() is accessible because it calls it in B
Even if the getHello() method would be public in A it would still call it for the instance of B.
As Java Language Specification (https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6) states:
A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor. It is not inherited by subclasses.
When you create a reference to object of A class it is not possible to get access to this method from outside of this class in your case.

Why can I get access to static method of my super class from child instance? [duplicate]

This question already has answers here:
Are static methods inherited in Java?
(15 answers)
Closed 7 years ago.
Why is it possible to get access to the static method of my super class from child instance?
public class Test {
public static void main(String[] args) {
new UtilImpl().fun();
new AbstractUtil() {}.fun();
}
static abstract class AbstractUtil {
public static void fun() {
System.out.println("Fun!");
}
}
static class UtilImpl extends AbstractUtil {
}
}
I can agree with access to the static method of parent class from an instance of the parent class. But if I instantiate a child class, it's weird to have access to the static context of the parent class.
PS
And what are advantages of calling the static method on instance?
In Java, it is allowed to call static methods with an instance variable. This is defined in JLS section 8.4.3.2, quoting:
A method that is declared static is called a class method.
A class method is always invoked without reference to a particular object.
In such a case, Java will actually discard the instance you used and call the static method.
Example 15.12.4.1-1 expresses this in the following way:
When a target reference is computed and then discarded because the
invocation mode is static, the reference is not examined to see
whether it is null:
class Test1 {
static void mountain() {
System.out.println("Monadnock");
}
static Test1 favorite(){
System.out.print("Mount ");
return null;
}
public static void main(String[] args) {
favorite().mountain();
}
}
which prints:
Mount Monadnock
Here favorite() returns null, yet no NullPointerException is thrown.
It's called inheritance. A subclass inherits public members of the parent class, including static methods. The important thing is that the static method is not bound to any instance. You could just do:
UtilImpl.fun();
AbstractUtil.fun();
As far as the compiler is concerned, it's the same thing. The only difference is that your code creates objects but these are not relevant to the way the methods are called (plus as #Dici said in the comments you should have also gotten a warning from the compiler).

Why cannot we override static method in the derived class [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can we override static method in Java?
We cannot override the static methods of the base class.
Actually I tried something like this:
// Base class
public class StaticExampleImpl {
protected String name="overriding";
public static void display(){
System.out.println("static method display : base class");
}
}
Then the derived class is as follows:
//derived class
public class StaticDemo extends StaticExampleImpl {
// cannot override the static methods...
//#Override
public static void display(){
System.out.println("child!!! static method display");
}
public static void main(String[] args) {
StaticDemo d=new StaticDemo();
d.display(); // derived class display is called rather than Base class.
}
}
So, when I uncomment the #Override method, it gives error as "Static methods cannot be overriden". But with commenting it works fine. So, when we create the Objects and call the static methods with the instances, those work fine. so what is the difference??
because static methods are not get inherited.
When you uncomment #Override it means you are trying to override the
static method which is not possible thats why you are getting an
error.
But when you comment //#Override it means you are declaring a new
method in child class.
Static methods does not belong to an instance of a class, it belongs to the actual class.
When you call d.display();, you are really calling the static method of the StaticDemo d reference's static method.
if you did :
StaticExampleImpl d2 = new StaticDemo();d2.display(), you will find that it calls the base class's display.
However, don't do this. It leads to confusing code, and is a bad way to implement inheritance poorly.
Overriding depends the an instance of a class. polymorphismis that you can subclass a class and the objects implementing those subclasses will have different behaviors for those method defined in the superclass (and overridden in the subclasses) .static methods does not belong to an instance of a class so the concept is not applicable.
Static methods cannot be inherited. If you want to call the 'base' class static method, you have to explicitely call StaticExampleImpl.display().
Static methods are bound to class they can't be inherited thats why you can't have base class static method in derived class.
If you are trying to override a static method, there is probably something wrong with your design.
OOP and Polymorphism allows you to do the following:
public class MyClass1 {
public String toString() { return "MyClass1 Instance"; }
}
public class MyClass2 extends MyClass1 {
#Override
public String toString() { return "MyClass1 Instance"; }
}
public void printSomething(MyClass1 myclass1){
System.out.println(myclass1);
}
Inside printSomething, the toString method which is going to be called is the one on the runtime type of myClass1: when you pass inside printSomething an instance of MyClass2, its compile-type will be MyClass1 but its runtime type will be MyClass2
It is clear that to use polymorphism you need objects instances, where the actual runtime type could different from the compile type. Static methods however do not belong to any object instance, but to the class. Why don't you explain us what you are trying to achieve?
The following code:
StaticExampleImpl one = new StaticExampleImpl();
StaticDemo two = new StaticDemo();
StaticExampleImpl three = two;
one.display();
two.display();
three.display();
Will yield the following output:
static method display : base class
child!!! static method display
static method display : base class
As you can see, the method does not get inherited. This is why they are called 'static methods': they are called statically, not dynamically, as instance methods would be. The compile-time type of the class is what matters when calling static methods, not the runtime type.
This is also why you shouldn't call static methods through object instances. Always call them like this:
StaticExampleImpl.display();
StaticDemo.display();
This completely takes away the confusion that might (will) come up when people expect inheritance to work for these methods.
any static block in java, may be static variables, methods are loaded when the class is loaded. You probably know about class loader in java. So thing is static block (methods, variables or anything is static) is loaded once. So you can’t actually override any static block.
Commenting #Override means that you are writing another static method in sub class, but not just overriding base class method.

Confused with Java Overriding the access level [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why can't you reduce the visibility of a method in a java subclass?
How come I can override a private method in superclass with a public when in a subclass, but I cannot override a public method in the superclass into private method in subclass?
Why?
Thank you in advance.
Overriding a method can't ever reduce the visibility. Allowing that would violate the Liskov Substitution Principle, which states (simplified) that all objects of a derived class B must have the same properties as the base class A. In this case one such "property" would be a public method foo which would be "lost" if B had that same method, but made it protected.
Also, since private methods are not inherited (try calling it from a derived class!) they can't ever be overriden. You can have a public method with the same name as a private one in the base class, but that's not overriding, it's simply a new method with the same name, but not other relation. Calls to the private method in the base class will not call the public method in the superclass, even when executed on objects of the superclass!
In other words: private methods never use runtime polymorphism.
See this sample:
public static class Base {
public void callBoth() {
foo();
bar();
}
private void foo() {
System.out.println("Base.foo");
}
protected void bar() {
System.out.println("Base.bar");
}
}
public static class Sub extends Base {
public void foo() {
System.out.println("Sub.foo");
}
public void bar() {
System.out.println("Sub.bar");
}
}
When executing new Sub().callBoth() the output will be this:
Base.foo
Sub.bar
Because it doesn't break the class contract to make a method more available. If Kitten subclasses Animal, and Animal has a public method feed(), then Kitten must also have a public method feed(), as it must be possible to treat any instance of Kitten like an instance of Animal. Redefining the access level to private would break that.
If the public method became private, then it would not be possible to up cast the instance into its parent class (because one of the methods would be unavailable).
If the private method became public, then it would be possible to up case the instance into its parent class (because then you would just have no way to grab the private / publicly overriden method).
The access level can't be more restrictive than the overridden method.
private-->[default]-->protected-->public
By overriding you're saying that your subclass can be called with the same api but may function differently. Making something public increases the access level - so you're not removing guaranteed functionality.
By making a public method private (if you could actually do this) you'd be removing functionality, so breaking the "contract". It also doesn't make sense in that the method could still be called publicly, it's just that the public call would access the public method in the superclass, which would be counterintuitive.

Categories