Liskov Substitution Principle question

Let's say you have the following interface:

interface DatabaseManager {
  DatabaseConnection getConnection();
}

And an implementation:

class MySqlDatabaseManager implements DatabaseManager {
  MySqlDatabaseConnection getConnection() { ... }
}

If I have code that accepts a DatabaseManager, you can pass it a MySqlDatabaseManager. If I call getConnection, you will give me back a MySqlDatabaseConnection, which I am fine with because I've written my code to work with any DatabaseConnection.

This is an example of covariance.


The following code does not actually work in Java.

No consider this interface:

interface DataLoader {
  Data loadData(MySqlDatabaseConnection connection);
}

And an implementation:

  class SpecialDataLoader implements DataLoader {
    /** NOT VALID JAVA **/
    Data loadData(DatabaseConnection connection) { ... }
  }

From a type theory point of view, there is no reason why this cannot work.

If I write code using a DataLoader, you can pass it a SpecialDataLoader. If I call loadData, I will be passing it MySqlDatabaseConnection, which is fine because SpecialDataLoader.loadData is written to work with any DatabaseConnection.

This is an example of contravariance.

As mentioned a couple of times, Java does not support contravariant arguments.

/r/learnprogramming Thread