Can final keyword be used for a method?
Absolutely! The final keyword can be applied to just about anything, in each case meaning "you don't get to change this anymore."
Here's what it means when applied to...
a variable: You simply cannot assign the variable a new value (rendering it a constant, of course)
a method: You cannot re-implement (i.e., override) this method in a subclass
a class: You cannot define a subclass
In each case we're simply indicating: once this thing is declared, this is the last value (or implementation) you'll ever see for it.
Yes, it is possible to declare a method as final. That will mean that a method cannot be overridden by its subclasses.
From The Java Language Specifications, Third Edition, Section 8.4.3.3:
A method can be declared final to
prevent subclasses from overriding or
hiding it. It is a compile-time error
to attempt to override or hide a final
method.
For more information, the Writing Final Classes and Methods page from The Java Tutorials has more information.
Yes.
You can make a method final
public class A {
public static final void f() {
System.out.println("test");
}
}
There are typically two reasons for making a method final
When a method is final, it "may" be inlined.
When a method is final, the method is impossible to override.
Sure can. Making it impossible to override.
Sure, check out The Final Word on the Final Keyword
public abstract class AbstractBase
{
public final void performOperation() // cannot be overridden
{
prepareForOperation();
doPerformOperation();
}
protected abstract void doPerformOperation(); // must override
}
Yes.
A final method cannot be overridden by subclasses. This is often used to prevent subclasses from altering crucial behaviors of the class.
As a note to the other answers. You can use final. In practice I rarely see people using it and I'm not sure why.
A lot of the code I write these days is intended for multi-threaded environments and I tend to make the class final an immutable (if its a value class) so that it is threadsafe.
The problem with marking some methods as final (and not others) is that you are stating that there is something special about that method and nothing special about the others. That's rarely what people actually mean in my experience.
If a class is intended for inheritence you need to keep it clean and keep it small to prevent unwanted side-effects. All this depends on whether you are writing code for your self and your team or whether you are writing for a wider audience - i.e. a public api on an Open Source project or a commercial project.
yes, final keyword can be used for a method. It will preserve the immutability. it prevents between methods from being broken. For example, suppose the implementation of some method of class X assumes that method M will behave in a certain way. Declaring X or M as final will prevent derived classes from redefining M in such a way as to cause X to behave incorrectly.
Related
As succinctly described here, overriding private methods in Java is invalid because a parent class's private methods are "automatically final, and hidden from the derived class". My question is largely academic.
How is it not a violation of encapsulation to not allow a parent's private method to be "overridden" (ie, implemented independently, with the same signature, in a child class)? A parent's private method cannot be accessed or inherited by a child class, in line with principles of encapsulation. It is hidden.
So, why should the child class be restricted from implementing its own method with the same name/signature? Is there a good theoretical foundation for this, or is this just a pragmatic solution of some sort? Do other languages (C++ or C#) have different rules on this?
You can't override a private method, but you can introduce one in a derived class without a problem. This compiles fine:
class Base
{
private void foo()
{
}
}
class Child extends Base
{
private void foo()
{
}
}
Note that if you try to apply the #Override annotation to Child.foo() you'll get a compile-time error. So long as you have your compiler/IDE set to give you warnings or errors if you're missing an #Override annotation, all should be well. Admittedly I prefer the C# approach of override being a keyword, but it was obviously too late to do that in Java.
As for C#'s handling of "overriding" a private method - a private method can't be virtual in the first place, but you can certainly introduce a new private method with the same name as a private method in the base class.
Well, allowing private methods to be overwritten will either cause a leak of encapsulation or a security risk. If we assume that it were possible, then we’d get the following situation:
Let's say that there's a private method boolean hasCredentials() then an extended class could simply override it like this:
boolean hasCredentials() { return true; }
thus breaking the security check.
The only way for the original class to prevent this would be to declare its method final. But now, this is leaks implementation information through the encapsulation, because a derived class now cannot create a method hasCredentials any more – it would clash with the one defined in the base class.
That’s bad: lets say this method doesn’t exist at first in Base. Now, an implementor can legitimately derive a class Derived and give it a method hasCredentials which works as expected.
But now, a new version of the original Base class is released. Its public interface doesn’t change (and neither do its invariants) so we must expect that it doesn’t break existing code. Only it does, because now there’s a name clash with a method in a derived class.
I think the question stems from a misunderstanding:
How is it /not/ a violation of encapsulation to not allow a parent's private method to be "overridden" (ie, implemented independently, with the same signature, in a child class)
The text inside the parentheses is the opposite of the text before it. Java does allow you to “independently implement [a private method], with the same signature, in a child class”. Not allowing this would violate encapsulation, as I’ve explained above.
But “to not allow a parent's private method to be "overridden"” is something different, and necessary to ensure encapsulation.
"Do other languages (C++ or C#) have different rules on this?"
Well, C++ has different rules: the static or dynamic member function binding process and the access privileges enforcements are orthogonal.
Giving a member function the private access privilege modifier means that this function can only be called by its declaring class, not by others (not even the derived classes). When you declare a private member function as virtual, even pure virtual (virtual void foo() = 0;), you allow the base class to benefit from specialization while still enforcing the access privileges.
When it comes to virtual member functions, access privileges tells you what you are supposed to do:
private virtual means that you are allowed to specialize the behavior but the invocation of the member function is made by the base class, surely in a controlled fashion
protected virtual means that you should / must invoke the upper class version of the member function when overriding it
So, in C++, access privilege and virtualness are independent of each other. Determining whether the function is to be statically or dynamically bound is the last step in resolving a function call.
Finally, the Template Method design pattern should be preferred over public virtual member functions.
Reference: Conversations: Virtually Yours
The article gives a practical use of a private virtual member function.
ISO/IEC 14882-2003 §3.4.1
Name lookup may associate more than one declaration with a name if it finds the name to be a function name; the declarations are said to form a set of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded. The access rules (clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name’s declaration used further in expression processing (clause 5).
ISO/IEC 14882-2003 §5.2.2
The function called in a member function call is normally selected according to the static type of the object expression (clause 10), but if that function isvirtualand is not specified using aqualified-idthen the function actually called will be the final overrider (10.3) of the selected function in the dynamic type of the object expression [Note: the dynamic type is the type of the object pointed or referred to by the current value of the object expression.
A parent's private method cannot be accessed or inherited by a child class, inline with principles of encapsulation. It is hidden.
So, why should the child class be
restricted from implementing its own
method with the same name/signature?
There is no such restriction. You can do that without any problems, it's just not called "overriding".
Overridden methods are subject to dynamic dispatch, i.e. the method that is actually called is selected at runtime depending on the actual type of the object it's called on. With private method, that does not happen (and should not, as per your first statement). And that's what is meant by the statement "private methods can't be overridden".
I think you're misinterpreting what that post says. It's not saying that the child class is "restricted from implementing its own method with the same name/signature."
Here's the code, slightly edited:
public class PrivateOverride {
private static Test monitor = new Test();
private void f() {
System.out.println("private f()");
}
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
});
}
}
class Derived extends PrivateOverride {
public void f() {
System.out.println("public f()");
}
}
And the quote:
You might reasonably expect the output to be “public f( )”,
The reason for that quote is that the variable po actually holds an instance of Derived. However, since the method is defined as private, the compiler actually looks at the type of the variable, rather than the type of the object. And it translates the method call into invokespecial (I think that's the right opcode, haven't checked JVM spec) rather than invokeinstance.
It seems to be a matter of choice and definition. The reason you can't do this in java is because the specification says so, but the question were more why the specification says so.
The fact that C++ allows this (even if we use virtual keyword to force dynamic dispatch) shows that there is no inherent reason why you couldn't allow this.
However it seem to be perfectly legal to replace the method:
class B {
private int foo()
{
return 42;
}
public int bar()
{
return foo();
}
}
class D extends B {
private int foo()
{
return 43;
}
public int frob()
{
return foo();
}
}
Seems to compile OK (on my compiler), but the D.foo is not related to B.foo (ie it doesn't override it) - bar() always return 42 (by calling B.foo) and frob() always returns 43 (by calling D.foo) no matter whether called on a B or D instance.
One reason that Java does not allow override the method would be that they didn't like to allow the method to be changed as in Konrad Rudolph's example. Note that C++ differs here as you need to use the "virtual" keyword in order to get dynamic dispatch - by default it hasn't so you can't modify code in base class that relies on the hasCredentials method. The above example also protects against this as the D.foo does not replace calls to foo from B.
When the method is private, it's not visible to its child. So there is no meaning of overriding it.
I apologize for using the term override incorrectly and inconsistent with my description. My description describes the scenario. The following code extends Jon Skeet's example to portray my scenario:
class Base {
public void callFoo() {
foo();
}
private void foo() {
}
}
class Child extends Base {
private void foo() {
}
}
Usage is like the following:
Child c = new Child();
c.callFoo();
The issue I experienced is that the parent foo() method was being called even though, as the code shows, I was calling callFoo() on the child instance variable. I thought I was defining a new private method foo() in Child() which the inherited callFoo() method would call, but I think some of what kdgregory has said may apply to my scenario - possibly due to the way the derived class constructor is calling super(), or perhaps not.
There was no compiler warning in Eclipse and the code did compile. The result was unexpected.
Beyond anything said before, there's a very semantic reason for not allowing private methods to be overridden...THEY'RE PRIVATE!!!
If I write a class, and I indicate that a method is 'private', it should be completely unseeable by the outside world. Nobody should be able access it, override it, or anything else. I simply ought to be able to know that it is MY method exclusively and that nobody else is going to muck with it or depend on it. It could not be considered private if someone could muck with it. I believe that it's that simple really.
A class is defined by what methods it makes available and how they behave. Not how those are implemented internally (e.g. via calls to private methods).
Because encapsulation has to do with behavior and not implementation details, private methods have nothing to do with the idea encapsulation. In a sense, your question makes no sense. It's like asking "How is putting cream in coffee not a violation of encapsulation?"
Presumably the private method is used by something that is public. You can override that. In doing so, you've changed behavior.
I mean, obviously, there is no benefit on the polymorphic side,
and declaring (all of) these methods as final would prevent me from overriding them.
And I know IT IS possible to do, and the compiler doesn't prevent you from doing it.
I would love to get a usage example...
There are some marginal cases where such design, if perhaps not optimal, could at least be motivated. For example, you may have a system of classes, all subclasses of a common parent, where each subclass implements a further interface. There may be a set of interfaces with different formalities, but the same essential function.
In that particalar case it wouldn't hurt to make all the methods final and let each subclass add its own methods which make use of them.
I'd say it's part of the "core" component. You build something and you design the architecture, and you know that that method should never be changed.
The abstract class could have package access to some internal methods.
In this case we have
an incomplete class
functionality has to stay the same and grants secured access to the internal model
That is all we need to declare a type abstract and all its methods final. Consider as an example a Panel class that holds the graphics, but not always offers a method to actually make it draw itself - subclasses can have different drawing behaviourse. On the other hand it can offer a final protected DrawBuffer makeCircle() or something like that which, for some reason, has to access the internal model to make a DrawBuffer.
The JIT can take benefit when some methods declared in such way, when it cannot be overridden. (static, private, final, in final class)
let's imagine you have classes:
abstract class A {
public void doSomething() {
// default and only realization;
}
}
class B extends A { ... }
Then you write something like:
A a = MyAFactory.createA();
a.doSomething();
When method cannot be known to be final, and there is possible (even if not loaded just now) overridings, compiler makes second line to invoke virtual method. I.e. first it will determine which exactly class A, then looking in virtual method table, and only then call to particular methods.
But! If method is known as it cannot be overridden, then compiler can place to this point direct call to A.doSomething().
So, it is recommended to make method final unless you need them to be overridden.
Let's imagine class like this:
abstract class C {
public abstract int getMin();
public abstract int getMax();
public final int getSize() {
return getMax() - getMin();
}
}
in this example, it is obvious behavior of getSize() and hardly to imagine when it needs to be changed. So, declaring it final, not only gives a benefit by discarding virtual invocation mechanism, but also protects from unintended override of method with particular and predefined behavior.
I have an abstract class with an abstract method, the parameters for which I want to be final - that is, I do not want to allow implementations of the abstract class & method to reassign the parameter.
EDIT: The motivation for this is not immutability per se, which is more to do with the design of the objects. (In fact, in my use case, the parameter is collection which will be mutated in the implementation of the abstract method.) Rather, I want to communicate to anyone implementing my abstract class/method that these variables should not be reassigned. I know that I can communicate that via the java-doc, but I was looking for something more contractual - that they would have to follow, rather than just be guided to follow.
In a non-abstract method, I can do this using the final keyword - for example:
public class MyClazz {
public void doSomething(final int finalParameter){
finalParameter++; // compile error - cannot assign a value to final variable
}
}
However, if I use the final keyword in an abstract method, this does not form part of the contract - that is, implementations of the abstract method do not require the final keyword, and the parameter can be reassigned:
public abstract class MyAbstractClazz {
public abstract void doSomething(final int finalVariable);
}
public class MyExtendedClazz extends MyAbstractClazz {
#Override
public void doSomething(int finalVariable) { // does not require final keyword
finalVariable++; // so the variable is modifiable
}
}
As pointed out in answers to this SO Question, the final keyword does not form part of the method signature, which is why the implementation of the abstract class does not require it.
So, there are two questions:
Why is the final keyword not part of the method signature? I understand that it isn't,
but I want to know if there's a particular reason why it isn't.
Given that the final keyword is not part of the method signature, is there an alternative way of making parameters in an abstract method unassignable?
Other research:
this SO question touches on the same issue, but doesn't either of my two questions. In fact, the second question is explicitly asked, but does not receive an answer.
lots of questions/blogs etc. on the final keyword refer to "the final word". However, with respect to this question, the relevant comment is as follows (which, while useful, doesn't address my two questions):
Note that final parameters are not considered part of the method signature, and are ignored by the compiler when resolving method calls. Parameters can be declared final (or not) with no influence on how the method is overriden.
I have an abstract class with an abstract method, the parameters for which I want to be final - that is, I do not want to allow implementations of the abstract class & method to reassign the parameter.
Why not? That's an implementation detail. It's unobservable to the calling code, so there's no reason why the abstract method should specify it. That's why it's not part of the method signature, either - just like synchronized isn't.
A method should implement its documented contract - but how it chooses to do so is up to it. The contract can't say anything useful about the finality of a parameter, as Java always uses pass-by-value.
Parameters are passed by value, if you call the method using certain variable, this variable wont get modified even if you reassign the parameter inside the method, that's why it doesn't make sense for final to be part of the contract.
As we use "default" keyword as a access specifier, and it can be used in switch statements as well with complete different purpose, So i was curious that is there any other keywords in java which can be used in more then one purposes
The "default" in the case of access modifier isn't a keyword - you don't write:
default void doSomething()
However, when specifying the default value of an attribute of annotations - it is.
switch (a) {
default: something();
}
and
public #interface MyAnnotation {
boolean bool() default true;
}
That, together with final as pointed out by Jon Skeet seems to cover everything. Perhaps except the "overloaded" for keyword:
for (initializer; condition; step) and for (Type element : collection)
You can't use default as an access specifier, so I don't think even that counts. (EDIT: As Bozho pointed out, it can be used in annotations.)
final means "can't be derived from / overridden" and "is read-only" which are two different - but related - meanings.
default can be used both in a switch and as a default value in an annotation (as pointed out by Bozho)
final means "can't be derived from / overridden" and "is read-only" which are two different - but related - meanings (as pointed out by Jon)
extends can be used both to specify the supertype of a class and can be used in wildcards and type variables to put a constraint (related but not exactly the same) (List<? extends Foo>)
super can be used to specify to something in a superclass of the current class, or in a wildcard to put a constraint (List<? super Foo>)
static means both "part of the class, not an instance" (for methods, attributes or initializers) and as a static import
class to declare a class (class Foo {}), or to refer to a class literal (Foo.class) (as answered by ILMTitan)
(for can be used in a normal for loop and the "enhanced" for, but that's more like overloading (as Bozho puts it so nicely) than really having two meanings)
Something no one else has mentioned yet: the class keyword has two different uses.
Declaring a class:
class Test{};
and indicating a class literal:
Class<Test> testClass = Test.class;
The final keyword can mean different things.
When modifying classes is means that the class cannot be subclassed.
When modifying a method, it means that the method cannot be Overridden.
When modifying a variable, it means that the variable cannot point to any other variable.
The default keyword is not used as an access specifier. The absence of private, protected and public means use of default.
Example:
class Test { // default access for class.
int A; // default access for the class member.
}
Some examples of Java keywords which find different use are:
final : A final class cannot be subclassed, a final method cannot be overridden, and a final variable can occur at most once as a left-hand expression.
Super: Used to access members of a class inherited by the class in which it appears, also used to forward a call from a constructor to a constructor in the superclass.
Static: Used to create static initialization blocks, also static members and static imports.
for:Used for the conventional for loop and the newer Java 1.5 enhanced for loop.
The static keyword associates methods and fields with a class instead of instances of that class, but it's also used to signify static initialization sections as in:
public class MyClass
{
private static int a;
static
{
a = 1;
}
public static void doSomethingCool()
{
...
}
}
Pascal's comment reminded me of static imports:
import static MyClass.doSomethingCool;
public class MyOtherClass
{
public void foo()
{
// Use the static method from MyClass
doSomethingCool();
}
}
I gave a look at java keywords but it seems that keywords are unique.. you can check yourself.
By the way default can't used as an access specifier, it's inherited when noone is specified.
Do we really use default as an access specifier? No specifier at all is "default". But you don't use the keyword that way.
final has different uses:
in a variable declaration it means a variable can't be changed.
In a method signature it means a method can't be overridden
In a parameter list it means a variable can't be altered in a method.
The "extends" keyword can be for single inheritance (either implementation or "pure abstract class" aka "interface inheritance" in Java).
The "extends" keyword can also be used for multiple (interface) inheritance.
The ones who always argue that Java doesn't support multiple inheritance will hence have a hard time arguing that "extends" in those two cases is doing exactly the same thing.
Now I'm in the other camp: I consider that multiple interface inheritance is multiple inheritance and that implementation inheritance is just an OOP detail (that doesn't exist at the OOA/OOD level) and hence I consider that "extends" is really doing the same thing in both case and that hence my answer doesn't answer the question :)
But it's an interesting keyword nonetheless :)
You can think of the following things
Default
final
super
":" (colon) used at different places , which has a different meaning at different places
As all the other answers have stated, there are many keywords that server multiple purposes depending on context. I just wanted to add that there is a reason for this: There is a strong aversion to adding keywords because such additions break existing code, so when new features are added existing keywords are used if they make a reasonable fit, such as super and extends for generics and default for annotations, or they are just skipped as in the colon used in the enhanced for loop.
So my point is to expect that as the language continues to evolve even more uses are found for existing keywords rather than introducing new ones.
BTW there is no such thing as an access specifier in Java. The term in the JLS is 'access modifier'.
As succinctly described here, overriding private methods in Java is invalid because a parent class's private methods are "automatically final, and hidden from the derived class". My question is largely academic.
How is it not a violation of encapsulation to not allow a parent's private method to be "overridden" (ie, implemented independently, with the same signature, in a child class)? A parent's private method cannot be accessed or inherited by a child class, in line with principles of encapsulation. It is hidden.
So, why should the child class be restricted from implementing its own method with the same name/signature? Is there a good theoretical foundation for this, or is this just a pragmatic solution of some sort? Do other languages (C++ or C#) have different rules on this?
You can't override a private method, but you can introduce one in a derived class without a problem. This compiles fine:
class Base
{
private void foo()
{
}
}
class Child extends Base
{
private void foo()
{
}
}
Note that if you try to apply the #Override annotation to Child.foo() you'll get a compile-time error. So long as you have your compiler/IDE set to give you warnings or errors if you're missing an #Override annotation, all should be well. Admittedly I prefer the C# approach of override being a keyword, but it was obviously too late to do that in Java.
As for C#'s handling of "overriding" a private method - a private method can't be virtual in the first place, but you can certainly introduce a new private method with the same name as a private method in the base class.
Well, allowing private methods to be overwritten will either cause a leak of encapsulation or a security risk. If we assume that it were possible, then we’d get the following situation:
Let's say that there's a private method boolean hasCredentials() then an extended class could simply override it like this:
boolean hasCredentials() { return true; }
thus breaking the security check.
The only way for the original class to prevent this would be to declare its method final. But now, this is leaks implementation information through the encapsulation, because a derived class now cannot create a method hasCredentials any more – it would clash with the one defined in the base class.
That’s bad: lets say this method doesn’t exist at first in Base. Now, an implementor can legitimately derive a class Derived and give it a method hasCredentials which works as expected.
But now, a new version of the original Base class is released. Its public interface doesn’t change (and neither do its invariants) so we must expect that it doesn’t break existing code. Only it does, because now there’s a name clash with a method in a derived class.
I think the question stems from a misunderstanding:
How is it /not/ a violation of encapsulation to not allow a parent's private method to be "overridden" (ie, implemented independently, with the same signature, in a child class)
The text inside the parentheses is the opposite of the text before it. Java does allow you to “independently implement [a private method], with the same signature, in a child class”. Not allowing this would violate encapsulation, as I’ve explained above.
But “to not allow a parent's private method to be "overridden"” is something different, and necessary to ensure encapsulation.
"Do other languages (C++ or C#) have different rules on this?"
Well, C++ has different rules: the static or dynamic member function binding process and the access privileges enforcements are orthogonal.
Giving a member function the private access privilege modifier means that this function can only be called by its declaring class, not by others (not even the derived classes). When you declare a private member function as virtual, even pure virtual (virtual void foo() = 0;), you allow the base class to benefit from specialization while still enforcing the access privileges.
When it comes to virtual member functions, access privileges tells you what you are supposed to do:
private virtual means that you are allowed to specialize the behavior but the invocation of the member function is made by the base class, surely in a controlled fashion
protected virtual means that you should / must invoke the upper class version of the member function when overriding it
So, in C++, access privilege and virtualness are independent of each other. Determining whether the function is to be statically or dynamically bound is the last step in resolving a function call.
Finally, the Template Method design pattern should be preferred over public virtual member functions.
Reference: Conversations: Virtually Yours
The article gives a practical use of a private virtual member function.
ISO/IEC 14882-2003 §3.4.1
Name lookup may associate more than one declaration with a name if it finds the name to be a function name; the declarations are said to form a set of overloaded functions (13.1). Overload resolution (13.3) takes place after name lookup has succeeded. The access rules (clause 11) are considered only once name lookup and function overload resolution (if applicable) have succeeded. Only after name lookup, function overload resolution (if applicable) and access checking have succeeded are the attributes introduced by the name’s declaration used further in expression processing (clause 5).
ISO/IEC 14882-2003 §5.2.2
The function called in a member function call is normally selected according to the static type of the object expression (clause 10), but if that function isvirtualand is not specified using aqualified-idthen the function actually called will be the final overrider (10.3) of the selected function in the dynamic type of the object expression [Note: the dynamic type is the type of the object pointed or referred to by the current value of the object expression.
A parent's private method cannot be accessed or inherited by a child class, inline with principles of encapsulation. It is hidden.
So, why should the child class be
restricted from implementing its own
method with the same name/signature?
There is no such restriction. You can do that without any problems, it's just not called "overriding".
Overridden methods are subject to dynamic dispatch, i.e. the method that is actually called is selected at runtime depending on the actual type of the object it's called on. With private method, that does not happen (and should not, as per your first statement). And that's what is meant by the statement "private methods can't be overridden".
I think you're misinterpreting what that post says. It's not saying that the child class is "restricted from implementing its own method with the same name/signature."
Here's the code, slightly edited:
public class PrivateOverride {
private static Test monitor = new Test();
private void f() {
System.out.println("private f()");
}
public static void main(String[] args) {
PrivateOverride po = new Derived();
po.f();
});
}
}
class Derived extends PrivateOverride {
public void f() {
System.out.println("public f()");
}
}
And the quote:
You might reasonably expect the output to be “public f( )”,
The reason for that quote is that the variable po actually holds an instance of Derived. However, since the method is defined as private, the compiler actually looks at the type of the variable, rather than the type of the object. And it translates the method call into invokespecial (I think that's the right opcode, haven't checked JVM spec) rather than invokeinstance.
It seems to be a matter of choice and definition. The reason you can't do this in java is because the specification says so, but the question were more why the specification says so.
The fact that C++ allows this (even if we use virtual keyword to force dynamic dispatch) shows that there is no inherent reason why you couldn't allow this.
However it seem to be perfectly legal to replace the method:
class B {
private int foo()
{
return 42;
}
public int bar()
{
return foo();
}
}
class D extends B {
private int foo()
{
return 43;
}
public int frob()
{
return foo();
}
}
Seems to compile OK (on my compiler), but the D.foo is not related to B.foo (ie it doesn't override it) - bar() always return 42 (by calling B.foo) and frob() always returns 43 (by calling D.foo) no matter whether called on a B or D instance.
One reason that Java does not allow override the method would be that they didn't like to allow the method to be changed as in Konrad Rudolph's example. Note that C++ differs here as you need to use the "virtual" keyword in order to get dynamic dispatch - by default it hasn't so you can't modify code in base class that relies on the hasCredentials method. The above example also protects against this as the D.foo does not replace calls to foo from B.
When the method is private, it's not visible to its child. So there is no meaning of overriding it.
I apologize for using the term override incorrectly and inconsistent with my description. My description describes the scenario. The following code extends Jon Skeet's example to portray my scenario:
class Base {
public void callFoo() {
foo();
}
private void foo() {
}
}
class Child extends Base {
private void foo() {
}
}
Usage is like the following:
Child c = new Child();
c.callFoo();
The issue I experienced is that the parent foo() method was being called even though, as the code shows, I was calling callFoo() on the child instance variable. I thought I was defining a new private method foo() in Child() which the inherited callFoo() method would call, but I think some of what kdgregory has said may apply to my scenario - possibly due to the way the derived class constructor is calling super(), or perhaps not.
There was no compiler warning in Eclipse and the code did compile. The result was unexpected.
Beyond anything said before, there's a very semantic reason for not allowing private methods to be overridden...THEY'RE PRIVATE!!!
If I write a class, and I indicate that a method is 'private', it should be completely unseeable by the outside world. Nobody should be able access it, override it, or anything else. I simply ought to be able to know that it is MY method exclusively and that nobody else is going to muck with it or depend on it. It could not be considered private if someone could muck with it. I believe that it's that simple really.
A class is defined by what methods it makes available and how they behave. Not how those are implemented internally (e.g. via calls to private methods).
Because encapsulation has to do with behavior and not implementation details, private methods have nothing to do with the idea encapsulation. In a sense, your question makes no sense. It's like asking "How is putting cream in coffee not a violation of encapsulation?"
Presumably the private method is used by something that is public. You can override that. In doing so, you've changed behavior.