Access modifiers inheritance: on abstract methods - java

On one hand, I have an abstract class with an abstract method.
On the other hand, I have a child class which overrides the abstract method and specifies the "public" access modifier to it.
Is it meaningful at all what visibility I give to my original abstract class' abstract method?

In Java, subclasses are allowed to "increase" the visibility of a method when overriding it, but not "decrease" it. I.e. a protected method can be overridden and made public, but a public method can't be overridden and made protected.
The meaning of keeping a superclass method protected (not necessary to have the superclass or the method abstract here) is that it allows subclasses to override the method and either keep it protected or make it public. If the superclass makes the method public, then that forces any subclass that overrides that method to have that method remain public.
The JLS, Section 8.4.8.3, covers these requirements:
The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, as follows:
If the overridden or hidden method is public, then the overriding or hiding method must be public; otherwise, a compile-time error occurs.
If the overridden or hidden method is protected, then the overriding or hiding method must be protected or public; otherwise, a compile-time error occurs.
If the overridden or hidden method has package access, then the overriding or hiding method must not be private; otherwise, a compile-time error occurs.

Related

What cases can access modifiers be different when using inheritance?

I've been using Java for a while, largely self-taught. But I am a bit confused about access modifiers and it's bugging me because I have the OCA exam later this week and it's the only topic that I'm not very strong with.
If we have a class with a protected method and we extend that class and override that method using public, that's ok. We went from having a protected method to a public method. My question is, in what other cases can the access modifiers be different?
Thanks in advance!
The exact rules are given by JLS 8.4.8.3. Requirements in Overriding and Hiding.
The access modifier of an overriding or hiding method must provide at least as much access as the overridden or hidden method, as follows:
If the overridden or hidden method is public, then the overriding or hiding method must be public; otherwise, a compile-time error occurs.
If the overridden or hidden method is protected, then the overriding or hiding method must be protected or public; otherwise, a compile-time error occurs.
If the overridden or hidden method has package access, then the overriding or hiding method must not be private; otherwise, a compile-time error occurs.
It must be this way. If you could override a method with a more restrictive access, this would violate the Liskov Substitutability Principle (LSP). The LSP says that you should be able to use an instance of a subtype wherever you can use an instance of the supertype.

When should I override superclass's methods in a subclass? Must all superclass's methods be overridden if there are no extra functionality?

I have a superclass and subclasses that inherits the superclass. The superclass contains 6 methods but my subclasses only have a different implementation of 1 of the superclass's methods which needs to be overridden. Do I still have to override the remaining 5 methods in the subclass by doing, ie;
#Override
public void someMethod(String someString) {
super.someMethod(someString);
}
I feel like it's redundant to do so but when calling someMethod in the subclass, will it execute the superclass's methods if it's not overridden or will there be an error? I'm not sure what's good programming practice as I'm new to Java.
No, you don't have to override other methods if you do not change their implementation, that's what inheritance means. And this is a good practice of reusing your code to avoid repeating yourself.
when calling someMethod in subclass, will it execute the superclass's
methods if it's not overridden or will there be an error?
Yes, it will. No error will be thrown unless the method you call is visible to subclasses.
As per official Oracle documentation,
The ability of a subclass to override a method allows a class to inherit from a superclass whose behavior is "close enough" and then to modify behavior as needed. The overriding method has the same name, number and type of parameters, and return type as the method that it overrides. An overriding method can also return a subtype of the type returned by the overridden method. This subtype is called a covariant return type.
When overriding a method, you might want to use the #Override
annotation that instructs the compiler that you intend to override a
method in the superclass. If, for some reason, the compiler detects
that the method does not exist in one of the superclasses, then it
will generate an error.
So I would recommend reading the official document.

Rules to redeclare abstract method public? [duplicate]

The Java compiler doesn't complain when I override a protected method with a public method. What's really happening here? Is it overriding or hiding the parent method since the parent method has lower visibility?
A sub-class can always widen the access modifier, because it is still a valid substitution for the super-class. From the Java specification about Requirements in Overriding and Hiding:
The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, as follows:
If the overridden or hidden method is public, then the overriding or hiding method must be public; otherwise, a compile-time error occurs.
If the overridden or hidden method is protected, then the overriding or hiding method must be protected or public; otherwise, a compile-time error occurs.
If the overridden or hidden method has default (package) access, then the overriding or hiding method must not be private; otherwise, a compile-time error occurs.
From the point of view of an external class, the public method is just a new method, not an overriding method, since the external class could not access the protected method anyway.
On the other hand, lowering the visibility is not allowed because the external class can always use a reference of the type of a super-class to reference an object of the sub-class and call the same method.
The visibility only affects external accessibility. Being a public method any external class can call it.
Access level of the overriding method doesn't affect visibility of the original method. After override, with any access levels, the original method can only be accessed by calling super in the subclass.

What is distinction between subclass of superclass in same package and different package?

What is difference between this two sentence :
AA- a subclass within the same package as the instance's superclass can override any superclass method that is not declared private or final.
BB- a subclass in a different package can only override the non-final methods declared public or protected.
I believe each method can be overriden from it's superclass if it is not final
in java private methods are "automatically final, and hidden from the derived class"
in java any non-static methods can be public , protected or private
So from sentence AA I conclude that only public and protected superclass's methods can be overriden
and the same from sentenceBB
So I confused what is the distinction between 2 sentences?
The Sentences from your source are a bit unclear actually.
Sentence A also includes the default declared methods. This is also referred to as "package private". This happens if you just ommit the access modifier on your method.
Classes outside of the package won't be able to override them.

Java - Making inherited variables PRIVATE

I need to make my inherited instance variables private; is this possible?
IE, Superclass "Entity" has an int instance variable "health".
How can subclass "Zombie" (Extends "Entity") inherit the health variable from Entity, and have it private? I don't want other classes to be able to directly access the health variable, I want set and get methods for it.
Tell me if I wasn't specific enough; any help appreciated.
Simply : you can't.
This would break the contract of the superclass. Your class, being an Entity, exposes, like its superclass, a field named health. If you had the ability to make it private, all code using this field in instances of Entity (including instances of subclasses of Entity) would break with your class...
If you can, change the superclass (ie Entity) to make the field private. That's the common practice.
Make the variable private in the superclass and let all subclasses use accessor methods.
A second choice would be to make it package-private and arrange for those classes to which you want to deny access to be in another package. This would make sense if your Zombie is especially close to Entity (shares many internals) whereas other classes are more loosely coupled to their superclass.
You cannot decrease the visibility of any instance variable or method of the super class in your subclass..
Suppost you have super class with a public method.. And, suppose you were allowed to decrease the visibility to private in sub class..
Then see what's happens when you create object like this, and access that method of super class: -
SuperClass obj = new SubClass();
obj.pubMethod();
Now, at compile time, compiler sees that method pubMethod() is public in SuperClass, it will allow the access.. Note it does not check for the instance type on the RHS..
Now, at runtime, when JVM checks that the instance is of SubClass, then the actual method it would try to invoke will be searched in the SubClass..
But wait.. Did you see what happened when JVM went to search for pubMethod in SubClass that you made private.. BOoooooMMM -- A Crash..
That's why it is not allowed..
So, you cannot make it private..
From JLS Section - 8.4.8.3: -
The access modifier (§6.6) of an overriding or hiding method must
provide at least as much access as the overridden or hidden method, or
a compile-time error occurs. In more detail:
If the overridden or hidden method is public, then the overriding or hiding method must be public; otherwise, a compile-time error
occurs.
If the overridden or hidden method is protected, then the overriding or hiding method must be protected or public; otherwise,
a compile-time error occurs.
If the overridden or hidden method has default (package) access, then the overriding or hiding method must not be private;
otherwise, a compile-time error occurs.
You cannot add restrictions to an instance variable in a subclass, i.e. of health is protected in Enitity it cannot be private in Zombie (you can make it public).
However, you can make health private in Entity and define a protected getter and setter there. Subclasses can use these methods.

Categories