面向对象3大特性之一:继承

继承

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

注意:

  • 派生类继承基类的所有成员,不管是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     }
  • 结构不支持继承
  • 派生类是对基类的扩展,派生类可以对基类进行成员的添加、重写、覆盖操作

构造函数

  • 派生类无法继承基类的构造函数
  • 当调用派生类的构造函数时,默认先调用基类的无参构造函数,当基类没有无参构造,需要派生类通过base关键字指定要调用的基类构造函数
 1     class Person
 2     {
 3         public Person() 4         {
 5             Console.WriteLine("父类的无参构造函数被调用");
 6         }
 7     }
 8
 9     class Student:Person10     {
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     }

执行结果:

当基类中不存在无参的构造函数时,需要通过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     }

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

如果我们想要使派生类调用基类的有参构造函数,而不是无参构造函数,就可以在派生类中通过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     }

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

 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的对象时,首先在内存中分配了空间,内存中的初始状态如下图:

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

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

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

时间: 2025-01-17 04:46:03

面向对象3大特性之一:继承的相关文章

面向对象的三大特性之继承

# 面向对象的三大特性之继承 # 当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好 (如机器人) # 当类之间有很多相同的功能,提取这些共同的功能做成基类,用继承比较好 (动物--猫) # 继承同时有两种含义:1,继承基类的方法,并且做出自己的改变或扩展(代码重用),这种意义并不大,因为它使子类和基类出现强耦合 # 2,声明某个子类兼容于某基类.定义一个接口类,子类继承接口类,并实现接口中定义的方法 # 接口继承只是接口类规定了子类必须实现的方法,但是接口类里不去实现,子类

面向对象4大特性

面向对象4大特性:抽象,封装,继承,多态. 抽象:在类的设计层次:将某些事务的共同属性提取出来集合到一个类:类与对象之间的关系:类时抽象的,对象是具体的,类是对象的模板,对象的创建时以类未模板的,同一个类创造出来的对象具有共同的属性,但属性值不同. 封装:利用抽象数据类型将数据和基于数据的操作封装在一起(事物的属性和方法),数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系.系统的其他部分只有通过包裹在数据外面的被授权的操作来与这个抽象数据类型交流与交互

面向对象的三大特性之继承-基础知识总结------彭记(05)

面向对象的三大特性之继承: js中的某些对象没有一些需要的属性和方法,但是另外的对象有,那么拿过使用,就是继承. js中继承的实现方式: 1.混入式继承:通过循环将一个对象中的所有属性和方法混入到另外一个对象中: var me={ work:function(){ console.log('敲代码'): } }: var mayun={ money:9999999, car:'000', manager:function(){ console.log('管理巴巴...'); } } /*遍历,让

java基础篇(二) ----- java面向对象的三大特性之继承

java面向对象的三大特性之继承: 复用代码是java众多引人注目的功能之一,但是想要成为极具革命性的语言,仅仅是复制代码并对其加以改变是不够的.它必须能够做更多的事.引自<Think in java>    而代码复用也是程序员一直不断追求的.由此来说下代码复用的一种方式 java面向对象的三大特性--继承!! 在面向对象程序设计中,继承机制可以有效地组织类的结构.确定类之间的关系,在已有类的基础上开发新的类.继承机制在程序代码复用.提高软件开发效率.降低软件系统维护成本等方面具有重要作用.

面向对象的三大特性---封装继承多态

面向对象的三大特性---封装继承多态 首先我们来创建一个控制台程序 新建一个父类Person 创建一个子类继承父类Person 子类: main函数: 输出结果: 根据结果显示创建子对象,首先调用父类的构造函数在调用子类的构造函数. 继承的传递性 例如: A:B,B:C,则A:C ⅰ.继承过来之后被隐藏,有意隐藏加一个关键字"new",如果加了关键字"new",就告诉子类,父类里面的sayHi只能被隐藏,不能被覆写  ⅱ.继承过来之后被覆写/重写,覆写需要在父类里面

面向对象编程三大特性之继承

面向对象编程有三大特性:继承,封装,多态~ 从object基类开始,逐步向下开枝散叶,组成了整个对象体系. 为什么要用这种形式? 解答这个问题之前,我们可以先回顾一下生物的进化史~ 从单细胞开始到现在的哺乳动物,在不断地进化中,物种的身体结构愈加复杂,这种进化所花费的时间非常漫长,但是一旦进化成功,后代就可以直接拥有父母的结构,而不用再次花费漫长的时间用来进化. 现在我们再次回到继承上来,object基类支持 .NET Framework 类层次结构中的所有类,并为派生类提供低级别服务.这是 .

面向对象3大特性:封装、继承、多态——封装(this 、访问修饰符、内部类)

封装的概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问.而是通过该类提供的方法来实现对隐藏信息的操作和访问 封装的好处: a.只能通过规定的方法访问数据 b.隐藏类的细节,方便修改和实现 封装的实现步骤: 1.修改属性的可见性--设为private 2.创建getter/setter方法--用于属性的读写 3.在getter/setter方法中进入属性控制语句--对属性值的合法性进行判断 public class TelPhone { //定义成员变量 private float sc

java中的3大特性之继承

继承的特点:继承父类的属性和方法.单继承(多层继承)c++里的继承是多继承 特性 :方法的复写(重写) java中的继承和OC中一样. 比如:人可以养狗; 人---->狗 :整体和部分(拥有)关系. 球队---->球员 :整体和部分的关系. 代码中是最常见 has a 的关系 人 ---->学生 :学生是人  : 说明有一个继承关系存在 , 关系到底是否表现出来,有具体的情况来决定. 如何判断两个事物之间是否存在一个继承关系: is a  谁是谁是否成立.成立就有继承关系. A:B :

Python全栈开发——面向对象的三大特性(继承 &amp; 多态 &amp;封装)

1.继承 1.两层意思改变和扩展(详细看随笔继承和组合) 2.多态(体现在运行时的状态) 1.不同的类可以调用相同的方法,得到不同的结果 2.实际上是继承的一种体现机制 class H2o: def __init__(self,name,temperature): self.name=name self.temperature=temperature def turn_ice(self): if self.temperature<0: print('温度太低,变成[%s]' %self.name