FINAL keyword

K

kaja_love160

hello


1)
If method ( call it U ) in parent class is made private, then methods
of child class can’t access U directly, but they still inherit this
private method U.
Is it similar situation if parent method ( call it U1 ) is declared
final  Meaning child methods can’t access U1 directly, but they still
inherit it?



2)
Subclass can override parent’s class method by creating method with
same name and same parameter list --> this is not true if parent
method is declared private
So if compiler identifies a method by its name and its parameter list,
then why do we get compile-time error if “hey()†in B is private
( compiler informing us that “hey()†can’t be overriden ):


class A{

private final void hey(){…}

}

class B extends A{

private void hey(){…}
}






, while compiler doesn't complain when “hey()†in class B is made
public:

class A{

private final void hey(){…}

}

class B extends A{

public void hey(){…}
}


? That would suggest that when it comes to overriding method, java
doesn’t only distinguish between methods by their name and parameter
list, but also by their access modifier.

thank you
 
L

Lew

1)
If method ( call it U ) in parent class is made private, then methods
of child class can’t access U directly, but they still inherit this
private method U.

No.
A class C inherits from its direct superclass and direct superinterfaces all non-private methods (whether abstract or not) of the superclass and superinterfaces that are public, protected or declared with default access in the same package as C and are neither overridden (§8.4.8.1) nor hidden (§8.4.8.2) by a declaration in the class.

Also, methods don't inherit methods anyway, classes do.
Is it similar situation if parent method ( call it U1 ) is declared
final  Meaning child methods can’t access U1 directly, but they still
inherit it?

No. "final" (not "FINAL" as in your subject, because that's not a keyword)
does not mean "child methods can’t access [it] directly", and methods don't
inherit methods anyway. Classes inherit methods.

"final" does not control accessibility, only overridability.
2)
Subclass can override parent’s class method by creating method with
same name and same parameter list --> this is not true if parent
method is declared private

Correct so far.
So if compiler identifies a method by its name and its parameter list,
then why do we get compile-time error if “hey()†in B is private
( compiler informing us that “hey()†can’t be overriden ):

What is the error message? What is the actual code? Provide an SSCCE!

I cannot get any kind of error message from an attempt to "override" a private
method, final or not. Perhaps because it's not illegal?
class A{

private final void hey(){…}

}

This code doesn't compile.
class B extends A{

private void hey(){…}
}

This code doesn't compile.
, while compiler doesn't complain when “hey()†in class B is made
public:

class A{

private final void hey(){…}

}

class B extends A{

public void hey(){…}
}


? That would suggest that when it comes to overriding method, java
doesn’t only distinguish between methods by their name and parameter
list, but also by their access modifier.

Perhaps, if your facts were correct. My SSCCE didn't give anything like the
error you hinted about.
Compiling 1 source file to projects/testit/build/classes
compile:
run-single:
Parent.privFinal()
Parent.priv()
BUILD SUCCESSFUL (total time: 3 seconds)


<sscce comment="this code compiles and runs without compiler error"
source="testit/Child.java" >
/** Child.java
*/
package testit;

class Parent
{
private final void privFinal()
{
System.out.println("Parent.privFinal()");
}
private void priv()
{
System.out.println("Parent.priv()");
}
public final void invoke()
{
privFinal();
priv();
}
}

/** Child .
// warning: "Exporting non-public type through public API" from IDE.
*/
public class Child extends Parent
{
private void privFinal()
{
System.out.println("Child.privFinal()");
}
private void priv()
{
System.out.println("Child.priv()");
}
public static void main( String [] args )
{
Parent child = new Child();
child.invoke();
}
}
</sscce>

It compiles, it runs, it makes output.
 
E

Esmond Pitt

If method ( call it U ) in parent class is made private, then methods
of child class can’t access U directly, but they still inherit this
private method U.

Not in any useful sense, no, they don't inherit it at all.
Is it similar situation if parent method ( call it U1 ) is declared
final  Meaning child methods can’t access U1 directly, but they still
inherit it?

Adding 'final' to a private method has zero effect. It is already final.
2)
Subclass can override parent’s class method by creating method with
same name and same parameter list --> this is not true if parent
method is declared private

Exactly so.
So if compiler identifies a method by its name and its parameter list,
then why do we get compile-time error if “hey()†in B is private
( compiler informing us that “hey()†can’t be overriden ):

because A.hey() was declared final so it explicitly can't be overridden.
What the actual point of that rule is is a mystery to me. Possible
compiler bug, ask the language lawyers. I no longer am one ...
, while compiler doesn't complain when “hey()†in class B is made
public:

Possible compiler bug, see above.
? That would suggest that when it comes to overriding method, java
doesn’t only distinguish between methods by their name and parameter
list, but also by their access modifier.

It does indeed. It doesn't make much sense to me either, except that the
intent of whoever wrote private final void hey() in A was pretty clear
and the compiler is enforcing at least part of it.
 
R

Roedy Green

If method ( call it U ) in parent class is made private, then methods
of child class can’t access U directly, but they still inherit this
private method U.
Is it similar situation if parent method ( call it U1 ) is declared
final ? Meaning child methods can’t access U1 directly, but they still
inherit it?

final has to do with whether you can change a variable or override a
method or class.

It has nothing to do with visibility.

see http://mindprod.com/jgloss/final.html
http://mindprod.com/jgloss/scope.html
 
C

Christian

Roedy said:
final has to do with whether you can change a variable or override a
method or class.

It has nothing to do with visibility.

see http://mindprod.com/jgloss/final.html
http://mindprod.com/jgloss/scope.html

I would say not entirely..

for example:

for (final Object o: collection) {
new Runnable() {
public void run(){
//do something with o
}
}
}

o gets visible to the anonymous class because of final

while allowing o itself to be overriden for each object in the collection..

final seems to be a bit overloaded..

Christian
 
E

Eric Sosman

Esmond said:
Exactly so.


because A.hey() was declared final so it explicitly can't be overridden.
What the actual point of that rule is is a mystery to me. Possible
compiler bug, ask the language lawyers. I no longer am one ...


Possible compiler bug, see above.


It does indeed. It doesn't make much sense to me either, except that the
intent of whoever wrote private final void hey() in A was pretty clear
and the compiler is enforcing at least part of it.

I'm missing something here ... What compiler message
do you get when a subclass has a private method with the
same name and signature as one in the superclass? I get
no complaint at all for

class Super {
private void hey() {
System.out.println("Super: Hey!");
}
}

class Sub extends Super {
private void hey() {
System.out.println("Sub: Hey!");
}
}

In a sense this is not "overriding" because neither hey()
method is usable outside its class' own code. But still:
what's all this talk of compiler errors?
 
L

Lew

Not at all so!

There is no such rule.

Possible developer error?

Possible misleading report of the problem?

Facts not in evidence. Conclusion erroneous.
I'm missing something here ... What compiler message
do you get when a subclass has a private method with the
same name and signature as one in the superclass? I get
no complaint at all for

class Super {
private void hey() {
System.out.println("Super: Hey!");
}
}

class Sub extends Super {
private void hey() {
System.out.println("Sub: Hey!");
}
}

In a sense this is not "overriding" because neither hey()
method is usable outside its class' own code. But still:
what's all this talk of compiler errors?

Correct. There is no such compiler error as that at which the OP hinted.

See my SSCCE upthread.
 
L

Lew

More correctly, it has nothing to do with accessibility.
I would say not entirely..

for example:

for (final Object o: collection) {
new Runnable() {
public void run(){
//do something with o
}
}
}

o gets visible to the anonymous class because of final

while allowing o itself to be overriden for each object in the collection..

final seems to be a bit overloaded..

That is not a question of accessibility or visibility but of the inner class's
ability to rely on the variable's value.
 
K

kaja_love160

I sincerely apologise for the bug.
It's true that the code doesn't produce error ( I'm still not sure why
it did that since to my knowledge I haven't changed the code since and
now it runs fine )

But how can you claim that if parent class declared a method private
or final,then child class doesn't inherit the method? I know child
class can't access the method directly, but if what you've said was
true, then the following code wouldn't compile:


....
public static void main(String[] args) {
B a = new B();
a.aja();
}
....


class A{

public void aja(){
hey();
}

final private void hey()
{
System.Out.Print("A.hey");
}
}


class B extends A{...}


Again, I'm really sorry for all the troubles
 
L

Lew

I sincerely apologise for the bug.
It's true that the code doesn't produce error ( I'm still not sure why
it did that since to my knowledge I haven't changed the code since and
now it runs fine )

But how can you claim that if parent class declared a method private
or final,then child class doesn't inherit the method? I know child
class can't access the method directly, but if what you've said was
true, then the following code wouldn't compile:


...
public static void main(String[] args) {
B a = new B();
a.aja();
}
...


class A{

public void aja(){
hey();
}

final private void hey()
{
System.Out.Print("A.hey");
}
}


class B extends A{...}

You're right. That code doesn't compile.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,210
Messages
2,571,091
Members
47,691
Latest member
Jenny-jane

Latest Threads

Top