继承

密封类

密封类(关键字sealed)是不允许其它类继承的,类似Java中的final关键字。

 public sealed class SealedClassName
{
//...
}

初始化顺序

子类初始化顺序如下:

  1. 初始化类的实例字段;
  2. 调用基类的构造函数;
  3. 调用子类的构造函数。
 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
new C(); Console.ReadKey();
}
} public class A
{
public A()
{
Console.WriteLine("A 类构造函数被调用。");
}
} public class B : A
{
public B()
{
Console.WriteLine("B 类构造函数被调用。");
}
} public class C : B
{
public C()
{
Console.WriteLine("C 类构造函数被调用。");
}
}
}

结果如下:

 A 类构造函数被调用。
B 类构造函数被调用。
C 类构造函数被调用。

带参数的构造函数

Java中使用super调用父类的构造函数,而C#中则使用base,同时写法也稍微有点不同,如下:

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
new C(); Console.ReadKey();
}
} public class A
{
public A(int a, int b)
{
Console.WriteLine("A 类构造函数被调用。");
Console.WriteLine(a + ":" + b);
}
} public class B : A
{
public B(int name1, int name2) : base(name1, name2)
{
Console.WriteLine("B 类构造函数被调用。");
}
} public class C : B
{
public C() : base(, )
{
Console.WriteLine("C 类构造函数被调用。");
}
}
}

输出如下:

 A 类构造函数被调用。
:
B 类构造函数被调用。
C 类构造函数被调用。

方法多态

子类重写父类的方法使用virtual和override实现。

 1 using System;
2
3 namespace Study
4 {
5 class Program
6 {
7 static void Main(string[] args)
8 {
9 new C().func();
10
11 Console.ReadKey();
12 }
13 }
14
15 public class A
16 {
17 public virtual void func()
18 {
19 Console.WriteLine("A 类的 func 方法调用。");
20 }
21 }
22
23 public class B : A
24 {
25 public override void func()
26 {
27 Console.WriteLine("B 类的 func 方法调用。");
28 }
29 }
30
31 public class C : B
32 {
33 public override void func()
34 {
35 base.func();
36 Console.WriteLine("C 类的 func 方法调用。");
37 }
38 }
39 }

输出如下:

 B 类的 func 方法调用。
C 类的 func 方法调用。

阻止重写方法

如果不希望虚方法被重写,可以使用sealed关键字。

1 public sealed override void func()
2 {
3 //...
4 }

新成员方法隐藏老成员方法

使用new关键字可以隐藏非虚的老成员方法。

 1 using System;
2
3 namespace Study
4 {
5 class Program
6 {
7 static void Main(string[] args)
8 {
9 C c = new C();
10 c.func();
11 ((B)c).func();
12 ((A)c).func();
13
14 Console.ReadKey();
15 }
16 }
17
18 public class A
19 {
20 public void func()
21 {
22 Console.WriteLine("A 类的 func 方法调用。");
23 }
24 }
25
26 public class B : A
27 {
28 public new void func()
29 {
30 Console.WriteLine("B 类的 func 方法调用。");
31 }
32 }
33
34 public class C : B
35 {
36 public new void func()
37 {
38 Console.WriteLine("C 类的 func 方法调用。");
39 }
40 }
41 }

输出如下:

 C 类的 func 方法调用。
B 类的 func 方法调用。
A 类的 func 方法调用。

接口

C#中不允许多重继承,但接口可以多重继承。

接口声明

声明一个接口的写法如下:

 public interface ICustom
{
}

C#中接口规则:

  1. 定义的方法不需要添加public等限定符,默认的所有方法都是public的;
  2. 可以包含方法、属性、事件和索引器;
  3. 不可以包含字段、运算符重载、构造函数和析构函数;
  4. 也不可以包含静态相关的所有定义;

类实现接口

实现接口的写法与继承一致:

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
ICustom custom = new Custom();
custom.name = "A";
custom.MoveTo(, ); Console.ReadKey();
}
} public interface ICustom
{
string name { set; get; } void MoveTo(float x, float y);
} public class Custom : ICustom
{
public string name { get; set; } public void MoveTo(float x, float y)
{
Console.WriteLine("Custom \"" + name + "\" move to: " + x + ", " + y);
}
}
}

输出如下:

Custom "A" move to: , 

接口的隐式实现和显式实现

如果在实现接口时没有指明该方法是属于哪个接口的话,称为隐式实现,如上面的例子。如果指明了方法是来自哪个接口则称为显式实现。

C#中的隐式实现与Java和AS3的使用一致,就不多讲,下面主要说一下接口的显式实现。

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
Custom custom = new Custom();
custom.name = "A";
(custom as ICustomA).MoveTo(, );
(custom as ICustomB).MoveTo(, ); Console.ReadKey();
}
} public interface ICustomA
{
string name { set; get; } void MoveTo(float x, float y);
} public interface ICustomB
{
string name { set; get; } void MoveTo(float x, float y);
} public class Custom : ICustomA, ICustomB
{
public string name { get; set; } void ICustomA.MoveTo(float x, float y)
{
Console.WriteLine("ICustomA \"" + name + "\" move to: " + x + ", " + y);
} void ICustomB.MoveTo(float x, float y)
{
Console.WriteLine("ICustomB \"" + name + "\" move to: " + x + ", " + y);
}
}
}

运行结果如下:

 ICustomA "A" move to: ,
ICustomB "A" move to: ,

显示接口总结:

  1. 显示接口一般用于多个接口实现时,存在同名方法但需要不同的处理时。
  2. 我们发现如果使用显示的接口,需要将对象转换为对应的接口对象才能调用到对应的接口方法。
  3. 显示实现接口时不能写public在前方。
  4. 显示实现的接口不能由类直接访问,必须转换为对应的接口对象才行。

抽象类

C#中,抽象类使用与Java中一致,我们写一个例子来验证即可。

 using System;

 namespace Study
{
class Program
{
static void Main(string[] args)
{
Custom custom = new Custom();
custom.name = "A";
custom.MoveTo(, ); Console.ReadKey();
}
} public abstract class AbstractCustom
{
public string name { set; get; } public abstract void MoveTo(float x, float y);
} public class Custom : AbstractCustom
{
public override void MoveTo(float x, float y)
{
Console.WriteLine("Custom \"" + name + "\" move to: " + x + ", " + y);
}
}
}

运行结果如下:

Custom "A" move to: , 

抽象类总结:

  1. 抽象类也是类,所以不能多重继承;
  2. 抽象类不能实例化,可以包含抽象方法,抽象方法不能实现;
  3. 抽象方法为虚方法;
  4. 非抽象子类必须实现抽象方法;

C#学习笔记(二):继承、接口和抽象类的更多相关文章

  1. Java学习笔记之---比较接口与抽象类

    Java学习笔记之---比较接口与抽象类 抽象类是描述事物的本质,接口是描述事物的功能 接口与抽象类的异同 1.一个类只能继承一个父类,但是可以有多个接口 2.抽象类中的抽象方法没有方法体,但是可以有 ...

  2. java基础学习笔记二(接口、super、this)

    一.super 和 this的用法 主要解释一下引用构造函数的用法 super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句) this(参数):调用本类中另一种形式的构造函数(应 ...

  3. 【知了堂学习笔记】java 接口与抽象类

    本次主角:抽象类 .接口. 对于皮皮潇这样一类的Java初学者来说,接口和抽象类如果不去花大量的精力与时间是很难弄清楚的,而我也是在最近这周的项目学习中感觉到了我对这两个概念不熟悉,所以导致对一些问题 ...

  4. 吴裕雄--天生自然C++语言学习笔记:C++ 接口(抽象类)

    接口描述了类的行为和功能,而不需要完成类的特定实现. C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念. 如果类中至少有一个函数被声明为纯虚 ...

  5. PHP学习笔记二十八【抽象类】

    <?php //定义一个抽象类.主要用来被继承 //如果一个类继承了抽象类,则它必须实现该抽象类的所有抽象方法(除非它自己也是抽象类) // abstract class Animal{ pub ...

  6. mybatis学习笔记二(接口注解)

    直接上代码,全部在代码里讲解. 1.实体类 package com.home.entity; /** * 此类是:user实体类 * @author hpc * @2017年1月10日下午9:36:5 ...

  7. Java学习笔记二十八:Java中的接口

    Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...

  8. Typescript 学习笔记六:接口

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  9. 学习笔记(二)--->《Java 8编程官方参考教程(第9版).pdf》:第七章到九章学习笔记

    注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法者自负一切 ...

  10. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

随机推荐

  1. int和integer;Math.round(11.5)和Math.round(-11.5)

    int是java提供的8种原始数据类型之一.Java为每个原始类型提供了封装类,Integer是java为int提供的封装类.int的默认值为0,而Integer的默认值为null,即Integer可 ...

  2. [转]ASP.NET数据库连接字符串总结

    这个不难,而且很重要,但总忘,找了篇比较全的,作为资料. 原文链接http://developer.51cto.com/art/201107/275406.htm 关于数据库链接字符串的相关知识,我们 ...

  3. UVA 10765 Doves and bombs(双连通分量)

    题意:在一个无向连通图上,求任意删除一个点,余下连通块的个数. 对于一个非割顶的点,删除之后,原图仍连通,即余下连通块个数为1:对于割顶,余下连通块个数>=2. 由于是用dfs查找双连通分量,树 ...

  4. Java [Leetcode 260]Single Number III

    题目描述: Given an array of numbers nums, in which exactly two elements appear only once and all the oth ...

  5. 【转】使用 Auto Layout 的典型痛点和技巧

    layoutIfNeeded()强制立刻更新布局 原文网址:http://www.jianshu.com/p/0f031606e5f2 官方文档:Auto Layout Guide 加上去年WWDC上 ...

  6. Spring各jar包的作用(转载)

    spring.jar是包含有完整发布的单个jar 包,spring.jar中包含除了spring-mock.jar里所包含的内容外其它所有jar包的内容,因为只有在开发环境下才会用到 spring-m ...

  7. oracle 统计语句 与常见函数的归纳(未完待续)

    一.统计语句 1. count count(*)与count(0)语句的区别: count(*)统计所有数量 count(0)统计第一列不为空的 2. 两个统计量的减法 select (select ...

  8. ylbtech-Model-Account(通用账户模块设计)

    ylbtech-DatabaseDesgin:ylbtech-Model-Account(通用账户模块设计) ylbtech-Model-Account(通用账户模块设计) 1.A,数据库关系图(Da ...

  9. hdu 2594-Simpsons’ Hidden Talents(KMP)

    题意: 给你两个串a,b,求既是a的前缀又是b的后缀的最长子串的长度. 分析: 很自然的想到把两个串连接起来,根据KMP的性质求即可 #include <map> #include < ...

  10. const 常量数据,只读

    网上其他的博客地址:1 http://www.cnblogs.com/ronny/p/3672501.html 2 http://www.cnblogs.com/hellogiser/p/cplusp ...