This question already has answers here:
Java protected fields vs public getters
(8 answers)
Closed 9 years ago.
my question is concerning about the "protected" access modifier.
I know its functionality, but I don't know when I need to use it.
Conceptually methods in a class could be divided as:
constructors
setters/getters
methods used from clients (i.e other classes)
internal methods (used from other methods in the class)
You use protected when
Your class is designed for inheritance - You expect the users of your library to inherit from the class that you are designing. Very often the class will be abstract.
The class provides special functionality to its derived classes that must not be visible to other classes - You know that derived classes must have access to information that would otherwise be private, or
The derived classes must provide functionality to the base class - See Template Method Pattern for information about this use of protected methods.
Note that protected methods are similar to public methods in the sense that once you put them in, they need to stay in for as long as you support your library. Unlike private methods that you can freely remove, protected methods remain a part of the interface of your class.
Use it when you need to do some internal stuff that is not exposed in public API but still needs to be overriden by subclasses.
You need to use the protected access modifier, when you want the descendant class to see the fields / methods of the super class, BUT you do not want other classes to see these.
One situation I've found it useful in is when a superclass's method is intended to call a subclass's method, e.g.
public abstract class SuperClass
public final void exposedMethod {
hiddenMethod();
}
abstract protected void hiddenMethod();
}
public class SubClass extends SuperClass {
protected void hiddenMethod() { }
}
In this case exposedMethod takes care of things like logging and retry logic, while hiddenMethod is the actual method implementation
A lot of classes in the java api use protected constructers so that you can only have instances of objects from other objects. Example: The Graphics class. It has a protected constructor, and a way to obtain a copy of the Graphics class is to have a Image object to call getGraphics() on.
A primary usage of protected methods is when a class expects its derived classes to override the method with its own features, and also call the base class version.
E.g.
public class Base
{
public void doStuff()
{
a(); b(); c();
}
protected void a(){ //does something
}
protected void b(){ //does something
}
protected void c(){ //does something
}
}
...
public class Derived extends Base
{
protected void b()
{
// Does something different before the original functionality.
super.b(); // Calls the original functionality
// Does something different after the original functionality.
}
}
...
public class Main
{
public static void main(String args[])
{
Base b = new Derived();
b.doStuff(); // Calls b.a(), ((Derived)b).b(), b.c()
}
}
You should always encapsulate your code to restrict access to the meet the exact level of access needed. Use the protected modifier when you need to only allow access to the code within the package or when its subclassed. I don't get what you mean by...
Conceptually methods in a class could be divided as: constructors setters/getters methods used from clients (i.e other classes) internal methods (used from other methods in the class)
Just put the access modifier infront of what you need to be labeled as "protected".
Related
In a java book I'm reading, a practice program takes the protected clone() method in the Object class and overrides it. When they do this tho, they expand the visibility modifier to public so it can be used in any package. I'm confused why this would need to be done though. If by definition, everything is a subclass of Object and a method is declared protected in the Object class. Wouldn't that mean every class would have access to it. What is the need to make the method public when overriding it? I'm confused.
You need to override it as public because you may wish to call it from a third class. Let's assume you have a Base class which has a subclass Child that overrides the method clone. Now I may have a third class as below.
public class Third {
public void m1(Child c) {
Child d = c.clone();
}
}
Here, class, Third is calling clone method, hence it needs to be declared public to be called.
This question already has answers here:
Protected in Interfaces
(15 answers)
Closed 5 years ago.
When I implement an interface method, I am forced to make it a public method.
We may have cases where we want to use either the default (like in case of access within the same package) or protected.
Can anyone please explain the reason behind this limitation?
Interfaces are meant to define the public API of a type - and only that, not its implementation. So any method (or static member) you define in an interface is by definition public.
Since an interface can't contain any concrete implementation, there is no way to call any member methods from within. And declaring such methods but leaving the calls to them to subclasses or totally unrelated clients would mean your type definition is incomplete and brittle. That is why if you need to define protected or package access members, you can do so in an abstract class (which may also contain implementation).
Maybe this will provide some answers.
To my knowledge, you use interfaces to allow people from outside your code to interact with your code. To do this, you need to define your methods public.
If you would like to force someone to override a given set of private methods, you might want to declare an abstract class with a series of abstract protected methods.
An interface is a contract that the class that implements it will have the methods in the interface. The interface is used to show the rest of the program that this class has the methods and that they could be called
EDIT: This answer is meant for C# interface implementations. In this case of Java the scenario is similar just that the syntactic analyzer wants a public keyword mentioned in the interface, which is implicitly done in C#
Interface methods are implicitly public in C# because an interface is a contract meant to be used by other classes. In addition, you must declare these methods to be public, and not static, when you implement the interface.
interface IStorable
{
void Read( );
void Write(object obj);
}
Notice that the IStorable method declarations for Read( ) and Write( ) do not include access modifiers (public, protected ..). In fact, providing an access modifier generates a compile error.
class Document : IStorable
{
public void Read( )
{
//
}
public void Write(object obj)
{
//
}
}
Just think about interfaces as Contracts to be implemented as public
If we mark a interface method as private the implementing class wont
see the method and cant override it.
If we mark a interface method as protected the implementing class
wont see the method unless it is in the same package as the
interface.
If we mark a interface method without any access modifier the
implementing class wont see the method unless it is in the same
package as the interface
Is there a reason one can change the access modifier of an overridden method? For instance,
abstract class Foo{
void start(){...}
}
And then change the package-private access modifier to public,
final class Bar extends Foo{
#Override
public void start(){...}
}
I'm just asking this question out of curiosity.
Java doesn't let you make the access modifier more restrictive, because that would violate the rule that a subclass instance should be useable in place of a superclass instance. But when it comes to making the access less restrictive... well, perhaps the superclass was written by a different person, and they didn't anticipate the way you want to use their class.
The programs people write and the situations which arise when programming are so varied, that it's better for language designers not to "second-guess" what programmers might want to do with their language. If there is no good reason why a programmer should not be able to make access specifiers less restrictive in a subclass (for example), then it's better to leave that decision to the programmer. They know the specifics of their individual situation, but the language designer does not. So I think this was a good call by the designers of Java.
Extending a class means the subclass should at least offer the same functionality to the other classes.
If he extends that, then it is not a problem.
Extending could be be either adding new methods or by offering existing methods to more classes like making a package-access method public.
There is only one, you might want the override to be visible by more classes, since no modifier is default, public broadens that.
The explaination is this:-
It's a fundamental principle in OOP: the child class is a fully-fledged instance of the >parent class, and must therefore present at least the same interface as the parent class. >Making protected/public things less visible would violate this idea; you could make child >classes unusable as instances of the parent class.
class Person{
public void display(){
//some operation
}
}
class Employee extends Person{
private void display(){
//some operation
}
Person p=new Employee();
Here p is the object reference with type Person(super class),when we are calling >p.display() as the access modifier is more restrictive the object
reference p cannot access child object of type Employee
Edit: OK, I changed my answer to fix the problem.
If that couldn't be done, then there would be some cases where a class wouldn't be able to implement an iterface and extend a class because they have the same method with different access modifiers.
public Interface A {
public void method();
}
public abstract classs B {
protected void method();
}
public class AB extends B implements A {
/*
* This would't be possible if the access modifier coulnd't be changed
* to less restrictive
*/
public void method();
}
Is it possible to define a private abstract class in Java? How would a Java developer write a construct like below?
public abstract class MyCommand {
public void execute()
{
if (areRequirementsFulfilled())
{
executeInternal();
}
}
private abstract void executeInternal();
private abstract boolean areRequirementsFulfilled();
}
You can't have private abstract methods in Java.
When a method is private, the sub classes can't access it, hence they can't override it.
If you want a similar behavior you'll need protected abstract method.
It is a compile-time error if a method declaration that contains the keyword abstract also contains any one of the keywords private, static, final, native, strictfp, or synchronized.
And
It would be impossible for a subclass to implement a private abstract method, because private methods are not inherited by subclasses; therefore such a method could never be used.
Resources :
JLS - 8.4.3. Method Modifiers
JLS - 8.4.3.1. abstract Methods
That would be protected instead of private. It means that only classes that extend MyCommand have access to the two methods. (So do all classes from the same package, but that's a minor point.)
What is the fragile base class problem in java?
A fragile base class is a common problem with inheritance, which applies to Java and any other language which supports inheritance.
In a nutshell, the base class is the class you are inheriting from, and it is often called fragile because changes to this class can have unexpected results in the classes that inherit from it.
There are few methods of mitigating this; but no straightforward method to entirely avoid it while still using inheritance. You can prevent other classes inheriting from a class by labelling the class declaration as final in Java.
A best practice to avoid the worst of these problems is to label all classes as final unless you are specifically intending to inherit from them. For those to intend to inherit from, design them as if you were designing an API: hide all the implementation details; be strict about what you emit and careful about what you accept, and document the expected behaviour of the class in detail.
A base class is called fragile when changes made to it break a derived class.
class Base{
protected int x;
protected void m(){
x++;
}
protected void n(){
x++; // <- defect
m();
}
}
class Sub extends Base{
protected void m(){
n();
}
}
It is widely described in below article By Allen Holub on JavaWorld
Why extends is evil.
Improve your code by replacing concrete base classes with interfaces
All of what Colin Pickard said is true, but here I want to add some of the best practices when you are writing code that may cause this kind of issue, and especially if you are creating a framework or a library.
Make all your concrete classes final by default, because you probably don't want them to be inherited. You can find this behavior as a feature of many languages, such as Kotlin. Besides, if you need to extend it, you can always remove the final keyword. In this way the absence of final on a class can be interpreted as a warning to not rely on specific functionality for other methods on this that are not private and/or final.
For classes that cannot be marked as final, make as many methods as possible final to ensure they're not modified by subclasses. Additionally, do not expose methods that are not meant to be overridden—prefer private over protected. Assume that any method not private and/or final will be overridden and ensure that your superclass code will still work.
Try to not use an inheritance ("Bar is a Foo") relationship. Instead use a helper ("Bar uses a Foo") relationship between your classes. Use interfaces rather than abstract classes to ensure that classes using this helper have a uniform interface.
Remember that almost* every extends can be replaced by implements. This is true event when you want to have a default implementation; an example of such a conversion is shown below:
Old Code:
class Superclass {
void foo() {
// implementation
}
void bar() {
// implementation
}
}
class Subclass extends Superclass {
// don't override `foo`
// override `bar`
#Override
void bar() {
// new implementation
}
}
New Code:
// Replace the superclass with an interface.
public interface IClass {
void foo();
void bar();
}
// Put any implementation in another, final class.
final class Superclass implements IClass {
public void foo() {
// implementation for superclass
}
public void bar() {
// implementation for superclass
}
}
// Instead of `extend`ing the superclass and overriding methods,
// use an instance of the implementation class as a helper.
// Naturally, the subclass can also forgo the helper and
// implement all the methods for itself.
class Subclass implements IClass {
private Superclass helper = new Superclass();
// Don't override `foo`.
public void foo() {
this.helper.foo();
}
// Override `bar`.
public void bar() {
// Don't call helper; equivalent of an override.
// Or, do call helper, but the helper's methods are
// guaranteed to be its own rather than possibly
// being overridden by yours.
}
}
The advantage of this is that the methods of the superclass are able to be sure they are working with one another, but at the same time you can override methods in your subclass.
*If you actually wanted the superclass to use your overridden method you are out of luck using this approach unless you also want to reimplement all of those methods on the "subclass". That said, the superclass calling the subclass can be confusing so it may be good to reevaluate that type of usage, its incompatibility with this approach notwithstanding.