diff --git a/docs/design/classes.md b/docs/design/classes.md index 5f4ec15882e3..8e8b1101d052 100644 --- a/docs/design/classes.md +++ b/docs/design/classes.md @@ -45,7 +45,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Alias](#alias) - [Inheritance](#inheritance) - [Virtual methods](#virtual-methods) - - [Virtual override keywords](#virtual-override-keywords) + - [Virtual modifier keywords](#virtual-modifier-keywords) - [Subtyping](#subtyping) - [`Self` refers to the current type](#self-refers-to-the-current-type) - [Constructors](#constructors) @@ -1182,9 +1182,9 @@ direct call to the method does. [Class functions](#class-functions) may not be declared virtual. -##### Virtual override keywords +##### Virtual modifier keywords -A method is declared as virtual by using a _virtual override keyword_ in its +A method is declared as virtual by using a _virtual modifier keyword_ in its declaration before `fn`. ``` @@ -1204,7 +1204,7 @@ _non-virtual_. This means: - they have an implementation in the current class, and that implementation must work for all derived classes. -There are three virtual override keywords: +There are three virtual modifier keywords: - `virtual` - This marks a method as not present in bases of this class and having an implementation in this class. That implementation may be @@ -1230,6 +1230,12 @@ There are three virtual override keywords: | `abstract` | ✅ | ❌ | ❌ | _not present_
`virtual`
`abstract`
`impl` | `abstract`
`impl`
_may not be
mentioned if
`D` is not final_ | | `impl` | ✅ | ✅ | ✅ | `virtual`
`abstract`
`impl` | `abstract`
`impl` | +Since validating a method with a virtual modifier keyword involves looking for +methods with the same name in the base class, virtual methods must be declared +after the `extend base` declaration when present in a class definition. This +simplifies the compiler, and follows the +[information accumulation principle](/docs/project/principles/information_accumulation.md). + #### Subtyping A pointer to a base class, like `MyBaseClass*` is actually considered to be a @@ -1246,11 +1252,16 @@ or _vtable_. Any calls to virtual methods will perform the method using the function pointer in the vtable, to get the overridden implementation from the most derived class that implements the method. +This data layout is reflected in the order of declarations in a class +definition. An `extend base` declaration, when present in a class definition, +must appear before any other declarations adding data to the class instances, +such as instance variables. + Since a final class may not be extended, the compiler can bypass the vtable and use [static dispatch](https://en.wikipedia.org/wiki/Static_dispatch). In general, you can use a combination of an abstract base class and a final class -instead of an extensible class if you need to distinguish between exactly a type -and possibly a subtype. +instead of an extensible class if you need to distinguish between "exactly a +type" and "possibly a subtype." ``` base class Extensible { ... } @@ -1713,7 +1724,7 @@ declaration. Access modifiers are how Carbon supports [encapsulation](#encapsulated-types). The [access modifier](https://en.wikipedia.org/wiki/Access_modifiers) is written -before any [virtual override keyword](#virtual-override-keywords). +before any [virtual modifier keyword](#virtual-modifier-keywords). **Rationale:** Carbon makes members public by default for a few reasons: