[Reading Notes] C # advanced programming Chapter 4 inheritance,
(1) inherited types
1. Implement inheritance and interface inheritance
In object-oriented programming, there are two completely different inheritance types: Implementation inheritance and interface inheritance.
- Implement inheritance: indicates that a type is derived from a base type and has all member fields and functions of the base type. In implementation inheritance, the derived type uses each function code of the base type, unless you specify to override the implementation code of a function in the definition of the derived type.This type inheritance is useful when you need to add features to an existing type, or many related types share a set of important public functions.
- Interface inheritance: indicates that a type only inherits the signature of the function and does not inherit any implementation code.When you need to specify that this type has certain available features, it is best to use this type of inheritance.
2. Multi-Inheritance
C # multi-implementation inheritance is not supported, but the type can be derived from multiple interfaces-multi-interface inheritance. To be accurate, because System. Object is a common base class, each C # class (except the Object class) has a base class and can have any number of base interfaces.
3. Structure and class
Structure does not support implementation inheritance, but supports interface inheritance.
The definition structure and class can be summarized:
- The structure is always derived from System. ValueType. They can also be derived from any number of interfaces.
- Classes are always derived from System. Object or another class selected by the user. They can also be derived from any number of interfaces.
(2) Implement inheritance
Declare a class derived from another class. The syntax is as follows:
Example:
The following code creates the MyBaseClass class and MyClass class. The MyClass class is derived from the MyBaseClass class.
class MyBaseClass{}class MyClass : MyBaseClass{}
If the class (or structure) is also derived from the interface, use commas to separate the base class and interface in the list:
class MyClass : MyBaseClass,IInterface1,IInterface2 {}
For the structure, the syntax is as follows:
public struct MyStruct: IInterface1, IInterface2{}
1. Virtual Methods
To declare a base-class function as virtual, you can rewrite the function in any derived class:
Class MyBaseClass {public virtual string VirtualMethod () {return "virtual method ";}}
In C #, functions are not virtual by default, but can be explicitly declared as virtual. At the same time, C # requires that the override keyword should be used for explicit declaration when the derived class overrides the functions in the base class:
Class MyClass: MyBaseClass, IInterface1, IInterface2 {public override string VirtualMethod () {return "override the virtual method of the base class ";}}
2. Hide Methods
If the method with the same signature is declared in both the base class and the derived class, but this method is not declared as virtual and override, the derived class method will hide the base class method.
Example:
In the following code, the base class and the derived class have the same method ShowName. When we need to hide the methods in the base class, we should use the keyword new explicitly; otherwise, the compiler will issue a warning. The base class method is hidden. We cannot access the base class method through the derived class, but can only access the base class method by the derived class.
Class MyBaseClass {public void ShowName (string name) {Console. writeLine (name) ;}} class MyClass: MyBaseClass, IInterface1, {public new void ShowName (string name) {Console. writeLine ("derived class" + name );}}
In most cases, we should rewrite the method instead of hiding the method, because hiding the method will pose a risk of calling an error method for the instance of the given class.
3. base class version of the called Function
C # has a special syntax used to call the base class version of a method from a derived class: base. <MethodName> ().
Example:
The following code prints the name of the base class, and then calls a greeting line.
Class MyBaseClass {public virtual void ShowName (string name) {Console. writeLine (name) ;}} class MyClass: MyBaseClass, IInterface1, IInte {public override void ShowName (string name) {base. showName (name); Console. writeLine ("Welcome! ");}}
Run the above Code and the result is as follows:
4. abstract classes and Abstract Functions
C # declare classes and functions as abstract objects. Abstract classes cannot be instantiated, but abstract functions cannot be directly implemented. They must be rewritten in non-Abstract Derived classes. If a class contains an abstract function, the class is also abstract and must be declared as an abstract class.
Example:
The following code creates an abstract class and an abstract method:
abstract class MyAbstractClass { public abstract void FirstAbstractMethod();}
5. sealing and sealing methods
C # declare classes and methods as sealed. For classes, this indicates that the class cannot be inherited; for methods, this indicates that the method cannot be overwritten.
Example:
sealed class FisrtSealedClass{ }class ReadyClass : FisrtSealedClass{ }
The compiler reports an error.
Declare the method as sealed
Example:
Class MyBaseClass {public virtual void ShowName (string name) {Console. writeLine (name) ;}} class MyClass: MyBaseClass, IInterface1, IInterface2 {public sealed override void ShowName (string name) {base. showName (name); Console. writeLine ("Welcome! ");}}
To use the sealed keyword on a method or attribute, you must first declare it as a method or attribute to be overwritten from the base class. If the base class is to be sealed, do not declare it as virtual.
6. constructor of the derived class
Example:
class MyBaseClass{ public MyBaseClass() { } public MyBaseClass(int i) { }}class MyClass : MyBaseClass{ public MyClass() { } public MyClass(int i) { } public MyClass(int i,int j) { }}
If you instantiate MyClass in the following way:
MyClass myClass = new MyClass();
The execution sequence of the constructor is as follows:
If you instantiate MyClass in the following way:
MyClass myClass = new MyClass(4);
The execution sequence of the constructor is as follows:
Finally, instantiate MyClass as follows:
MyClass myClass = new MyClass(4, 8);
The execution sequence of the constructor is as follows:
You can also use base () and this () to change the execution sequence of the constructor.
class MyBaseClass{ public MyBaseClass() { } public MyBaseClass(int i) { }}class MyClass : MyBaseClass{ public MyClass() { } public MyClass(int i) { } public MyClass(int i, int j) : base(i) { }}
In this case, we instantiate MyClass as follows:
MyClass myClass = new MyClass(4, 8);
The execution sequence of the constructor is as follows:
The base keyword specifies that the. NET instantiation process uses constructors with specified parameters in the base class.
class MyBaseClass{ public MyBaseClass() { } public MyBaseClass(int i) { }}class MyClass : MyBaseClass{ public MyClass() { } public MyClass(int i) : this(i, 5) { } public MyClass(int i, int j) { }}
In this case, we instantiate MyClass as follows:
MyClass myClass = new MyClass(4);
The execution sequence of the constructor is as follows:
This keyword specifies that the. NET instantiation process uses the constructor with the specified parameters in the current class.
Note that do not use infinite loops:
class MyClass : MyBaseClass{ public MyClass() : this(1){ } public MyClass(int i) : this() { }}
The above Code uses this to specify each other, resulting in an infinite loop.
Through the analysis of the code above, we can know that the calling sequence of the constructor is to call System. Object first, and then proceed from top to bottom according to the hierarchy until the class to be instantiated by the compiler is reached.
No matter what constructor is used on the derived class (default constructor or non-default constructor), the default constructor of the base class is used unless explicitly specified.
(3) Modifier
Modifier, that is, a keyword applied to a type or member.
1. Visibility Modifier
| Modifier |
Apply |
Description |
| Public |
All types or members |
This item can be accessed by any code |
| Protected |
All members of the type and embedded type |
Only the derived type can access this item. |
| Internal |
All types or members |
You can only access this item in a set of programs that contain it. |
| Private |
All members of the type and embedded type |
You can only access this item in the type to which it belongs. |
| Protected internal |
All members of the type and embedded type |
You can only access this item in any code that contains the assembly and the derived type. |
2. Other Modifiers
| Modifier |
Apply |
Description |
| New |
Function Member |
Hide inherited members with the same signature |
| Static |
All members |
The member does not work with the specific instance of the class |
| Virtual |
Function member only |
A member can be rewritten by a derived class. |
| Abstract |
Function member only |
The Virtual Member defines the member signature, but no implementation code is provided. |
| Override |
Function member only |
The member overrides the inherited virtual or abstract member. |
| Sealed |
Class, method, and attribute |
The class cannot inherit from the sealed class. For attributes and methods, a member overrides an inherited Virtual Member, but a member in any derived class cannot override this member. This modifier must be used with override |
| Extern |
Only static [DllImport] Methods |
Members are implemented externally in another language |
(4) Interface
If a class is derived from an interface, declaring this class will implement some functions.
An interface can only contain methods, attributes, indexers, and event declarations.
An interface cannot be instantiated. It can only contain the signatures of its members.
Interfaces are always common and cannot be declared as virtual or static.
The interface usually starts with the letter I to know that this is an interface.
1. define and implement interfaces
First, we define an interface, which is a talking interface.
interface ITalk { void talk(string str);}
Next we will implement this interface through the Chinese class
Class Chinese: ITalk {public void talk (string str) {Console. WriteLine ("Chinese voice:" + str );}}
You can also define an American to implement this interface.
class American : ITalk { public void talk(string str) { Console.WriteLine("English:" + str); }}
Through the inheritance of interfaces, we have implemented a function that allows people in different countries to speak. We can easily call this function through interface references during external calls.
2. Interface Derivation
When ITalk does not meet the requirements, it is assumed that a Speak function needs to be added to Chinese and American at this time, which can be implemented through interface derivation.
interface ILanguage : ITalk{ void Speak(string str);}
Changed interface implementation
Class Chinese: ILanguage {public void Speak (string str) {Console. writeLine ("Chinese speech:" + str);} public void talk (string str) {Console. writeLine ("Chinese voice:" + str) ;}} class American: ILanguage {public void Speak (string str) {Console. writeLine ("English Speak:" + str);} public void talk (string str) {Console. writeLine ("English:" + str );}}