Let's have the specified code:
class Foo {
public void doSomething(){
System.out.println("Foo");
}
}
class Bar extends Foo{
@Override
public void doSomething(){
System.out.println("Bar");
}
}
public class doFoo{
public static invoke(Foo foo){
foo.doSomething();
}
public static void main(String[] args){
invoke(new Bar()); // Foo or Bar?
}
}
I tried running the code and the output is:
Bar
Then here's why I get confused.
First if it prints out Bar
, and invoke has argument type Foo
, why won't print out Foo
since it's a Foo
typed Object? Since Foo.doSomething()
should print out Foo
?
Second if this prints out Bar
, wouldn't there be some security issues? Let's say there's a private method called writeData(Database database, Data data)
method and writeData(Data data)
calling it. Or as the follows:
public void writeData(Data data){
writeData(DEFAULT_DATABASE != null ? DEFAULT_DATABASE : initializeDatabaseAndGet();
}
private void writeData(Database database, Data data){
// Idk what to write...
}
In this I could invoke writeData using Reflection and my custom implementation of Database. With my implementation sending passwords/tokens and things to hack into the database?
Am I misunderstanding things here?
since it's a Foo typed Object
This is the heart of your misconception. I assume you said it's 'Foo type' because of the 'Foo foo' declaration.
The object is actually a Bar. It was created by new Bar()
. The object is really, and will be for as long as it exists, a Bar.
A Bar is also a Foo, of course - that it what inheriting from Foo means. Nevertheless, its behaviour is that of a Bar.
You have a number of Foo variables - that is, variables that can contain a reference to a Foo object. But the variable being a Foo variable does not make the Bar-ness of the actual object go away.