Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text, images, code for inheritance tutorial #1316

Merged
merged 7 commits into from
Dec 14, 2016

Conversation

rpetrusha
Copy link
Contributor

Text, images, code for inheritance tutorial

Summary

A tutorial on inheritance that addresses basic concepts, implicit inheritance, inheritance for code reuse, and abstract base classes.

Fixes #265

Suggested Reviewers

@BillWagner @mairaw @stevehoag

@dotnet-bot
Copy link
Contributor

❌ Validation status: errors

File Status Preview URL Details
docs/csharp/tutorials/inheritance.md ❌Error Details
docs/csharp/tutorials/index.md ✅Succeeded
docs/csharp/tutorials/media/book-class.jpg ✅Succeeded
docs/csharp/tutorials/media/publication-class.jpg ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/base-and-derived.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/basics.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/is-a.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/shape.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/simpleclass.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/simpleclass2.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/use-publication.cs ✅Succeeded

docs/csharp/tutorials/inheritance.md

  • Line unspecified: [Error] Tag name 2 is not found
  • Line unspecified: [Error] Tag name 2 is not found

For more details, please refer to the build report.

Note: If you changed an existing file name or deleted a file, broken links in other files to the deleted or renamed file are listed only in the full build report.

@dotnet-bot
Copy link
Contributor

❌ Validation status: errors

File Status Preview URL Details
docs/csharp/tutorials/inheritance.md ❌Error Details
docs/csharp/tutorials/index.md ✅Succeeded
docs/csharp/tutorials/media/book-class.jpg ✅Succeeded
docs/csharp/tutorials/media/publication-class.jpg ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/base-and-derived.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/basics.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/is-a.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/shape.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/simpleclass.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/simpleclass2.cs ✅Succeeded
samples/snippets/csharp/tutorials/inheritance/use-publication.cs ✅Succeeded

docs/csharp/tutorials/inheritance.md

  • Line unspecified: [Error] Tag name 2 is not found

For more details, please refer to the build report.

Note: If you changed an existing file name or deleted a file, broken links in other files to the deleted or renamed file are listed only in the full build report.

@dotnet-bot
Copy link
Contributor

✅ Validation status: passed

File Status Preview URL Details
docs/csharp/tutorials/index.md ✅Succeeded View
docs/csharp/tutorials/inheritance.md ✅Succeeded View

For more details, please refer to the build report.

Note: If you changed an existing file name or deleted a file, broken links in other files to the deleted or renamed file are listed only in the full build report.

@dotnet-bot
Copy link
Contributor

Copy link
Member

@BillWagner BillWagner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ron, This looks really good. Like the LINQ tutorial Steve did, we should upgrade the code samples to use the modern language features.

One concept that needs to be explained better is the distinction between inheritance and visibility. Other than constructors, every member is inherited (except instance constructors, static constructors and finalizers). However, whether those members are visible depends on the member's access modifier.


> [!NOTE]
> Structs do not support inheritance, but they can implement interfaces. For more information, see [Interfaces](../../../csharp/programming-guide/interfaces/index.md).

Conceptually, a derived class is a specialization of the base class. For example, if you have a base class `Animal`, you might have one derived class that is named `Mammal` and another derived class that is named `Reptile`. A `Mammal` is an `Animal`, and a `Reptile` is an `Animal`, but each derived class represents different specializations of the base class.

When you define a class to derive from another class, the derived class implicitly gains all the members of the base class, except for its constructors and destructors. The derived class can thereby reuse the code in the base class without having to re-implement it. In the derived class, you can add more members. In this manner, the derived class extends the functionality of the base class.
When you define a class to derive from another class, the derived class implicitly gains all the members of the base class, except for its constructors and destructors, private members, and static members. The derived class can thereby reuse the code in the base class without having to re-implement it. In the derived class, you can add more members. In this manner, the derived class extends the functionality of the base class.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Static members are inherited:

public class B
{
    public static void DeclaredInB()
    {
        Console.WriteLine("Declared in Base");
    }
}

public class D :B
{

}
class Program
{
    static void Main(string[] args)
    {
        D.DeclaredInB();
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BillWagner. I can't believe that I missed that. I've corrected it.


The following illustration shows a class `WorkItem` that represents an item of work in some business process. Like all classes, it derives from <xref:System.Object?displayProperty=fullName> and inherits all its methods. `WorkItem` adds five members of its own. These include a constructor, because constructors are not inherited. Class `ChangeRequest` inherits from `WorkItem` and represents a particular kind of work item. `ChangeRequest` adds two more members to the members that it inherits from `WorkItem` and from <xref:System.Object>. It must add its own constructor, and it also adds `originalItemID`. Property `originalItemID` enables the `ChangeRequest` instance to be associated with the original `WorkItem` to which the change request applies.
The following illustration shows a class `WorkItem` that represents an item of work in some business process. Like all classes, it derives from <xref:System.Object?displayProperty=fullName> and inherits all its instance methods. `WorkItem` adds five members of its own. These include a constructor, because constructors are not inherited. Class `ChangeRequest` inherits from `WorkItem` and represents a particular kind of work item. `ChangeRequest` adds two more members to the members that it inherits from `WorkItem` and from <xref:System.Object>. It must add its own constructor, and it also adds `originalItemID`. Property `originalItemID` enables the `ChangeRequest` instance to be associated with the original `WorkItem` to which the change request applies.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove 'instance'. See previous comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@BillWagner I've modified this discussion extensively to discuss visibility (which addressed your general comment) and added an example. Thanks -- I think this makes it much less confusing.


- [Destructors](../programming-guide/classes-and-structs/destructors.md), which are called by the runtime's garbage collector to destroy instances of a class.

- [Static members](../programming-guide/classes-and-structs/static-classes-and-static-class-members.md). Only instance members are inherited by base classes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be deleted. Static members are inherited.


- [Static members](../programming-guide/classes-and-structs/static-classes-and-static-class-members.md). Only instance members are inherited by base classes.

- [Private](../language-reference/keywords/private.md) and [internal](../language-reference/keywords/internal.md) members. However, internal members of a base class may be *visible* to a derived class if the two types are in the same assembly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal members are inherited. Their visibility is limited to the assembly where the base class is declared, but they are inherited.

}
```

In some cases, a derived class *must* override the base class implementation. Base class members marked with the [abstract](../language-reference/keywords/abstract.md) keyword require that derived classes override them. Attempting to compile the following example generates compiler error CS0534, "<class> does not implement inherited abstract member <member>', because class `B` provides no implementtion for `A.Method1`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: implementtion

authorName = author;
}

public string ISBN
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto implemented (possibly readonly) properties here....


public class Automobile
{
public string _make;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be private fields. (And I think using auto-implemented properties would be best).


public abstract double Perimeter { get; }

public override string ToString()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These one line methods could all be expression bodied members.

this.length = length;
}

public double Side
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer either read only auto implemented properties, or expression bodied members (for Area and Perimeter)

private PublicationType pubType;
private string copyrName;
private int copyrDate;
private int totalPages;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer auto implemented properties, readonly where that matches the design

@rpetrusha
Copy link
Contributor Author

@BillWagner Thanks for all of the comments and reviewing the code so carefully. I've made all of your suggested changes, as well as added interpolated strings, so I think that the code is much more "modern".

@dotnet-bot
Copy link
Contributor

❌ Validation status: errors

File Status Preview URL Details
docs/csharp/tutorials/inheritance.md ❌Error Details

docs/csharp/tutorials/inheritance.md

  • Line unspecified: [Error] Tag name 1 is not found

For more details, please refer to the build report.

Note: If you changed an existing file name or deleted a file, broken links in other files to the deleted or renamed file are listed only in the full build report.


- [Destructors](../programming-guide/classes-and-structs/destructors.md), which are called by the runtime's garbage collector to destroy instances of a class.

- [Private](../language-reference/keywords/private.md) and [internal](../language-reference/keywords/internal.md) members. However, internal members of a base class may be *visible* to a derived class if the two types are in the same assembly.
Copy link
Member

@BillWagner BillWagner Dec 14, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This paragraph should e removed, after the changes you've made.

@BillWagner
Copy link
Member

@rpetrusha I read this again this morning. It looks great.

There's one typo left, and one paragraph that still states that private and internal methods aren't inherited. Once those two are fixed, LGTM.

@rpetrusha rpetrusha merged commit a780a11 into dotnet:master Dec 14, 2016
@rpetrusha rpetrusha deleted the inheritance branch January 18, 2017 22:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants