C#学习笔记(二):继承、接口和抽象类
继承
密封类
密封类(关键字sealed)是不允许其它类继承的,类似Java中的final关键字。
public sealed class SealedClassName
{
//...
}
初始化顺序
子类初始化顺序如下:
- 初始化类的实例字段;
- 调用基类的构造函数;
- 调用子类的构造函数。
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#中接口规则:
- 定义的方法不需要添加public等限定符,默认的所有方法都是public的;
- 可以包含方法、属性、事件和索引器;
- 不可以包含字段、运算符重载、构造函数和析构函数;
- 也不可以包含静态相关的所有定义;
类实现接口
实现接口的写法与继承一致:
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: ,
显示接口总结:
- 显示接口一般用于多个接口实现时,存在同名方法但需要不同的处理时。
- 我们发现如果使用显示的接口,需要将对象转换为对应的接口对象才能调用到对应的接口方法。
- 显示实现接口时不能写public在前方。
- 显示实现的接口不能由类直接访问,必须转换为对应的接口对象才行。
抽象类
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: ,
抽象类总结:
- 抽象类也是类,所以不能多重继承;
- 抽象类不能实例化,可以包含抽象方法,抽象方法不能实现;
- 抽象方法为虚方法;
- 非抽象子类必须实现抽象方法;
C#学习笔记(二):继承、接口和抽象类的更多相关文章
- Java学习笔记之---比较接口与抽象类
Java学习笔记之---比较接口与抽象类 抽象类是描述事物的本质,接口是描述事物的功能 接口与抽象类的异同 1.一个类只能继承一个父类,但是可以有多个接口 2.抽象类中的抽象方法没有方法体,但是可以有 ...
- java基础学习笔记二(接口、super、this)
一.super 和 this的用法 主要解释一下引用构造函数的用法 super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句) this(参数):调用本类中另一种形式的构造函数(应 ...
- 【知了堂学习笔记】java 接口与抽象类
本次主角:抽象类 .接口. 对于皮皮潇这样一类的Java初学者来说,接口和抽象类如果不去花大量的精力与时间是很难弄清楚的,而我也是在最近这周的项目学习中感觉到了我对这两个概念不熟悉,所以导致对一些问题 ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 接口(抽象类)
接口描述了类的行为和功能,而不需要完成类的特定实现. C++ 接口是使用抽象类来实现的,抽象类与数据抽象互不混淆,数据抽象是一个把实现细节与相关的数据分离开的概念. 如果类中至少有一个函数被声明为纯虚 ...
- PHP学习笔记二十八【抽象类】
<?php //定义一个抽象类.主要用来被继承 //如果一个类继承了抽象类,则它必须实现该抽象类的所有抽象方法(除非它自己也是抽象类) // abstract class Animal{ pub ...
- mybatis学习笔记二(接口注解)
直接上代码,全部在代码里讲解. 1.实体类 package com.home.entity; /** * 此类是:user实体类 * @author hpc * @2017年1月10日下午9:36:5 ...
- Java学习笔记二十八:Java中的接口
Java中的接口 一:Java的接口: 接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明.一个类通过继承接口的方式,从而来继承 ...
- Typescript 学习笔记六:接口
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- 学习笔记(二)--->《Java 8编程官方参考教程(第9版).pdf》:第七章到九章学习笔记
注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.若有违本之,则本人不负法律责任.违法者自负一切 ...
- JMX学习笔记(二)-Notification
Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...
随机推荐
- 通过org.springframework.web.filter.CharacterEncodingFilter定义Spring web请求的编码
通过类org.springframework.web.filter.CharacterEncodingFilter,定义request和response的编码.具体做法是,在web.xml中定义一个F ...
- MVC的项目使用html编辑器UEditorMINI
一个MVC的项目中有个发布新闻的页面需要用到一个html的编辑器,网上看到UEditor评价貌似还不错, 因为我用到的功能比较简单,就下载了MINI版本的, 使用的过程在这里总结一下. 关于UEdit ...
- [反汇编练习] 160个CrackMe之019
[反汇编练习] 160个CrackMe之018. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...
- Java Socket(1): 入门
前言:在最近一个即将结束的项目中使用到了Socket编程,用于调用另一系统进行处理并返回数据.故把Socket的基础知识总结梳理一遍. 一.TCP/IP协议 既然是网络编程,涉及几个系统之间的交互,那 ...
- Java泛型的好处
java 泛型是java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. ...
- Mysql 的存储过程和存储函数
优点: v 提高安全性 v 简化mysql查询 v 减轻带宽负担 缺点: v 增加服务器负担 v 对我们开发者来说,难度大一点 PHP中的函数 Function funname(参数){ //函数体 ...
- Eclipse “Invalid Project Description” when creating new project from existing source
1) File>Import>General>Existing Project into Workspace2) File>Import>Android>Exist ...
- hadoop中日志聚集问题
遇到的问题: 当点击上面的logs时,会出现下面问题: 这个解决方案为: By default, Hadoop stores the logs of each container in the nod ...
- http://jingyan.baidu.com/article/4dc40848e7b69bc8d946f127.html
http://jingyan.baidu.com/article/4dc40848e7b69bc8d946f127.html
- switchomega配置