图片 1

如果我们想要使派生类调用基类的有参构造函数,而不是无参构造函数,就可以在派生类中通过base为其要调用的基类构造函数

 1     class Person
 2     {
 3         public Person(string name)
 4         {
 5             Console.WriteLine("姓名:"+name);
 6         }
 7     }
 8 
 9     class Student : Person
10     {
11         public Student(string name, string num)
12             : base(name)
13         {
14             Console.WriteLine("学号:"+num);
15         }
16     }
17 
18     class Program
19     {
20         static void Main(string[] args)
21         {
22             Student stu = new Student("张三", "0002");
23             Console.ReadKey();
24         }
25     }

实现继承后每个子类仅保留了自己特有的特性,大大减少了冗余。

3.面向对象程序设计:

           
面向过程:分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用
                               的时候一个一个一次调用就可以了。

           
 面向对象:把构成事物分解成各个对象,创建对象后用对象调用各自方法以达到解决问
                               题的目的

           特性:封装,继承,多态,(密封);

         
 OOP(面向对象编程)达到软件工程的三个目标:重用性,灵活性,扩展性;

继承

继承表示一个类型(子类)派生自(继承于)一个基类型(父类),该类型将拥有基类型的所有成员字段和函数(不包括构造函数和析构函数)。

注意:

  • 派生类继承基类的所有成员,不管是public、private、protected还是其他的,不管是静态的还是非静态的;但是,虽然派生类继承类基类所有的成员,基类却只能访问由public和protected修饰的成员(派生类继承了基类所有的字段,但是只能访问基类中public和protected修饰的成员)

    1 class Person
    2 {
    3 private string name = “张三”;
    4 protected int age = 20;
    5 public bool gender = true;
    6
    7 public void ShowInfo_Person()
    8 {
    9 Console.WriteLine(this.name + “:” + this.age + “:” + this.gender);
    10 }
    11 }
    12
    13 class Chinese : Person
    14 {
    15 public void ShowInfo_Chinese()
    16 {
    17 Chinese chinese = new Chinese();
    18 Console.WriteLine(chinese.age);
    19 Console.WriteLine(chinese.gender);
    20 //Console.WriteLine(chinese.name);//由于基类中name用private修饰,所以在派生类中无法访问
    21 }
    22 }
    23
    24 class Program
    25 {
    26 static void Main(string[] args)
    27 {
    28 Chinese chinese = new Chinese();
    29 chinese.ShowInfo_Person();//输出结果:张三:20:True 此处通过派生类对象chinese可以调用基类中的ShowInfo_Person()方法,可以说明派生类也继承了private修饰的name字段
    30 Console.ReadKey();
    31 }
    32 }

  • 派生类(子类)只能有一个直接基类(父类);但是继承是可以传递的,例如ClassB派生自ClassA,同时ClassC派生自ClassB,那么ClassC会继承ClassB和ClassA中声明的成员。

    1 class Animal
    2 {
    3 public void Method_Animal()
    4 {
    5 Console.WriteLine(“Animal:—————“);
    6 }
    7 }
    8
    9 class Dog : Animal
    10 {
    11 public void Method_Dog()
    12 {
    13 Console.WriteLine(“Dog:***“);
    14 }
    15 }
    16
    17 class ErHa : Dog
    18 {
    19 public void Method_ErHa()
    20 {
    21 Console.WriteLine(“ErHa:……………”);
    22 }
    23 }
    24
    25 class Program
    26 {
    27 static void Main(string[] args)
    28 {
    29 ErHa eh = new ErHa();
    30 eh.Method_Animal();
    31 eh.Method_Dog();
    32 eh.Method_ErHa();
    33 Console.ReadKey();
    34 }
    35 }

  • C#不支持多重继承,派生类只能有一个直接基类,但是可以实现多个接口,并通过实现多个接口达到多重继承的目的

    1 interface IAnimal
    2 {
    3 void Method_Animal();
    4 }
    5
    6 interface IDog
    7 {
    8 void Method_Dog();
    9 }
    10 //实现多重继承
    11 class ErHa : IAnimal, IDog
    12 {
    13 public void Method_ErHa()
    14 {
    15 Console.WriteLine(“ErHa:……………”);
    16 }
    17
    18 public void Method_Animal()
    19 {
    20 Console.WriteLine(“Animal:**“);
    21 }
    22
    23 public void Method_Dog()
    24 {
    25 Console.WriteLine(“Dog:—————“);
    26 }
    27 }
    28
    29 class Program
    30 {
    31 static void Main(string[] args)
    32 {
    33 ErHa eh = new ErHa();
    34 eh.Method_Animal();
    35 eh.Method_Dog();
    36 eh.Method_ErHa();
    37 Console.ReadKey();
    38 }
    39 }

  • 结构不支持继承

  • 派生类是对基类的扩展,派生类可以对基类进行成员的添加、重写、覆盖操作

学过构造函数的应该都会知道,类在没有指定任何构造函数的情况下,程序默认会指派一个无参的构造函数。

     
 以前看过一个节目,其中有一个情节:一个小女孩对几本文言文书籍熟读能背像《三字经》,《诗经》,《笠翁对韵》。主持人吃惊的她的妈妈,这么小让她接触文言文,小孩子不会觉得难而反感,为什么现在还兴致勃勃。他妈妈的答案里有一句话至今让我记忆犹新:“…小孩子的世界里没有难易概念的…”

图片 2

 当基类中不存在无参的构造函数时,需要通过base关键字派生类指定其要调用的基类的构造函数

 1     class Person
 2     {
 3         public Person(string name)
 4         {
 5             Console.WriteLine(name);
 6         }
 7     }
 8 
 9     class Student : Person
10     {
11         public Student()
12         {
13             Console.WriteLine();
14         }
15     }
16 
17     class Program
18     {
19         static void Main(string[] args)
20         {
21             Student stu = new Student();
22             Console.ReadKey();
23         }
24     }

 以上代码执行时会出现以下错误:

实现继承后产生了两个角色:1.子类(派生类)、2.父类(基类)

2.析构方法:

析构方法:
析构方法用于析构类的实例,构造方法用于实例化,分配内存空间,而析构方法正
                     好与它相反,用于释放内存空间

图片 3

图片 4

小结:不能再结构中定义析构方法,只能对类使用析构方法;

            一个类只能有一个析构方法;

           无法继承或重载析构方法;

            它们是被自动调用的;

           析构方法既没有修饰符,也没有参数;

图片 5

接下来我们通过以下代码,了解一下子类对象的初始化过程

 1     class Person
 2     {
 3         public string name = "默认值:张三";
 4         public string gender = "默认值:男";
 5         public Person(string name, string gender)
 6         {
 7             this.name = name;
 8             this.gender = gender;
 9         }
10     }
11 
12     class Student : Person
13     {
14         public string num = "默认值:0002";
15         public Student(string name, string gender, string num)
16             : base(name, gender)
17         {
18             this.num = num;
19         }
20     }
21 
22     class Program
23     {
24         static void Main(string[] args)
25         {
26             Student stu = new Student("李四", "女", "0004");
27             Console.WriteLine(stu.name);
28             Console.WriteLine(stu.gender);
29             Console.WriteLine(stu.num);
30             Console.ReadKey();
31         }
32     }

 当在Main方法中实例化Student的对象时,首先在内存中分配了空间,内存中的初始状态如下图:

图片 6

 调用派生类的构造函数,首先会调用基类的构造函数,由于我们在派生类Student中通过base关键字指定了派生类要调用的基类构造函数为public
Person(string name,string
gender),所以首先会用传入的参数替换掉基类中成员的默认值,执行完成后,内存中的情况如下:

图片 7

 执行完指定的基类构造函数后,执行派生类自身的构造函数,执行完成后,内存中的情况如下:

图片 8

至此,派生类对象实例化完成。

上述的例子由于我们手动添加的那个构造函数,默认的构造函数就被清除掉了。

4.面向对象的特性:

封装:是实现面向对象程序设计的第一步,封装就是将数据或者函数等集合在一个个的单元中
            (我们称之为类)

           
意义,在于保护或者防止代码(数据)被我们无意中破坏,在于高效的调动各个对象资
            源;

            就是对类成员的再次包装,这样写更规范:
 Get方法,Set方法对字段的封装,属性对               字段的封装

图片 9

继承:继承用于创建可重用,扩展和修改在其他类中定义的行为的新类。其成员被继承的类称
           
为“基类”,继承这些成员的类称为“派生类”。派生类只能有一个直接基类。但是,继承是
           
可以传递的。如果ClassB派生出ClassC,ClassA派生出ClassB,则ClassC会继承  
                  ClassB和ClassA中的成员;

通过在派生类名后面追加冒号和基类名称,可以指定基类

图片 10

在创建子类的时候,必须要调用父类的构造方法,调用方式有两种:1,隐式调用2,显示调用
          (base)    隐式调用用了父类的无参构造器

图片 11

(后续)

构造函数

  • 派生类无法继承基类的构造函数
  • 当调用派生类的构造函数时,默认先调用基类的无参构造函数,当基类没有无参构造,需要派生类通过base关键字指定要调用的基类构造函数

    1 class Person
    2 {
    3 public Person()
    4 {
    5 Console.WriteLine(“父类的无参构造函数被调用”);
    6 }
    7 }
    8
    9 class Student:Person
    10 {
    11 public Student()
    12 {
    13 Console.WriteLine(“子类的无参构造函数被调用”);
    14 }
    15 }
    16
    17 class Program
    18 {
    19 static void Main(string[] args)
    20 {
    21 Student stu = new Student();
    22 Console.ReadKey();
    23 }
    24 }

 执行结果:

子类继承父类后,将会隐式继承父类的所有成员,但不包括构造函数。

       
是啊,一片白纸,你上什么颜色,它就接受什么颜色。它没有什么去对比。就如我们一般,没有接触过机器语言,汇编语言,甚至C语言,直接就是C#。所有我们大多数人没有对C#关于直接面向对象思想方法出来而感到神奇的觉悟。(后续待更)

 图片 12

                                                                       
                                                                       
              2017年3月21日  于青岛软件园  夜 21:42

图片 13

(整理笔记)

图例:

1.构造方法:

Man类后面的“()”,其实就是构造方法。只要你想创建类或结构的实例,必须调用它的构造方法,构造方法负责对类里面的字段进行初始化。(初始化
int 类型为0,bool类型为 false,char,string类型为“空”….)

图片 14

定义:构造方法必须类重名; 构造方法没有返回值,但可以有参数;

图片 15

构造方法可以有多个重载;  不带参数的构造方法为默认构造;

小结: 构造方法的本质是一个构造器,是为了类的实例化而产生;

           
构造方法是一种特殊的方法,它没有返回值,它必须与类重名,它只能在初始化的时候
            被系统自动执行,外部不能调用;

          如果将构造函数设置为private,则不能被外部实例化;

         
如果类里面有带参数的构造方法,想调默认构造时,必须把默认构造显示写出来;

遇到小问题:

图片 16

答案如下: 可以

图片 17

继承从字面上理解,无外乎让人想到某人继承某人的某些东西,一个给一个拿。这个语义在生活中,就像

面向对象编程:

图片 18

根据VS给我们提示的消息,我们可以看出,当代码中存在子类的成员和父类的成员相同的时候,子类的成员将父类的成员隐藏了。


子类的共性成员都被父类提取了,那么子类要使用怎么办?

图片 19

作用2:

继承的特性

通过一个简单的  :(冒号)实现了继承关系。

继承后的能力

 如何解决此类冗余问题 ——
使用继承

为什么会提示报这个错误?意思说父类不能没有一个无参的构造函数。

实现继承后的关系如下图:

父类的构造函数,在子类的内部创建一个父类的对象,以便自己去调用父类的成员。

子类会首先去默认执行父类的无参构造函数,然后在执行自己的构造函数

因为子类继承了父类的成员,这一项描述只能说明子类拥有的权利,并不代表子类去执行了。

通过调试发现在创建子类对象时的代码执行逻辑如下:

依次顺序可以不断向上取。

 

根据此特征我们可以推测子类和父类的构造函数一定有关系,但一定不是继承关系

 图片 20

 

图片 21

发表评论

电子邮件地址不会被公开。 必填项已用*标注