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这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...
随机推荐
- jquery live hover绑定方法
$(".select_item span").live({ mouseenter: function() { $(this).addClass("hover") ...
- UIView 设置alpha后, 子view也随着变化alpha, 解决方法
// _closeContainerBar.alpha = 0.7; _closeContainerBar.backgroundColor = [[UIColor blackColor] ...
- uestc 1725 吴神数
// 筛选法// 先求出 sqrt(1<<31)内的素数// 然后筛选出符合要求的数// 详情见代码注释// #pragma comment(linker, "/STACK:10 ...
- Oracle AWR报告自动生成并ftp脚本
脚本主要由以下几个部分组成: awr.sql 用来在sqlplus 中执行的脚本,该脚本从网上直接找的. awr.sh 用来调用sqlplus来生成awr报告. ftp.sh 用来打包压缩每天生成的a ...
- 【大数阶乘】NYOJ-28
大数阶乘 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 我们都知道如何计算一个数的阶乘,可是,如果这个数很大呢,我们该如何去计算它并输出它? 输入 输入一个整数 ...
- 【大数加法】POJ-1503、NYOJ-103
1503:Integer Inquiry 总时间限制: 1000ms 内存限制: 65536kB 描述 One of the first users of BIT's new supercompu ...
- 【LeetCode 169】Majority Element
Given an array of size n, find the majority element. The majority element is the element that appear ...
- 学习笔记——XSLT转换器的使用(Xalan和Saxon) .(转)
转自:http://blog.csdn.net/crystalbruce/article/details/7401602 XSLT分为两类: 1:客户端转换:需要浏览器的支持. 2:服务器转换:需要使 ...
- ASP.net MVC基础
简单了解了下MVC的基本开发步骤后,又对MVC的语法和模版详细看看了,小小总结下 对mvc开发,首先是要对布局有个基本的认识.Razor引擎使页面元素更加清晰 简单认识下 可以加载css和js等文件, ...
- container_of
在学习Linux驱动的过程中,遇到一个宏叫做container_of.该宏定义在include/linux/kernel.h中,首先来贴出它的代码: /** * container_of - cast ...