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?
 
     
     
    