However, as long as you trust that Liskov's Substitution Principle will be followed, then why would you not allow it to be overriden?
For example, because I want the skeleton implementation of an algorithm to be fixed, and only allow specific parts to be (re)defined by subclasses. This is widely known as the Template Method pattern (emphasis below by me):
The template method thus manages the larger picture of task semantics, and more refined implementation details of selection and sequence of methods. This larger picture calls abstract and non-abstract methods for the task at hand. The non-abstract methods are completely controlled by the template method but the abstract methods, implemented in subclasses, provide the pattern's expressive power and degree of freedom. Some or all of the abstract methods can be specialized in a subclass, allowing the writer of the subclass to provide particular behavior with minimal modifications to the larger semantics. The template method (which is non-abstract) remains unchanged in this pattern, ensuring that the subordinate non-abstract methods and abstract methods are called in the originally-intended sequence.
Update
Some concrete examples of projects I have been working on:
- communicating with a legacy mainframe system via various "screens". Each screen has a bunch of fields, of fixed name, position and length, containing specific data bits. A request fills up certain fields with specific data. A response returns data in one or more other fields. Each transaction follows the same basic logic, but the details are different on every screen. We used Template Method in several different projects to implement the fixed skeleton of the screen handling logic, while allowing subclasses to define the screen-specific details.
- exporting / importing configuration data in DB tables to/from Excel files. Again, the basic schema of processing an Excel file and inserting/updating DB records, or dumping the records to Excel is the same for each table, but the details of each table are different. So Template Method is a very obvious choice to eliminate code duplications and make the code easier to understand and maintain.
- Generating PDF documents. Each document has the same structure, but their content is different each time, depending on lots of factors. Again, Template Method makes it easy to separate the fixed skeleton of the generation algorithm from the case-specific, changeable details. In fact. it even applies on multiple levels here, as the document consists of several sections, each of which consists of zero or more fields. Template Method is applied on 3 distinct levels here.
In the first two cases, the original legacy implementation used Strategy, resulting in lots of duplicated code, which of course over the years grew subtle differences here and there, contained lots of duplicated or slightly different bugs, and was very difficult to maintain. Refactoring to Template Method (and some other enhancements, like using Java annotations) reduced code size by about 40-70%.
These are only the most recent examples which come to my mind. I could cite more cases from almost every project I have been working on so far.
Public methods virtual if not using interfaces -- makes mocking easier
Do not focus on mocks. Mocks are a valuable testing tool, but every time you create a mock, you are testing your code against an artificial environment, rather than the one it'll face in production. So minimise your use of mocks. To that end, marking methods as virtual really is a test tool of last resort. Overriding a method in order to test can often cause more problems than it solves (the tests all too easily break when changes are made to the way the two methods interact in the real code for example). Instead, use interfaces in the first place for when you do need to mock.
Dependency injection -- makes mocking easier
No! Stop fixating on mocking. Dependency injection helps reduce coupling between parts of your code, making both maintenance and testing far easier. Mocking is only made easier (if needed) by referencing those injected dependencies via interfaces.
Smaller, more targeted, choesive methods -- tests are more focused, easier to write
Smaller, more cohesive methods have many advantages. They tend to be far simpler to understand for a start. They can indeed also be easier to test. This one is definitely good advice.
Avoidance of static classes
Static classes only need to be avoided when their methods have side effects (access or modify global state, external resources like the file system, databases etc). If the methods are pure, ie rely on only their inputs and constants to derive a deterministic result, then make them static.
[Addendum, as a nod to something I learned from RobertHarvey recently, beware using static for methods that take a long time to execute. Unit tests should be fast and may need to mock slow methods, so don't make those methods static]
Avoid singletons, except where necessary
Avoid (in fact, never use) the singleton pattern. It's a glorified global variable. It's an anti-pattern. It's never ever necessary to use it.
Single instances of classes, injected into those parts of the code that need access absolutely should be used though. Please don't end up creating two copies of a class just to avoid being accused of using a singleton for example.
Avoid sealed classes
If a class is badly designed, doesn't use an interface and has virtual methods so they can be overridden by tests, then this holds true. But you don't want that; you want well designed classes that are accessible via interfaces and that do not contain virtual methods. At which point you can seal all of them. I do.
Best Answer
How would virtual methods help? The idea of mocking is that you rip out a class completely from your application and plug in a completely different mocked class, with the only thing in common that they both implement the same interface. Inheritance doesn't come into the game at all.