-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add abstract classes and inheritance page
- Loading branch information
1 parent
72668d7
commit d4abbbd
Showing
2 changed files
with
65 additions
and
0 deletions.
There are no files selected for viewing
13 changes: 13 additions & 0 deletions
13
public/documentation/object-programming/abstract-classes-and-inheritance.fsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[<AbstractClass>] | ||
type Drawable() = | ||
member _.Description = "A drawable shape." | ||
abstract member Draw: float * float -> unit | ||
|
||
type Square(size: int) = | ||
inherit Drawable() | ||
|
||
override this.Draw(x: float, y: float) = | ||
printfn $"Drawing a square @ X: {x}, Y: {y}" | ||
|
||
let square = Square(10) | ||
square.Draw(0, 0) |
52 changes: 52 additions & 0 deletions
52
public/documentation/object-programming/abstract-classes-and-inheritance.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# Abstract Classes and Inheritance | ||
|
||
Objects can also inherit functionality from other objects. Inheriting creates a hierarchical relationship between two objects (parent and child), where the child has all the behavior of the parent, but implements abstract members that are present, but not implemented, in the parent object. | ||
|
||
Abstract classes, unlike interfaces, can have: behavior, data, and abstract members. To define an abstract class you have to annotate the type with `[<AbstractClass>]`. | ||
|
||
```fsharp | ||
[<AbstractClass>] | ||
type Drawable() = | ||
member _.Description = "A drawable shape." | ||
abstract member Draw : float * float -> unit | ||
``` | ||
|
||
Then, you can inherit the behavior and/or data from this type while also implementing the abstract `Draw` member. | ||
|
||
```fsharp | ||
[<AbstractClass>] | ||
type Drawable() = | ||
member _.Description = "A drawable shape." | ||
abstract member Draw : float * float -> unit | ||
type Square(size: int) = | ||
inherit Drawable() | ||
// ^^ | ||
// make sure to pass any required constructor parameters | ||
override this.Draw(x: float, y: float) = | ||
printfn $"Drawing a square @ X: {x}, Y: {y}" | ||
let square = Square(10) | ||
square.Description // "A drawable shape." | ||
square.Draw(10, 20) // "Drawing a square @ X: 10, Y: 20" | ||
``` | ||
|
||
You can inherit behavior and data from non-abstract classes too. The difference being, abstract classes can provide abstract members that inheritors must provide an implementation for, while normal classes can not. | ||
|
||
```fsharp | ||
type Rockstar() = | ||
member _.PlayMusic() = ... | ||
abstract member Sing: unit -> unit | ||
type FreddieMercury() = | ||
inherit Rockstar() | ||
override this.Sing() = ... | ||
let rockstar = Rockstar() | ||
rockstar.PlayMusic() | ||
let freddie = FreddieMercury() | ||
freddie.PlayMusic() // inherits behavior of the parent. | ||
freddie.Sing() // overrides abstract behavior in the parent. | ||
``` |