【转】C#之继承

C#之继承

一.继承的类型
  在面向对象的编程中,有两种截然不同继承类型:实现继承和接口继承
  1.实现继承和接口继承
  *实现继承:表示一个类型派生于基类型,它拥有该基类型的所有成员字段和函数。在实现继承中,派生类型采用基类型的每个函数的实现代码,除非在派生类型的定义中指定某个函数的实现代码。在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时,可以使用这种类型的继承。
  *接口继承:表示一个类型只继承了函数的签名,没有继承任何的代码。在需要指定该类型具有某些可用的特性时,最好使用这种类型的继承。
  2.多重继承
  C#不支持多重继承,但C#允许类型派生自多个接口————多重接口继承。这说明,C#类可以派生自另一个类和任意多个接口。更准确的说,因为System.Object是一个公共的基类,所以每个C#(除Object之外)都有一个基类,还可以有任意多个接口。
  3.结构的继承
  使用结构的一个限制是结构不支持实现继承,但每个结构都自动派生自System.ValueType。不能编码实现类型层次的结构,但结构可以实现接口。

二.继承的实现
  语法:
  class MyDreved:BaseClass
  {

  }
  如果类或结构也派生自接口,则用逗号分隔列表中的基类和接口:
  class MyDreved:BaseClass,IIntenface1,IIntenface2
  {

  }

  如果在类定义中没有指定基类,C#编译器就假定System.Object是基类。

  1.虚方法
  把一个基类函数声明为virtual,就可以在任何派生类中重写(override)该函数:
  class BaseClass
  {
    public virtual void VirtualMethod()
    {
      //
    }
  }

  也可以把属性声明为virtual。对于虚属性或重写属性,语法与非虚属性相同,但要在定义中添加virtual关键字:
  public virtual string Name
  {
    get;set;
  }

  C#中虚函数的概念与标准OOP的概念相同:可以在派生类中重写虚函数。在调用方法时,会调用该派生类的合适方法。在C#中,函数默认情况下不是虚的,但(除了构造函数)可以显式的声明为virtual。
  在派生类中重写一个函数时,要使用override关键字显示声明:
  class MyDreved: BaseClass
  {
    public override void VirtualMethod()
    {
      //
    }
  }

  成员字段和静态函数都不能声明为virtual,因为这个概念只对类中的实例函数成员有意义。

  2.隐藏方法
  如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有分别声明为virtual和override,派生类方法就会隐藏基类方法。

复制代码
class A 
{public void a(){Console.WriteLine('CLASS is A');} 
}class B:A
{public void a(){Console.WriteLine('CLASS is B');}
}class client 
{static void main(){B b=new B();A a=b;a.a();b.a();}
}/*输出
CLASS IS A
CLASS IS B
*/
复制代码

 

  在大多数情况下,是要重写方法,而不是隐藏方法,因为隐藏方法会造成对于给定类的实例调用错误的方法。但是,C#语法会在编译时收到这个潜在错误的警告。

  在C#中,要隐藏一个方法应使用new 关键字声明,这样在编译时就不会发出警告:
  class A 
  {
    public void a()
    {
      Console.WriteLine('CLASS is A');
    } 
  }

  class B:A
  {
    public new void a()
    {
       Console.WriteLine('CLASS is B');
    }
  }

  3.调用函数的基类版本
  C#可以从派生类中调用方法的基本版本:base.<MethodName>()
  class MyDreved: BaseClass
  {
    public override void VirtualMethod()
    {
      base.VirtualMethod();
    }
  }
  可以使用base.<MethodName>()语法调用基类中的任何方法,不必从同一方法的重载中调用它。

  4.抽象类和抽象函数
  C#允许把类和函数声明为abstract.抽象类不能实例化,而抽象不能直接实现,必须在非抽象的派生类中重写。显然抽象函数也是虚拟的(尽管不需要提供virtual,实际上,也不能提供该关键字)。
  如果类包含抽象函数,则该类也是抽象的,也必须声明为抽象的:
  abstract class Building
  {
    public abstract void Cal();
  }

  抽象类中不能声明非抽象方法,但可以声明其它的非抽象成员。

  5.密封类和密封方法
  C#允许把类和方法声明为sealed。对于类,这表示不能继承该类;对于方法,表示不能重写该方法。
  sealed class A 
  {

  }

  class B:A //报错
  {

  }

  如果基类上不希望有重写的方法和属性,就不要把它声明为virtual.

  6.派生类的构造函数
  假定没有为任何类定义任何显示的构造函数,编译器就会为所有的类提供默认的初始化构造函数,在后台编译器可以很好的解决类的层次结构中的问题,每个类中的每个字段都会初始化为对应的默认值。
  在创建派生类的实例时,实际上会有多个构造函数起作用。要实例化的类的构造函数本身不能初始化类,还必须调用基类中的构造函数。
  构造函数的调用顺序是先调用Object,在按照层次结构调用基类的构造函数,由基类到父类,直到到达要实例化的类为止。在这个过程中,每个构造函数都初始化它自己的类中的字段。因为最先调用的总是基类的构造函数,所以派生类在执行过程中可以访问任何基类的成员,因为基类已经构造出来了,其字段也初始化了。

  *在层次结构中添加无参数的构造函数
    在层次结构中添加一个无参数的构造函数会替换默认的构造函数,所以在执行过程中,会默认调用基类中添加的无参数的构造函数。其它方面不变。
  *在层次结构中添加带参数的构造函数
  在层次结构中要调用这个带参数的构造函数,需要在父类的构造函数中显示调用:

复制代码
public abstract class GenericCustomer
{private string name;public GenericCustomer(){name = "<no name>";}public GenericCustomer(string name){this.name = name;}public string Name { get {return name;}set {name = value;}}}public class Nevermore60Customer : GenericCustomer
{private string referrerName;private uint highCostMinutesUsed;ublic Nevermore60Customer(string name) : this(name, "            <None>"){}public Nevermore60Customer(string name, string referrerName) : base(name){this.referrerName = referrerName;}public string ReferrerName{get {return referrerName;}set {referrerName = value;}}}    
复制代码

 

 

 

三. 修饰符
  修饰符可以指定方法的可见性:如public或private,还可以指定一项的本质,如方法是virtual或abstract.
  1.可见性修饰符
  修饰符            应用于                    说明
  public              所有类和成员                任何代码可以访问
  protected           类的成员和内嵌类              只有在类内部和派生类中访问
  internal           所有类和成员                只有在类内部和包含它的程序集中访问
  private          类的成员和内嵌类              只有在类内部访问
  protected internal    类的成员和内嵌类              只有在类内部,派生类中和包含它的程序集中访问

  不能把类定义为protected,private,protected internal,因为这些修饰符对于包含在名称空间中的类型没有意义。因此这些修饰符只能应用于成员。但是可以用这些修饰符定义嵌套的类(内嵌类,包含在其它类中的类),因为在这种情况下,类也具有成员的状态:
  public class OuterClass
  {
    protected class InnerClass
    {

    }
  }

  2.其它修饰符
  修饰符      应用于       说明
  new        函数        隐藏函数
  static      所有成员      静态
  virtual     函数         成员可以由派生类重写
  abstract      类,函数      抽象
  override      函数          重写虚拟和抽象的成员
  sealed      类,方法,属性       不能继承和重写
  extern        仅静态方法     成员在外部用另一种语言实现

四.接口
  public interface IDisposable
  {
    void Dispose();
  }

  声明接口在语法上和声明抽象类完全相同,但不允许提供任何成员的实现方式。抽象类可以提供除方法之外的其它成员的实现方式,比如属性。
  一般情况下,接口只能包含方法,属性,索引器和事件的声明。
  不能实例化接口,接口即不能有构造函数,也不能有字段。接口定义也不允许包含运算符重载。
  在接口中不允许声明关于成员的修饰符。接口成员总是公有的,不能声明为虚拟和静态。如果需要,在实现的类中声明。

  实现接口的类必须实现接口的所有成员。
  接口可以彼此继承,其方式与类的继承方式相同。

转载于:https://www.cnblogs.com/zhangxin4477/p/6731475.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429393.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 学习计划_Java学习计划范例

Java学习计划范例Java学习计划好的计划是成功的一半&#xff0c;今天是在创新思维的第一节课&#xff0c;在这门课程的开始&#xff0c;一个有策略的、有目的性的计划是非常必要的&#xff0c;为了在以后的学习中能够达到最好的.效果&#xff0c;"坚持"是一把雕刻刀&…

SQL Server 2012自动备份

SQL 2012和2008一样&#xff0c;都可以做维护计划&#xff0c;来对数据库进行自动的备份。 现在做这样一个数据库维护的计划&#xff0c;每天0点对数据库进行差异备份&#xff0c;每周日0点对数据库进行完全备份&#xff0c;并且每天晚上10点删除一次过期备份&#xff08;两个星…

mysql查逻辑表的分片规则_MySQL(19) Mycat分片(分库分表)配置

一、前言本文将基于主从复制&#xff0c;读写分离的环境基础上进行一个简单的分片(分库分表)配置二、Mycat分片配置mycat分片主要在scheam.xml&#xff0c;rule.xml这2个表中配置① scheam.xml&#xff1a;配置逻辑表以及对应使用的分片规则select user()这里小编主要对t_user表…

JS取消浏览器文本选中的方法

一 、问题的出现 今天在使用Easy-UI 的messager.alert()方法时候出现浏览器文本被选中&#xff0c;不知道其中是什么原因&#xff0c;如下图所示。 二 、解决思路 我最后的思路时在弹出消息框的同时&#xff0c;取消浏览器文本的选择&#xff0c;最后查找资料编写如下方法。  …

java 重构 if else_项目中的if else太多了,该怎么重构?

前言if else过多的话&#xff0c;一般都是用策略模式来进行重构&#xff0c;策略模式也非常的简单。先定义一个接口&#xff0c;各种处理分支实现这个接口&#xff0c;定义好 条件->处理类的映射关系&#xff0c;然后根据条件找到响应的处理类执行即可&#xff0c;当有新的分…

读书笔记:秘密

2017年立下了读30本书的旗子&#xff0c;现在这是第3本&#xff0c;是一本小说&#xff0c;东野圭吾的小说《秘密》。看小说也可以看出生活&#xff0c;但是是为了娱乐&#xff0c;是为了放松&#xff0c;小说本身挺好看的&#xff5e;引人入胜&#xff0c;一看到底类型。读书前…

mysql的student是什么意思_复习mysql

一、复习详尽如下&#xff1a;创建一个test库create database test;授权一个用户grant all privileges on *.* to xiang% identified by 1qazWSX;创建表create table student(id int not null);查询select * from tabel_name where 条件1 and 条件2增加insert into table_name …

算法复杂度的理解

算法复杂度的理解 from:http://blog.sina.com.cn/s/blog_4bab8e7f0102vmth.html算法复杂度分为时间复杂度和空间复杂度。 时间复杂度的计算 ​1.一个算法执行所耗费的时间&#xff0c;从理论上是不能算出来的&#xff0c;必须上机运行测试才能知道。但我们不可能也没有必要对每…

php如何将mysql数据库中的admin字段赋值给session_php实现将Session写入数据库

/**author Fahy*数据库为mysql&#xff0c;*数据库名为session&#xff0c;表名为session&#xff0c;*表中字段包括PHPSESSID,update_time,client_ip,data*/class Session{private static $handler null;private static $ip null;private static $lifetime null;private st…

linux 脚本 java_Linux 通过脚本执行Java程序

由于要统计不同的IP&#xff0c;代码中应用了HashSet来存放IP地址。上述Java程序是在Windows下编写的&#xff0c;如果在Linux服务器上运行&#xff0c;只需要把上面文件的路径和文件更换了就可以了。2.编写好java程序后&#xff0c;将java程序打成jar文件(环境Linux)我将上述测…

Java开启/关闭tomcat服务器

© 版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请注明出处 通过java代码实现Tomcat的开启与关闭 1.项目结构 2.CallTomcat.java package com.calltomcat.test;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;…

python命令行调试django代码_Django shell调试models输出的SQL语句方法

在settings.py里&#xff0c;配置如下logging&#xff1a;LOGGING {version: 1,disable_existing_loggers: False,handlers: {console:{level:DEBUG,class:logging.StreamHandler,},},loggers: {django.db.backends: {handlers: [console],propagate: True,level:DEBUG,},}}使…

5、如何快速找到多个字典中的公共键(key) 6 如何让字典保持有序 7 如何实现用户的历史记录功能(最多n条)...

5、如何快速找到多个字典中的公共键(key) from random import randint,sample #随机取数 # a sample("ABCDEF",randint(5,6)) # print(a) # b1 {x:randint(1,4) for x in sample("ABCDEF",randint(3,6))} # b2 {x:randint(1,4) for x in sample("A…

Bresenham画椭圆算法

这里不仔细讲原理&#xff0c;只是把我写的算法发出来&#xff0c;跟大家分享下&#xff0c;如果有错误的话&#xff0c;还请大家告诉我&#xff0c;如果写的不好&#xff0c;也请指出来&#xff0c;一起讨论进步。 算法步骤: (1) 输入椭圆的长半轴a和短半轴b。 (2) 计算初始值…

iOS MD5 (消息摘要算法5)

一、MD5定义 MD5即Message-Digest Algorithm 5&#xff08;消息-摘要算法5&#xff09;&#xff0c;为计算机安全领域广泛使用的一种散列函数&#xff0c;用以提供消息的完整性保护&#xff08;又译摘要算法、哈希算法&#xff09;&#xff0c;主流编程语言普遍已有MD5实现。…

“每日一道面试题”.Net中所有类的基类是以及包含的方法

闲来无事&#xff0c;每日一贴。水平有限&#xff0c;大牛勿喷。 .Net中所有内建类型的基类是System.Object毋庸置疑 Puclic Class A{}和 Public Class A&#xff1a;System.Object{}是等效的 System.Object包含了Finalize在内的8个方法。 公共实例方法&#xff1a; Virtual b…

JAVA怎么将整数反转_【leetcode刷题】[简单]7.反转整数(reverse integer)-java

反转整数 reverse integer题目给定一个 32 位有符号整数&#xff0c;将整数中的数字进行反转。示例 1:输入: 123输出: 321示例 2:输入: -123输出: -321示例 3:输入: 120输出: 21注意:假设我们的环境只能存储 32 位有符号整数&#xff0c;其数值范围是 [− 2^31, 2^31 − 1]。根…

Linux实战案例(2)实例讲解使用软连接的场景和过程

使用场景&#xff1a;使用软连接简化版本切换动作 进入操作目录&#xff0c; cd /opt/modules/ 1、创建软连接ln -s jdk1.8.0_131 jdk1.8ln -s spark-2.1.0-bin-hadoop2.7 sparkln -s hadoop-2.7.3 hadoop 2、删除软连接rm -rf hadooprm -rf sparkrm -rf jdk1.8 3、验证结果 …

java单车吧_暑假一个月,撸个共享单车后台

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼加解密差不多了&#xff0c;下一步开始写登录了。//先对称加密 key 和数据String key "j783420jfjyqalgr";String data "周"; // FBI通缉人 周String encrypt AESUtil.encrypt(data, key); // 向服务器传输…

KVM虚拟化技术之使用Qemu-kvm创建和管理虚拟机

一 .KVM 简介 KVM &#xff08;名称来自英语&#xff1a; Kernel-basedVirtual Machine 的缩写&#xff0c;即基于内核的虚拟机&#xff09; &#xff0c; 是一种用于Linux内核中的虚拟化基础设施&#xff0c;可以将Linux内核转化为一个hypervisor。KVM在2007年2月被导入Li…