[Full stack plan - C# of programming language] Summarize the second of the three major characteristics of object-oriented - inheritance

insert image description here

foreword

From the concept of inheritance, the methods and keywords that may be involved in inheritance, the inheritance of fixed-point blasting is one of the three characteristics.

Structure map of this article:
insert image description here

The second of the three major characteristics of object-oriented - inheritance

The concept of inheritance

Inheritance is one of the important features in object-oriented languages.

Only supported in C# language 单重继承, mainly for solving 代码重用问题.

In order to flexibly apply the inheritance relationship to programming, 接口来解决多重继承the relationship provided in the C# language.

Flexible use of the inheritance relationship between classes in programming can help reuse code and save development time
. That is to say, when A inherits from B, while A has all the class members contained in B, it can also specialize Lonely has its own members.

[Example]
I now have a Student class with the following attributes:
姓名、性别、身份证号、联系方式、专业、年级
At the same time, a Teacher class has the following attributes:
姓名、性别、身份证号、联系方式、职称、工资号
It is obvious that 姓名、性别、身份证号、联系方式these four familiarity are repeating the wheel.
So at this time, you can actually consider declaring a Person class, put these four attributes in this class, and then let the Student class and the Teacher class inherit from the Person class, then the Student class only needs to declare 专业和年级two additional attributes, and the Teacher class only needs to be 职称和工资号Two additional properties are declared . To a certain extent, it alleviates our repetitive coding actions.

The syntax used by inheritance:

<访问修饰符> class <基类>
{
    
    
 ...
}
class <派生类> : <基类>
{
    
    
 ...
}

The Person class in the above case is called in the official definition 基类(in fact, it may be more customary to call it the parent class), and the Student class and the Teacher class are called the Person class 派生类(and they are usually called subclasses)

insert image description here

Object类

The Object class is the most primitive and important class in the C# language.
Whether it is the standard class provided by the C# system or the class written by the user, it all comes from the Object class 直接或间接继承, which is the top-level class in the class hierarchy, that is, the root of the C# tree-type class hierarchy.

When the coder does not specify the parent class of the current class, it is assumed that the class inherits from the Object class by default.

As the most primitive parent class, the Object class is relatively limited in function, and it provides four common methods: Equals method, GetHashCode method, GetType method, and ToString method.

In actual development, most of us need to rewrite these four methods.

The Four Elder Methods in Objecte

① Equal method

The Equals method is mainly used to compare whether two objects are equal, and returns True if they are equal, otherwise returns False.
If it is an object of reference type, it is used to determine whether two objects refer to the same object.
As for judging whether it is the same object, my understanding is to judge whether it is the same address

Knowledge point 1: The Equals method provides two, one is static and the other is non-static

Static can be used directly, as for non-static, you need to create an object and call this method through the object.

Equals (object ol, object o2); //静态方法
Equals (object o); //非静态方法

[Classroom Demonstration]
First create the Person class. You don't need to write any code in the Person class. Then create a Test class. In this class, write a Test_Equals method to test how to compare two objects for equality.
Finally, create an object of the Test class in the Main function and call the Test_Equals method.

Test effect:
insert image description here
Test summary:
When Equals is used to compare objects of reference type, it compares its address

Test code:

	/// <summary>
    /// Main函数
    /// </summary>
    class Program
    {
    
    
        public static void Main(string[] args)
        {
    
    
            Test t = new Test();
            t.Test_Equals();
            Console.ReadKey();
        }
    }

		/// <summary>
       /// Person 类
       /// </summary>
        public class Person
        {
    
    
            public int Id {
    
     get; set; }
            public string Name {
    
     get; set; }
            public string Sex {
    
     get; set; }
        }
        
		/// <summary>
        /// 获取引用类型地址,比较引用类型地址的方法
        /// </summary>
        public void Test_Equals()
        {
    
    
            try
            {
    
    
                Person pp = new Person();
                Person ee = new Person();
                Person tt = pp; //对象tt 是由 对象pp 直接赋值
                pp.Id = 99;
                pp.Name = "test";
                pp.Sex = "nan";
                // 获取对象的地址
                var addr2 = getMemory(pp);
                var addr3 = getMemory(ee);
                var addr4 = getMemory(tt);
                Console.WriteLine("对象pp的地址是" + addr2);
                Console.WriteLine("对象ee的地址是" + addr3);
                Console.WriteLine("对象tt的地址是" + addr4);

                Console.WriteLine();
                Console.ForegroundColor =  ConsoleColor.DarkRed;
                Console.WriteLine("Equals 方法主要用于比较两个对象是否相等,如果相等则返回 True,否则返回 False。\n" +
                    "下面切实对Equals(静态方法) 进行使用:");
                Console.ResetColor();
                Console.WriteLine("对象pp和对象ee是否相等:{0}",Equals(pp,ee));
                Console.WriteLine();
                Console.WriteLine("对象tt直接由对象pp赋值:");
                Console.WriteLine("对象pp和对象tt是否相等:{0}", Equals(pp, tt));

                Console.WriteLine();
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.WriteLine("Equals 方法主要用于比较两个对象是否相等,如果相等则返回 True,否则返回 False。\n" +
                    "下面切实对Equals(非静态方法) 进行使用:");
                Console.ResetColor();
                Console.WriteLine("对象pp和对象ee是否相等:{0}", ee.Equals(pp));

            }
            catch (Exception ex)
            {
    
    

            }
        }

        // 获取引用类型的内存地址方法    
        public string getMemory(object o) 
        {
    
    
            GCHandle h = GCHandle.Alloc(o, GCHandleType.WeakTrackResurrection);

            IntPtr addr = GCHandle.ToIntPtr(h);

            return "0x" + addr.ToString("X");
        }

    }
    

② GetHashCode method

This GetHashCode method has not found a case where it is actually used.
insert image description here

The GetHashCode method returns the hash code of the current System.Object, and the hash value of each object is fixed.

[Class Demonstration]
Create two objects of the Person class and calculate their hash values ​​respectively.

Test effect:
insert image description here
test code:

class Program
    {
    
    
        public static void Main(string[] args)
        {
    
    
            //Test t = new Test();
            //t.Test_Equals();
            Person person1 = new Person();
            Person person2 = new Person();

            Console.WriteLine("person1对象的哈希值是:"+person1.GetHashCode());
            Console.WriteLine("person2对象的哈希值是:"+person2.GetHashCode());
            Console.ReadKey();
        }
    }

③ GetType method

Function:
The GetType method is used to obtain the type of the current instance, and the return value is System.Type.
Note:
The GetType method does not contain any parameters and is a non-static method.

【Classroom Demonstration】
【Example】Create a variable of word integer type, a variable of floating point type, a variable of string type, and an object of class Person, and use the GetType method to obtain their types and output.

Test effect:
insert image description here
test code:

    class Program
    {
    
    
        public static void Main(string[] args)
        {
    
    
            int a = 520;
            double b = 13.14;
            string c = "1314520";
            Person d = new Person();

            Console.WriteLine(a.GetType());
            Console.WriteLine(b.GetType());
            Console.WriteLine(c.GetType());
            Console.WriteLine(d.GetType());

            Console.ReadKey();
        }
    }

④ ToString method

Role:
The ToString method returns a string of object instances, which by default will return the qualified name of the class type.
I think this method is quite commonly used. It is more to rewrite the ToString method according to your own needs and return the string information you need.

[Classroom Demonstration]
Create variables of integer type, floating-point type variables, objects of Object class and objects of Person type, and use the ToString method to obtain and output their string representations respectively.
Test effect:
insert image description here

Test summary:
It can be summed up in a shallow way. In ToString without rewriting, the output result of the value type is the current value, and for the application type, the output is the class name of the current object.

Test code:

    class Program
    {
    
    
        public static void Main(string[] args)
        {
    
    
            Int32 a = 520;
            Object b = new Object();
            double c = 13.14;
            Person d = new Person();
            Console.WriteLine("值类型(Int32类型)的字符串的表现形式:{0}", a.ToString());
            Console.WriteLine("值类型(double类型)的字符串的表现形式:{0}", c.ToString());
            Console.WriteLine("引用类型(Object类型)字符串的表现形式:{0}", b.ToString()); 
            Console.WriteLine("引用类型(Person类型)字符串的表现形式:{0}", d.ToString());


            Console.ReadKey();
        }
    }

insert image description here

Four Keywords in Inheritance

① Call the parent class member method - base

1) The relationship between attributes and methods in the inheritance relationship
When the subclass and the superclass define a method with the same name, the object in the subclass cannot call the method of the same name in the superclass, and the method in the subclass is called. .
If the subclass needs to call the members in the parent class, it can be done with the base keyword. The specific usage is as follows:
base. 父类成员

The user will encounter this and base keywords in the program, the this keyword represents the object of the current class, and the base keyword represents the object in the parent class.

In the case where both the Student class and the Teacher class inherit from the Person class, they have their own Print method for outputting information.
insert image description here

If you do not add the base keyword and directly call the Print method in the two derived classes, you will get the following results:
insert image description here
When you need to use the methods in the parent class, you need the help of the base keyword:

insert image description here
Test results:
insert image description here
2) In the inheritance relationship The relationship between constructors
By default, the no-argument constructor of the parent class is automatically called in the constructor of the subclass, and :base(参数)the form is only used if the constructor with parameters in the parent class needs to be called.

[Demo by default]
insert image description here
Test result:
insert image description here
[Call subclass with parameter constructor demo]
insert image description here

Test Results:
insert image description here

Then, if you want to call the parameterized constructor of the parent class, you need :base(参数)to implement it.
insert image description here
Test result:
insert image description here
Test summary:
This form is only used if you need to call the constructor with parameters in the parent class :base(参数).

② Increase program scalability - virtual and abstract

1) virtual (virtual method)
The virtual keyword can modify methods, properties, indexers and events, etc., and is used in the members of the parent class.
Its syntax is as follows:

//修饰属性
public  virtual  数据类型  属性名{
    
    get; set; }

//修饰方法
访问修饰符  virtual  返回值类型方法名
{
    
    
    语句块;
}

Note: The virtual keyword cannot modify members that are modified with static.

The virtual keyword is used to decorate methods in the base class. There are two situations in which virtual is used:

Case 1: A virtual method is defined in the base class, but the virtual method is not overridden in the derived class. Well 在对派生类实例的调用中,该虚方法使用的是基类定义的方法.
insert image description here

Extension:
At this time, the method in the subclass Student class has no modifier. If it is added to hidenew 关键字 the method in the subclass , the result is the same as the new modifier (C# reference )

insert image description here

Let's take a look at the output:
insert image description here
test code:

       public class Person
        {
            public int Id { get; set; }=1001;
            public string Name { get; set; } = "张三";
            public string Sex { get; set; } = "男";
            public string Cardid { get; set; } = "0x1111";
            public string Tel { get; set; } = "13390782367";

            public Person()
            {
                //Console.WriteLine("这是父类Person中的无参数构造器");
            }

            public Person(string str)
            {
                 Console.WriteLine("这是父类Person中的有参数构造器,输入的参数是"+str);
            }

            public virtual void Print()
            {
                Console.WriteLine("编号:" + Id);
                Console.WriteLine("姓名:" + Name);
                Console.WriteLine("性别:" + Sex);
                Console.WriteLine("身份证号:" + Cardid);
                Console.WriteLine("联系方式:" + Tel);
            }
        }

 class Student:Person
    {
        public string Major { get; set; } = "计科技";
        public string Grade { get; set; } = "2001";
        public void Print()
        {
            Console.WriteLine("专业:" + Major);
            Console.WriteLine("年级:" + Grade);
        }
    }
 class Program
    {
        public static void Main(string[] args)
        {
            Person p = new Person();
            Console.ForegroundColor =  ConsoleColor.DarkRed;
            Console.WriteLine("这是父类Person自己的Print方法(虚方法)输出的内容:");
            p.Print();
            Console.ResetColor();

            Console.WriteLine();
            Console.ForegroundColor =  ConsoleColor.Cyan;
            Console.WriteLine("在子类Student不重写该虚方法的情况下:");
            Person stu1 = new Student();
            stu1.Print();
            Console.ResetColor();


            Console.ReadKey();
        }
    }

Case 2: A virtual method is defined in the base class and then used in the derived class override重写. Then在对派生类实例的调用中,该虚方法使用的是派生重写的方法。
insert image description here
test result:
insert image description here
So to sum up, when the virtual keyword is used for the parent class, when the inherited subclass declares another method of the same name and does not use overrideoverriding, the method in the parent class is called by default.
But if it is overridden, it can be understood that the subclass method is better, then the system will call the overridden method.

2) abstract (abstract method)

It can be seen as a virtual method without an implementation body.

An abstract method is declared and used, and it is a method that must be overridden by a derived class 抽象类就是用来被继承的; if a class contains an abstract method, the class must be defined as an abstract class, regardless of whether it also contains other general methods; abstract classes cannot have entities.

Definition syntax of abstract method:

访问修饰符  abstract  方法返回值类型  方法名(参数列表);

[In-class walkthrough]
Create an abstract class ExamResult, and define the attributes of student ID, math (Math), and English (English) grades in the class, and define an abstract method to calculate the total grade.
Define the student classes of mathematics major and English major respectively to inherit the abstract class ExamResult, rewrite the method of calculating the total score and calculate the total score according to the different weights of the subject scores.
Among them, mathematics majors account for 60% of mathematics scores, and English scores account for 40%; English majors account for 40% of mathematics scores and 60% of English scores.

Test results:
insert image description here
This small exercise is quite simple, and its role is limited to familiarity 定义抽象类with重写抽象方法

test code

 abstract class ExamResult
    {
    
    
        //学号
        public int Id {
    
     get; set; }
        //数学成绩
        public double Math {
    
     get; set; }
        //英语
        public double English {
    
     get; set; }

        //计算总成绩
        public abstract void Total();
    }


class MathMajor : ExamResult
    {
    
    
        public override void Total()
        {
    
    
            double total = Math * 0.6 + English * 0.4;
            Console.WriteLine("学号为"+Id+"的数学专业的同学的最终成绩为:"+total);
        }
    }
class EnglishMajor : ExamResult
    {
    
    
        public override void Total()
        {
    
    
            double tatol = Math * 0.4 + English * 0.6;
            Console.WriteLine("学号为"+Id+"的英语专业的同学的最终成绩为"+tatol);
        }
    }

Summary:
In practical applications, subclasses can only override virtual methods or abstract methods in the parent class 当不需要使用父类中方法的内容时,将其定义成抽象方法,否则将方法定义成虚方法.

③ Declare a sealed class or a sealed method - sealed

The meaning of the sealed keyword is sealed. Using this keyword can modify a class or a method in a class. The modified class is called a sealed class, and the modified method is called a sealed method.

The sealed method must appear in the subclass and be the superclass method overridden by the subclass, that is, the sealed keyword must be used together with the override keyword.

[Drilling in class]
Create an abstract class AreaAbstract that calculates area, and define an abstract method to calculate area.

Define the rectangle class to inherit the abstract class and override the abstract method to define it as a sealed method;
define the circle class to inherit the abstract class and override the abstract method to define the class as a sealed class.

Here you can also accumulate how C# outputs floating-point numbers with a specified number of digits.
Reference article

Reference Code

abstract class AreaAbstract
    {
    
    
        public abstract void Total();
    }
class Rectangle : AreaAbstract
    {
    
    
        //设置自己的长和宽的熟悉
        public double Len {
    
     get; set; }
        public double Wid {
    
     get; set; }

        //重写抽象方法,并定义为密封方法
        public sealed override void Total()
        {
    
    
            Console.WriteLine("该矩形的面积是"+Len*Wid);
        }
    }
sealed class Round : AreaAbstract
    {
    
    
        //计算圆面积的半径熟悉
        public double R {
    
     get; set; }
        public override void Total()
        {
    
    
            //积累C# 浮点类型输出指定位数
            Console.WriteLine("该圆的面积是{0:f3}",R*Math.PI);
        }
    }

The Round class cannot be inherited:
insert image description here
The Area method in the Rectangle class cannot be overridden.
insert image description here

insert image description here

Summarize

① C# only supports single inheritance, which is used to solve the problem of code reuse. C# uses interfaces to solve multiple inheritance.
② The Object class is the most primitive and important class in the C# language. There are Equals()、GetHashCode()、GetTyep()、ToString()four methods under it. When we actually use them, most of them need to rewrite these four methods.
③ If you want to use a method in the parent class in the subclass, you need to use the keyword base④ The
subclass can only use the content of the parent class. Define the method as a virtual method.重写虚方法或者抽象方法

Guess you like

Origin blog.csdn.net/weixin_52621323/article/details/125730125