欢迎来到 IT实训基地-南通科迅教育
咨询电话:0513-81107100
C#中的继承与多态还有接口
2017/2/27
科迅教育
364
南通网页设计培训怎么挑选-基础教学

简单继承

最简单的三个类

 

?
1
2
3
4
5
6
publicclassAnimal {
    publicAnimal()
    {
        Debug.Log("Construct Animal!");
    }
}

?
1
2
3
4
5
6
publicclassMammal : Animal {
    publicMammal()
    {
        Debug.Log("Construct Mamal!");
    }
}

?
1
2
3
4
5
6
7
publicclassSheep : Mammal
{
    publicSheep()
    {
        Debug.Log("Construct Sheep!");
    }
}

在main里面

 

 

?
1
Sheep sheep =newSheep();

\

 

 

子类的构造函数会依次执行基类的构造函数,没有异议。

 

需要注意的是,没有特别声明,子类都会自动去找父类中没有参数的构造函数,如果基类中没有,则需要在子类的构造函数中调用,比如:

 

?
1
2
3
4
5
6
7
8
9
publicclassAnimal{
 
    intage;
    publicAnimal(int_age)
    {
        age = _age;
        Debug.Log("Construct Animal!");
    }
}

则子类的构造函数就要这样写

 

 

?
1
2
3
4
publicMammal():base(0)
{
    Debug.Log("Construct Mamal!");
}

 

 

在基类Animal中添加函数

 

?
1
2
3
4
publicvoidEat()
{
    Debug.Log("Animal Eat!");
}

 

下面谈一下方法的覆盖

在子类Sheep中覆盖定义Eat方法

 

?
1
2
3
4
publicnewvoidEat()
{
    Debug.Log("Sheep Eat!");
}

这里的new关键字表示隐藏基类中的方法,官方解释如下:

 

new 关键字可以显式隐藏从基类继承的成员。隐藏继承的成员时,该成员的派生版本将替换基类版本。虽然可以不使用 new 修饰符来隐藏成员,但将收到编译器警告。如果使用 new 来显式隐藏成员,将禁止此警告。

测试代码:

 

?
1
2
3
4
5
Sheep sheep =newSheep();
Animal animal =newSheep();
 
sheep.Eat();
animal.Eat();

结果是这样的

 

\

 

没有发生多态行为,声明的基类对象,执行的就是基类方法,声明的子类对象,执行的就是子类方法。

在子类的函数中,都有一个base变量,可以认为是一个对基类的引用,通过base就可以调用基类的方法。

 

多态

多态就是多态就是父类引用指向子类对象,调用方法时会调用子类的实现,而不是父类的实现,这叫多态。

基类Animal中定义函数

 

?
1
2
3
4
publicvirtualvoidBirth()
{
    Debug.Log("Animal Birth!");
}

 

Sheep中overrride一下

 

?
1
2
3
4
publicoverridevoidBirth()
{
    Debug.Log("Sheep Birth!");
}

测试代码

 

 

?
1
2
3
Sheep sheep =newSheep();
Animal animal =newSheep();
animal.Birth();

执行结果

 

\

 

有下面两个需要注意的点

1.子类调用父类的方法

当然是直接用base了。

2.继承链中的虚方法

无论在虚拟成员和最初声明虚拟成员的类之间已声明了多少个类,虚拟成员永远都是虚拟的。如果类 A 声明了一个虚拟成员,类 B 从 A 派生,类 C 从类 B 派生,则类 C 继承该虚拟成员,并且可以选择重写它,而不管类 B 是否为该成员声明了重写。

 

Sealed关键字的用法

Sealed关键字用来阻止派生类重写虚拟成员。还是举例说明。

基类Animal中定义方法

 

?
1
2
3
4
publicvirtualvoidMove()
{
    Debug.Log("Animal Move!");
}

Mammal中sealed override这个函数

 

 

?
1
2
3
4
publicsealed overridevoidMove()
{
    Debug.Log("Mammal Move!");
}

这时候在Sheep中已经无法overide这个函数了,因为在Sheep看来,基类的Move是被当作一个普通函数来处理的,如果要定义自己的Move函数,就要加new,像这样

 

 

?
1
2
3
4
publicnewvoidMove()
{
    Debug.Log("Sheep Move!");
}

 

写点代码来测试多态性

 

?
1
2
3
4
5
6
7
8
9
Animal animal =newAnimal(1);
Animal animal1 =newMammal(1);
Animal animal2 =newSheep();
Sheep sheep =newSheep();
 
animal.Move();
animal1.Move();
animal2.Move();
sheep.Move();

运行结果

 

\

 

第一个无话可说,直接执行了Animal的move函数

第二个,正常的多态

第三个有点意思,多态到Mammal就打住了

第四个就是普通的执行Sheep类的成员函数。

 

abstract关键字的使用

官方解释:abstract 修饰符指示所修饰的内容缺少实现或未完全实现。abstract 修饰符可用于类、方法、属性、索引器和事件。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。

接地气的解释:abstract类用于搭建子类的框架,子类必须实现其中的abstract方法,使用的也是override关键字。

abstract方法和vitual方法的区别

abstract方法没有函数体,子类一定要有对应方法的实现。

vitual方法子类可以选择实现也可以选择不实现。

两个都可以用于实现多态。

 

抽象类不能实例化。抽象类的用途是提供一个可供多个派生类共享的通用基类定义。例如,类库可以定义一个抽象类,将其用作多个类库函数的参数,并要求使用该库的程序员通过创建派生类来提供自己的类实现。

 

接口

接口包含类或结构可以实现的一组相关功能的定义。
例如,使用接口可以在类中包括来自多个源的行为。 由于C#语言不支持多重继承,所以该功能很重要。 此外,如果要模拟结构的继承,也必须使用接口,因为它们无法实际从另一个结构或类继承。

 

定义一个简单的接口,只有接口函数的定义,没有实现。

 

?
1
2
3
4
5
publicinterfaceISay {
 
    voidSayHello();
    voidSayFuck();
}

 

 

Sheep继承ISay接口
?
1
publicclassSheep : Mammal, ISay

则Sheep类中必须要有ISay中定义的接口的定义

 

?
1
2
3
4
5
6
7
8
9
publicvoidSayHello()
{
    Debug.Log("ISay Hello");
}
 
publicvoidSayFuck()
{
    Debug.Log("ISay SayFuck");
}

测试代码

 

 

?
1
2
3
Sheep sheep =newSheep();
sheep.SayHello();
sheep.SayFuck();

执行结果

 

\

 

接口有下面几个属性

接口类似于抽象基类。实现接口的任何类或结构都必须实现其所有成员。
接口无法直接进行实例化。其成员由实现接口的任何类或结构来实现。
接口可以包含事件、索引器、方法和属性。
接口不包含方法的实现。
一个类或结构可以实现多个接口。一个类可以继承一个基类,还可实现一个或多个接口。

77
关闭
先学习,后交费申请表
每期5位名额
在线咨询
免费电话
QQ联系
先学习,后交费
TOP
您好,您想咨询哪门课程呢?
关于我们
机构简介
官方资讯
地理位置
联系我们
0513-91107100
周一至周六     8:30-21:00
微信扫我送教程
手机端访问
南通科迅教育信息咨询有限公司     苏ICP备15009282号     联系地址:江苏省南通市人民中路23-6号新亚大厦三楼             法律顾问:江苏瑞慈律师事务所     Copyright 2008-