I am not sure if I understand the example used for LSP.
You may have noticed all of the FTP client classes so far have the same function signatures. That was done purposefully so they would follow Liskov's Substituitability Principle. An SFTPClient object can replace an FTPClient object and whatever code is calling upload, or download, is blissfully unaware.
SFTPClient requires username and password, whereas FTPClient does not. In the calling code I cannot replace FTPClient(host=host, port=port) with SFTPClient(host=host, port=port), so I do not see how SFTPClient can be a substitute for FTPClient. Could you please explain?
Great question! I had to look up Liskov's again to make sure this example was still valid. Fortunately for me, and quite by accident, I think it still works. Let me try to explain.
Liskov's as it originally appeared states, "Let Φ(x) be a property provable about objects x of type T. Then Φ(y) should be true for objects y of type S where S is a subtype of T." So I took this as the principle applies to objects, not classes. In general, I think most people agree. So a class has a constructor which returns an object and as long as the object returned by the constructor can replace an object of the parent type you are following Liskov's.
All that being said with higher-level languages like Python it's probably a better practice to follow Liskov's even with the constructor since we can pass a Class name to a function and then construct an object of that class inside the function. In that scenario what I've written in this article would absolutely blow up.
I am not sure if I understand the example used for LSP.
You may have noticed all of the FTP client classes so far have the same function signatures. That was done purposefully so they would follow Liskov's Substituitability Principle. An SFTPClient object can replace an FTPClient object and whatever code is calling upload, or download, is blissfully unaware.
SFTPClient requires username and password, whereas FTPClient does not. In the calling code I cannot replace FTPClient(host=host, port=port) with SFTPClient(host=host, port=port), so I do not see how SFTPClient can be a substitute for FTPClient. Could you please explain?
Thanks for pointing it out. I've fixed it.
Great question! I had to look up Liskov's again to make sure this example was still valid. Fortunately for me, and quite by accident, I think it still works. Let me try to explain.
Liskov's as it originally appeared states, "Let Φ(x) be a property provable about objects x of type T. Then Φ(y) should be true for objects y of type S where S is a subtype of T." So I took this as the principle applies to objects, not classes. In general, I think most people agree. So a class has a constructor which returns an object and as long as the object returned by the constructor can replace an object of the parent type you are following Liskov's.
All that being said with higher-level languages like Python it's probably a better practice to follow Liskov's even with the constructor since we can pass a Class name to a function and then construct an object of that class inside the function. In that scenario what I've written in this article would absolutely blow up.
Thank you for the explanation!