1多态是为了让相同类的不同对象尽可能的体现出不同的特性:
c#中多态的实现有3种方法:
虚方法,抽象类和接口
虚方法:在父类中某一个特殊的方法做个标记,表示我知道这个方法在父类中怎么实现,但这个方法在子类中可能要被重写~
用virtual标记的方法的调用优先级会被降低,那么
1)父类对象去调这个方法的时候,就是调用虚方法本身(注意:虚方法和一般方法一样,也是可以被调用的)
2)子类对象去调用虚方法时,若子类中重写了overwrite了虚方法,那么就会去调用子类的方法,否则调用父类的虚方法
以上两点虚方法和普通的方法调用没有任何区别
3)
当父类中装载子类对象时,子类虽然表现出父类的特性,但父类虚方法会被子类的重写方法隐藏--------------多态的实现
用同一个父类对象去装载不同的子类对象,当调用父类对象的虚方法时,实际上回去调用真正子类重写的对应虚方法
class Program
{
static void Main(string[] args)
{
Father s = new Son(12);
s.SayHello(); //调子类方法,输出“我是Son”,注意:父类如果初始化自己的对象,也可以去调用自己的虚方法
Console.ReadKey();
}
}
public class Father : Object
{
public int Age { set;get; }
public Father(int age)
{
this.Age = age;
}
public virtual void SayHello() {
Console.WriteLine("我是father");
}
}
public class Son : Father
{
public Son(int age) : base(age) { }
public override void SayHello()
{
Console.WriteLine("我是Son");
}
}
抽象类:
当一个方法在父类中我不知道该怎么去实现时,此时可以采用抽象方法~抽象方法只能包含在抽象类中
1.抽象类不能初始化,只能初始化继承抽象类的子类
2.抽象类中可以有不抽象的属性和方法,并且可以在子类中继承到并调用
3.抽象方法只能申明,不能有方法体,只能在实现其抽象方法的子类中去调用
4.普通的类中不能有抽象方法,若类中用到一个抽象方法,则这个类必须是抽象类
实例代码:
class Program
{
static void Main(string[] args)
{
Father s = new Son(12);
s.SayAge();
Console.ReadKey();
}
}
public abstract class Father : Object
{
public int Age { set;get; }
public Father(int age)
{
this.Age = age;
}
public virtual void SayAge(){} //1)抽象类只是不能实例化和必须有抽象方法,其他与普通类没有什么区别 2)virtual实现多态必须要有方法体
public abstract void SayHello();//1)abstract必须要在抽象类中2)abstract方法中必须没有函数实现
}
public class Son : Father
{
public Son(int age) : base(age) { }
public override void SayHello()
{
Console.WriteLine("我是Son");
}
public override void SayAge()
{
Console.WriteLine("Age is {0}",this.Age);
}
}
virtual和abstract申明的方法都可以直接被覆盖,子类中用override显式声明去覆盖它(
当用父类类型去承载子类的对象时,子类对象装进父类类型中的时刻,有override的方法就可以去覆盖父类中的同名的virtual或abstract方法)
当使用抽象类时,子类继承抽象类时,如果子类不是抽象类时,必须实现父类中所有的抽象的属性和方法
什么时候应该去使用抽象类:
如果类中需要写抽象的成员(抽象方法和抽象属性),就把包含这个抽象方法的类写成抽象类
如果类中不需要抽象的成员(抽象方法和抽象属性),就不用写成抽象类
//用抽象模板类实现多态的一个经典的例子: class Program { static void Main(string[] args) { Shape s = new Rectangle(5, 2);//new Circle(5); Console.WriteLine("Area:{0} Length:{1}",s.getArea(),s.getLength()); Console.ReadKey(); //用父类去装子类对象的好处,更换子类对象,其它地方的代码不用去变动 } } /************************************************************************/ /* 抽象类的基本模板,我不知道在基类中怎么实现 getArea()和getLength()方法 * 因此需要把这两个方法写成抽象方法,因此基类也就自然是抽象类了*/ /************************************************************************/ public abstract class Shape : Object { public abstract double getArea(); public abstract double getLength(); } /************************************************************************/ /* 实现圆的面积和周长 */ /************************************************************************/ public class Circle : Shape { //圆自己的属性 public double R { get; set; } //圆的构造方法 public Circle(double r) { this.R = r; } public override double getArea() { return Math.PI * Math.Pow(R, 2); } public override double getLength() { return 2 * Math.PI * R; } } /************************************************************************/ /* 实现矩形的面积和周长 */ /************************************************************************/ public class Rectangle : Shape { public double Length { get; set; } public double Width { get; set; } public Rectangle(double length, double width) { Length = length; Width = width; } public override double getArea() { return Length*Width; } public override double getLength() { return 2*(Length+Width); } }