C#多态
概念:一个对象能有多种形态或者类型。
当子类中的方法和父类中的方法同名时
解决方法:
(1)方法的重载(方法名相同,参数(类型、个数)不同)
(2)隐藏父类中的方法(在子类方法修饰符后面加 new)
(3)虚方法(在父类方法修饰符后面加 virtual ,在子类方法修饰符后面加 override)
1. 虚方法 virtual
使用:
(1)将父类的方法标记为 virtual 。
(2)将子类的方法标记为 override 。
(3)使用虚方法一样可以调用父类的方法。
(4)实例:
using System;
namespace _虚方法Virtual
{
class Shape //父类
{
protected int width, height; //字段
public Shape(int a = 0, int b = 0) //构造方法
{
width = a;
height = b;
}
public virtual int area() //与子类方法同名,父类在访问修饰符后面加 virtual
{
Console.WriteLine("父类的面积:");
return 0;
}
}
class Rectangle : Shape //子类 Rectangle
{
public Rectangle(int a = 0, int b = 0) : base(a, b) //构造方法
{
}
public override int area() //与父类方法同名,父类在访问修饰符后面加 override
{
return (width * height);
}
}
class Triangle : Shape //子类 Triangle
{
public Triangle(int a = 0, int b = 0) : base(a, b) //构造方法
{
}
public override int area() //与父类方法同名,父类在访问修饰符后面加 override
{
return (width * height / 2);
}
}
class Tester
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(3,5); //创建 Rectangle 对象
Triangle t = new Triangle(6,5); //创建 Triangle 对象
int R_area = r.area(); //使用对象中的方法;
int T_area = t.area(); //使用对象中的方法;
Console.WriteLine($"Triangle 类的面积:{T_area},Rectangle 类的面积:{R_area}");
Console.ReadKey();
}
}
}
2. 抽象类 abstract
注意点:
(1)抽象方法没有方法体。
(2)抽象成员只能存在于抽象类中。
(3)抽象类中可以有非抽象成员。
(4)抽象类的子类必须实现抽象类中的方法。
(5)抽象类只能作为父类,不能被实例化。
(6)实例:
using System;
namespace _抽象类abstract
{
abstract class Shape //抽象类
{
abstract public int area(); //抽象方法
}
class Rectangle : Shape //子类
{
private int length;
private int width;
public Rectangle(int a = 0, int b = 0)
{
length = a;
width = b;
}
public override int area() //实现父类的抽象方法
{
Console.WriteLine("Rectangle 类的面积:");
return (width * length);
}
}
class RectangleTester
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(10, 7);
double a = r.area();
Console.WriteLine("面积: {0}", a);
Console.ReadKey();
}
}
}
虚方法 | 抽象方法 |
---|---|
用 virtual 修饰 | 用 abstract 修饰 |
要有方法体 | 没有方法体 |
可以被子类 override 重写 | 必须被子类 override 重写 |
除了密封类之外的任何类中 | 只能在抽象类中 |
3. 接口 interface
特点:
(1)通常接口命令以 I 字母开头。
(2)接口可以被其他类多重继承。
(3)不能直接对接口进行实例化。
(4)可以包含方法、属性、事件、索引器等成员,但不能有字段。
(5)成员的访问权限默认为 public,不需要写访问修饰符。
(6)接口不能继承类,可以继承接口。
(7)接口是特殊的抽象类,不能为接口成员编写具体的可执行代码。
(8)实例:
using System;
namespace _接口Interface
{
interface IParentInterface //声明接口类
{
void ParentInterfaceMethod();
}
interface IMyInterface : IParentInterface //接口可以继承接口,不能也不需要实现父类的方法。
{
void MethodToImplement();
}
class InterfaceImplementer : IMyInterface //类继承接口
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
iImp.ParentInterfaceMethod();
Console.ReadKey();
}
public void MethodToImplement() //实现接口 IMyInterface 中的方法
{
Console.WriteLine("MethodToImplement() called.");
}
public void ParentInterfaceMethod() //实现接口 IParentInterface 中的方法
{
Console.WriteLine("ParentInterfaceMethod() called.");
}
}
}