> 用父类的对象来调用子类的方法
> 对继承来说,是在子类中定义方法,调用父类中的属性。
多态:在父类中定义方法,然后在子类中创建对象来调用。
比如父类中有:
属性:体重
行为:叫
子类中有猫、狗、羊。
那么在父类中创建对象时,就可以调用猫、狗、羊这三个子类来实现“叫”这个行为。
> 也就是:以父类的身份出现,但以子类的方式工作。
# 虚方法
多态使得派生类(子类)的实例可以直接赋值基类的对象,然后直接通过这个对象调用派生类的方法。
c#中类的多态性是通过在派生类(子类)中写**基类**的虚方法来实现。
也就是:
```
子类(实例)=> (虚方法)= > 父类(对象)=> 子类方法
```
在父类中用`virtual`来写需方法,在子类中用`override`来重写虚方法。
```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 多态
{
class Vehicle //定义父类名叫Vehicl
{
public string Name { get; set; } //定义属性。但其实如果不定义为属性,也是可以的,也可以直接定义为变量:public string Name; 也是可以的
public virtual void Move() // 用virtual来表示虚方法
{
Console.WriteLine("{0}可以移动", Name);
}
}
class Train:Vehicle //定义子类 火车
{
public override void Move() // 用override来重写虚方法
{
Console.WriteLine("{0}可以在铁轨上行驶", Name); //把默认的base方法替换掉
}
}
class Car:Vehicle // 定义子类 汽车
{
public override void Move()
{
Console.WriteLine("{0}可以在道路上行驶", Name);
}
}
class Program
{
static void Main(string[] args) // 在Main()中创建对象
{
Vehicle v = new Vehicle(); // 先创建父类对象
Train t = new Train();//创建子类对象
Car c = new Car(); // 创建子类对象
Vehicle[] vs = { v, t, c }; // 创建父类的对象数组并赋值,这个集合名叫vs。
v.Name = "交通工具";
t.Name = "火车";
c.Name = "汽车";
vs[0].Move(); //第一个元素是 v,在基类中,所以默认调用基类方法
vs[1].Move(); //第二个元素是t,在派生类中,所以会自动调用派生类 Train 中的方法
vs[2].Move(); //第三个元素是c,在派生类中,所以会自动调用派生类Car中的方法
Console.Read();
}
}
}
```
# 抽象类和抽象方法
接上述多态。
可在父类中定义抽象方法`abstract class Vehicle`,也就是没有中括号以及括号内的内容,然后在子类中重写override 。
但要注意,此时如果在Program 中创建对象,那么抽象方法无法创建对象,这时候要通过将其具体化到子类中去实现。
![](https://ws1.sinaimg.cn/large/006tNc79gy1frzxn6o7z2j30j00a5gn8.jpg)
![](https://ws1.sinaimg.cn/large/006tNc79gy1frzxq77vchj30nb07gdh3.jpg)
```
namespace 多态
{
abstract class Vehicle //abstract写前面,此时这个类也是抽象的
{
public string Name { get; set; }
public abstract void Move(); // abstract 为抽象方法,无需中括号以及其内部的内容。
}
class Train:Vehicle
{
public override void Move() // 用override来重写虚方法
{
Console.WriteLine("{0}可以在铁轨上行驶", Name);
}
}
class Car:Vehicle
{
public override void Move()
{
Console.WriteLine("{0}可以在道路上行驶", Name);
}
}
class Program
{
static void Main(string[] args) // 在Main()中创建对象
{
Train t = new Train();
Car c = new Car();
Vehicle v = new Train(); //此时创建父类对象时,要直接用子类的属性。
v.Name = "火车";
v.Move();
Console.Read(); //输出的结果为“火车在轨道上行驶”
}
}
}
```
# 接口
关键字:`interface`
实现:通过类 继承接口 来实现。
比如:定义2 个接口(名叫Information、Information2)
```
interface Information
{
string Code{get; set;}
string Name{get; set;}
void ShowInfo(); //不允许写修饰符 public
}
interface Information2
{
string Code{get; set;}
void ShowInfo();
}
```
实现:通过类来实现
```
public class JHInfo: Information, Information2 // 继承接口的列表
{
string code = "";
string Name = "";
public string Code //定义属性
{
get { return code;}
set { code = value;}
}
public void ShowInfo()
{
console.writeline(Code + Name);
}
}
```
> 报错:C#运行提示错误不实现接口成员
意思是:在接口中定义的所有元素,在后续要实现的类中,一旦继承了,就必须全部再体现一遍。例如上述接口中定义了两个属性以及一个方法,那么在后续的实现类中,也必须定义两个属性以及一个方法。
- 帮助文档 microsoft helo viewer
- c#开发环境及visual studio安装注意事项
- c#程序基本结构-基本语法
- Q1: public static void main(String[] args) 是什么意思
- Q2: c#命名空间+Main方法
- Q3:注释+命名规则+代码规则
- Q4: c#语句 system => console
- Q5: 数据类型 .net
- Q5: 常用名字、变量、运算符
- Q6: 对话窗输入-属性
- Q7: 递归
- Q8:决策分支、条件判断语句 if 语句
- Q9:数组
- Q10:字符串
- Q11:对象、类、访问权限、静态动态函数
- Q12:方法及参数——继承于类
- Q13:构造函数
- Q14:继承——base 关键字
- Q15:多态、虚方法、接口
- Q16:创建窗体应用、控件
- Q17:Ado数据访问、连接 sqlserver 数据库
- Q18: 读取数据command + DataRead( )、DataSet + DateAdapter
- Q19: Entity Framwork、entity 与 ADO.net的区别
- Q20: 对话框、文件、文件夹
- Q21: 导入excel数据、更新到 dbo 数据库中
- Q26: 获取 excel 中每个 sheet 的表名
- Q22: 两个窗体之间数据+方法传递
- Q23: 数学对象
- Q24: c#网站编写
- Q25: visual studio2017如何查看帮助
- Q27: c# dictionary 字典对象
- Q28: 数组与dataTable互相转化