There are many techniques for specifying software. However, they are not usually presented in a way that is directly applicable to object-oriented software. This tutorial surveys both operational and descriptive specification techniques, shows how to use them in several popular object-oriented software engineering methods, and provides case studies of developing useful, formal specification mechanisms that are appropriate for object-oriented software engineering. The tutorial first describes criteria for choosing specification mechanisms from both a theoretical (syntax and semantics, specifying properties, reasoning about properties, verification) and practical (ease of use, modularity, applicability, supporting tools) perspective. These criteria are then used to survey several popular operational (data flow diagrams, finite state machines, and petri nets) and descriptive (entity-relationship models, logic, and algebraic specifications) specification mechanisms. Finally it shows how to extend two of these techniques (algebraic specifications and finite state machines) so that they are suitable for object-oriented software engineering.