Não. Eles não herdam.
O fato de alguma outra classe usá-lo indiretamente não diz nada sobre herança, mas sobre encapsulamento.
Por exemplo:
class Some {
private int count;
public void increment() {
count++;
}
public String toString() {
return Integer.toString( count );
}
}
class UseIt {
void useIt() {
Some s = new Some();
s.increment();
s.increment();
s.increment();
int v = Integer.parseInt( s.toString() );
// hey, can you say you inherit it?
}
}
Você também pode obter o valor de count
dentro UseIt
via reflexão. Isso não significa que você herda.
ATUALIZAR
Mesmo que o valor esteja lá, ele não é herdado pela subclasse.
Por exemplo, uma subclasse definida como:
class SomeOther extends Some {
private int count = 1000;
@Override
public void increment() {
super.increment();
count *= 10000;
}
}
class UseIt {
public static void main( String ... args ) {
s = new SomeOther();
s.increment();
s.increment();
s.increment();
v = Integer.parseInt( s.toString() );
// what is the value of v?
}
}
Essa é exatamente a mesma situação do primeiro exemplo. O atributo count
está oculto e não é herdado pela subclasse. Ainda assim, como DigitalRoss aponta, o valor está lá, mas não por meio de herança.
Põe desta forma. Se seu pai é rico e lhe dá um cartão de crédito, você ainda pode comprar coisas com o dinheiro dele, mas não significa que você herdou todo esse dinheiro, não é?
Outra atualização
É muito interessante saber por que o atributo está lá.
Francamente, não tenho o termo exato para descrevê-lo, mas é a JVM e a maneira como funciona que carrega também a definição de pai "não herdada".
Poderíamos realmente mudar o pai e a subclasse ainda funcionará.
Por exemplo :
//A.java
class A {
private int i;
public String toString() { return ""+ i; }
}
// B.java
class B extends A {}
// Main.java
class Main {
public static void main( String [] args ) {
System.out.println( new B().toString() );
}
}
// Compile all the files
javac A.java B.java Main.java
// Run Main
java Main
// Outout is 0 as expected as B is using the A 'toString' definition
0
// Change A.java
class A {
public String toString() {
return "Nothing here";
}
}
// Recompile ONLY A.java
javac A.java
java Main
// B wasn't modified and yet it shows a different behaviour, this is not due to
// inheritance but the way Java loads the class
Output: Nothing here
Acho que o termo exato pode ser encontrado aqui: The JavaTM Virtual Machine Specification