一 类继承

继承是使代码可以复用的重要手段,也是面向对象程序设计的核心思想之一。继承呈现了面向对象程序设计的层次结构。

通过继承,我们能以一个已经存在的类为基础来定义一个新类。已存在的类称为基类或父类,新类称为派生类或子类。

派生类的成员包括:基类的成员和派生类自身声明的成员。

继承自基类的成员可以被访问,就像是派生类自己声明的一样。

class BaseClass
{
public string BaseField = "BaseField";
public void BaseMethod(string str)
{
Console.WriteLine($"BaseWrite:{str}");
}
}
class DerivedClass : BaseClass
{
public string DerivedField = "DerivedField";
public void DerivedMethod(string str)
{
Console.WriteLine($"DerivedWrite:{str}");
}
}
class Program
{
static void Main()
{
//派生类可以访问基类的成员
var derived = new DerivedClass();
derived.BaseMethod(derived.BaseField);
derived.BaseMethod(derived.DerivedField);
derived.DerivedMethod(derived.BaseField);
derived.DerivedMethod(derived.DerivedField);
}
}

二 所有类都派生自object类

除了object类,所有的类都是派生类,没有基类规格说明的类隐式地派生自object类。

object类是唯一的非派生类,因为它是继承层次结构的基础。

C#的类是单继承,一个类只能直接继承一个基类,而一个基类可以有多个派生类。

类继承的层次没有限制,作为基类的类A可以派生自类B,而这个类B又派生自类C,一直下去,直至object类。


三 屏蔽基类的成员

派生类不能删除基类的成员,但可以使用new关键字修饰基类成员名称相同的成员来屏蔽基类成员。

如果派生类需要访问被屏蔽的基类成员,可以使用base.表达式,实现基类访问。

从程序设计角度,应尽量避免使用基类访问这一特性。

class BaseClass
{
public string BaseField = "BaseField";
}
class DerivedClass : BaseClass
{
new public string BaseField = "NewBaseField"; //屏蔽基类成员
public void Show()
{
Console.WriteLine(BaseField); //输出NewBaseField
Console.WriteLine(base.BaseField); //输出BaseField
}
}
class Program
{
static void Main()
{
var derived = new DerivedClass();
derived.Show();
}
}

四 使用基类的引用

4.1 派生类的实例可以转换成基类的实例

关于里式转换:

  • 子类可以赋值给父类
  • 如果一个父类对象中装的是子类对象,则可以将这个父类对象强制转换为子类对象。

派生类的实例由基类的实例加上派生类新增的成员组成。派生类的引用指向整个类对象。

如果有一个派生类对象的引用,就可以通过转换获取基类部分的引用。

class MyBaseClass
{
public void Print()
{
Console.WriteLine("This is the base class");
}
}
class MyDerivedClass : MyBaseClass
{
new public void Print()
{
Console.WriteLine("This is the derivedclass");
}
}
class Program
{
static void Main()
{
MyDerivedClass derived = new MyDerivedClass();
MyBaseClass mybc = (MyBaseClass)derived; //转换成基类
derived.Print(); // This is the derivedclass
mybc.Print(); // This is the base class
}
}

4.2 虚方法和覆写方法

虚方法可以是基类的引用访问升至派生类中。

使用基类引用调用派生类的方法需要满足:

  • 派生类的方法和基类的方法具有相同的签名和返回类型;
  • 基类方法使用virtual标注;
  • 派生类方法使用override标注;

属性、事件和索引器也可以使用virtual-override

class MyBaseClass
{
virtual public void Print()
{
Console.WriteLine("This is the base class");
}
}
class MyDerivedClass : MyBaseClass
{
override public void Print()
{
Console.WriteLine("This is the derivedclass");
}
}
class Program
{
static void Main()
{
MyDerivedClass derived = new MyDerivedClass();
MyBaseClass mybc = (MyBaseClass)derived; //转换成基类
derived.Print(); // This is the derivedclass
mybc.Print(); // This is the derivedclass
//对基类方法的调用实际上调用了派生类中的方法
}
}


五 构造函数的执行

要创建对象的基类部分,需要隐式地调用基类的某个构造函数;

继承层次链中的每个类在执行它自己的构造函数前执行它的基类构造函数。

5.1 构造函数初始化语句

使用关键字base指明使用哪一个基类构造函数。

使用关键字this指明使用当前类的哪个构造函数。

public MyDerivedClass(int x,string s):base(s,x)
...
------------
public MyDerivedClass(int x):this(s,"default string")
...

六 类访问性和成员访问性

类的可访问性有两种:

  • public : 可以被系统内任何程序集中的代码访问
  • internal : 只能被它自己所在程序集内的类访问

成员的可访问性有五种:

  • private : 只在类的内部可访问
  • internal : 该程序集内所有类可访问
  • protected : 所有继承该类的类可访问
  • protected internal : 对所有继承该类的类和该程序集内所有类可访问
  • public : 任何类可访问

七 抽象类

7.1 抽象成员

抽象成员是被设计为被覆写的函数成员,抽象成员只可以在抽象类中声明。

  • 抽象成员必须是一个函数成员(方法、属性、事件、索引),字段和常量不能是抽象成员。
  • 必须用abstract修饰符标记
  • 不能有实现代码块

7.2 抽象类

抽象类是指设计为被继承的类,它只能被用作其他类的基类。

  • 抽象类用abstract修饰符声明;
  • 不能创建抽象类的实例;
  • 抽象类可以包含抽象成员和非抽象成员;
  • 抽象类自己可以派生自另一个抽象类;
  • 派生自抽象类的类必须使用override关键字实现该类的所有抽象成员,除非派生类自己也是抽象类

八 密封类

  • 密封类使用sealed修饰符修饰;
  • 密封类不能用作基类;

九 静态类

  • 静态类使用static标记;
  • 静态类中所有成员都必须是静态的;
  • 可以有一个静态构造函数,但不能有实例构造函数,不能创建实例;
  • 静态类是隐式密封的,不能被继承;

C#-5 类和继承的更多相关文章

  1. UML类图(上):类、继承和实现

    面向对象设计 对于一个程序员来说,在工作的开始阶段通常都是别人把东西设计好,你来做.伴随着个人的成长,这个过程将慢慢变成自己设计一部分功能来实现,自己实现.如果要自己设计,无论是给自己看,还是给别人看 ...

  2. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

  3. (转)Java:类与继承

    原文地址: http://www.cnblogs.com/dolphin0520/p/3803432.html 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态这四大 ...

  4. iBatis.net 类的继承extends和懒加载

    <resultMaps> <resultMap id="FullResultMap" class="t_c_team_member_permission ...

  5. python 类定义 继承

    0 前言 系统:win7 64bit IDE : python(x,y) 2.7.6.1 IDE集成的解释器:Python 2.7.6 (default, Nov 10 2013, 19:24:18) ...

  6. JS原型继承和类式继承

    前言 一个多月前,卤煮读了一篇翻译过来的外国人写的技术博客.此君在博客中将js中的类(构造)继承和原型继承做了一些比较,并且得出了结论:建议诸位在开发是用原型继承.文中提到了各种原型继承的优点,详细的 ...

  7. Java编程里类的继承

    今天,我们将要讨论的内容是Java里面类的继承的相关概念. 说到继承,我相信大家都不陌生.生活中,子承父业,子女继承父母的财产,这就是继承.实际上,Java里的继承也是如此.对于一个类来说,它的数据成 ...

  8. Java:类与继承

    Java:类与继承 对于面向对象的程序设计语言来说,类毫无疑问是其最重要的基础.抽象.封装.继承.多态这四大特性都离不开类,只有存在类,才能体现面向对象编程的特点,今天我们就来了解一些类与继承的相关知 ...

  9. swift_Class类的继承

    //: Playground - noun: a place where people can play var str = "Hello, playground" //***** ...

  10. C#类的继承,方法的重载和覆写

    在网易云课堂上看到唐大仕老师讲解的关于类的继承.方法的重载和覆写的一段代码,注释比较详细,在此记下以加深理解. 小总结: 1.类的继承:允许的实例化方式:Student t=new Student() ...

随机推荐

  1. tokitsukaze and Soldier 来源:牛客网

    题目 链接:https://ac.nowcoder.com/acm/contest/28886/1004 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 524288K, ...

  2. Sharding-jdbc + Seata + Nacos整合

    前置条件 先了解Sharding-jdbc.Seata.Nacos这三样东西各自的作用以及单独使用时的配置. 整合代码已放在github,详细步骤章节请搭配此项目看,欢迎start 思路 如果已经做过 ...

  3. java字符串类型数学运算表达式以及精度丢失问题

    字符串类型数学运算精度丢失问题 方式一:ScriptEngine 会精度丢失,可执行连续双括号 方式二:hutool ScriptUtil 会精度丢失,可执行连续双括号 方式三:hutool Scri ...

  4. Linux学习系列--用户(组)新增、查看和删除

    在实际的工作中,在接触Linux的用户组管理的时候,一般来说都是在系统开建设的时候设置好,root权限由特定的负责人保管用户密码,避免误操作带来不必要的麻烦. 在具体使用的时候,会利用相关的命令设置一 ...

  5. C#静态类、静态成员、静态方法

    一.作用 静态类和非静态类重要的区别是在于静态类不能被实例化,也就是说不能使用  new 关键字创建静态类类型的变量,防止程序员写代码来实例化该静态类或者在类的内部声明任何实例字段或方法. 用于存放不 ...

  6. CF1615G Maximum Adjacent Pairs

    \(CF1615G\) Description 给定一个数列 \(a\),你需要将所有 \(a_i=0\) 的位置填上一个 \(1\sim n\) 的正整数,使得数列的「值」最大. 数列的值定义为满足 ...

  7. 客户流失?来看看大厂如何基于spark+机器学习构建千万数据规模上的用户留存模型 ⛵

    作者:韩信子@ShowMeAI 大数据技术 ◉ 技能提升系列:https://www.showmeai.tech/tutorials/84 行业名企应用系列:https://www.showmeai. ...

  8. transform: scale() 实现鼠标悬浮在元素之上出现和消失

    前言 transform属性允许你旋转,缩放,倾斜或平移给定元素.其中scale(x, y)就是实现元素缩放的属性值. scale(x, y)的 x 乘以原本元素的 x:y 乘以原本的元素 y,就可以 ...

  9. Word 段前分页是什么?怎么设置?

    描述 这两个标题在第一个标题的页中,且两个标题都没有独立分页.要让每一个标题独立分页,需要对标题的格式进行修改. 段前分页指的是标题与标题之间不在同一个页中,每一个标题都在独立的页中. 设置段前分页 ...

  10. RabbitMQ 入门系列:5、基础编码:交换机的进阶介绍及编码方式。

    系列目录 RabbitMQ 入门系列:1.MQ的应用场景的选择与RabbitMQ安装. RabbitMQ 入门系列:2.基础含义:链接.通道.队列.交换机. RabbitMQ 入门系列:3.基础含义: ...