Skip to main content
Added mention of decorator pattern
Source Link
Pharap
  • 345
  • 1
  • 8

When I want to give an example of how inheritance works, I always point to C#'s Stream class.

The Stream class is an abstraction of the idea of a data stream from which bytes can be taken or to which bytes can be stored. Its child classes include FileStream which represents the data of a file, MemoryStream which represents data in memory (RAM), BufferedStream which is an adaptor to provide an extra layer of data buffering, and CryptoStream which represents a layer of encryption.

It's a very abstract example, but it's a real world example that highlights how different implementations of the same interface can be incredibly useful. It demonstrates the use of virtual functions, abstraction, the dependency inversion principle and the liskov substitution principle.

Any Stream can be wrapped in a StreamReader, StreamWriter, BinaryReader or BinaryWriter to handle the ability to read/write data more complex than bytes. These are also good examples of the decorator pattern being used 'in the wild'. (StreamReader and StreamWriter in turn inherit TextReader and TextWriter, which are themselves another good example.)

When I want to give an example of how inheritance works, I always point to C#'s Stream class.

The Stream class is an abstraction of the idea of a data stream from which bytes can be taken or to which bytes can be stored. Its child classes include FileStream which represents the data of a file, MemoryStream which represents data in memory (RAM), BufferedStream which is an adaptor to provide an extra layer of data buffering, and CryptoStream which represents a layer of encryption.

It's a very abstract example, but it's a real world example that highlights how different implementations of the same interface can be incredibly useful. It demonstrates the use of virtual functions, abstraction, the dependency inversion principle and the liskov substitution principle.

Any Stream can be wrapped in a StreamReader, StreamWriter, BinaryReader or BinaryWriter to handle the ability to read/write data more complex than bytes. (StreamReader and StreamWriter in turn inherit TextReader and TextWriter, which are themselves another good example.)

When I want to give an example of how inheritance works, I always point to C#'s Stream class.

The Stream class is an abstraction of the idea of a data stream from which bytes can be taken or to which bytes can be stored. Its child classes include FileStream which represents the data of a file, MemoryStream which represents data in memory (RAM), BufferedStream which is an adaptor to provide an extra layer of data buffering, and CryptoStream which represents a layer of encryption.

It's a very abstract example, but it's a real world example that highlights how different implementations of the same interface can be incredibly useful. It demonstrates the use of virtual functions, abstraction, the dependency inversion principle and the liskov substitution principle.

Any Stream can be wrapped in a StreamReader, StreamWriter, BinaryReader or BinaryWriter to handle the ability to read/write data more complex than bytes. These are also good examples of the decorator pattern being used 'in the wild'. (StreamReader and StreamWriter in turn inherit TextReader and TextWriter, which are themselves another good example.)

Source Link
Pharap
  • 345
  • 1
  • 8

When I want to give an example of how inheritance works, I always point to C#'s Stream class.

The Stream class is an abstraction of the idea of a data stream from which bytes can be taken or to which bytes can be stored. Its child classes include FileStream which represents the data of a file, MemoryStream which represents data in memory (RAM), BufferedStream which is an adaptor to provide an extra layer of data buffering, and CryptoStream which represents a layer of encryption.

It's a very abstract example, but it's a real world example that highlights how different implementations of the same interface can be incredibly useful. It demonstrates the use of virtual functions, abstraction, the dependency inversion principle and the liskov substitution principle.

Any Stream can be wrapped in a StreamReader, StreamWriter, BinaryReader or BinaryWriter to handle the ability to read/write data more complex than bytes. (StreamReader and StreamWriter in turn inherit TextReader and TextWriter, which are themselves another good example.)