多态
概念:
不同对象调用同一方法时,会有不同的表现行为,即方法名相同,但是动作不相同。
好处:
当我们想要表现不同对象的行为时,只调用一个方法就可以,不需要反复写多个方法,减少代码的冗余。
通过下面的图,可以看到继承和多态的区别:
子类继承父类是子类继承父类的方法,当调用父类的方法时,子类表现与父类完全相同,想让子类表现不同,需要重复地调用子类的方法,使得代码复杂冗余。当我们想只通过调用父类的方法,让子类表现不同的行为,就是只要一行代码,就可以让子类的表现各自的动作时,怎么办?这就需要面向对象的另一个概念即多态。
多态的实现方法
一:用父类实现多态
父类的方法为虚方法,子类重写父类。
virtual:子类与父类方法同名,我们需要用virtual把父类的方法定义为虚方法。
//定义person类
public class Person
{
//person类的无参数的构造方法
public Person()
{
}
//Person 类的有参数的构造方法
public Person(string name)
{
this.name = name;
}
private string name;
public string Name
{
get { return name; }
set { name = value; }
}
public virtual void Show()//虚方法,有方法体
{
Console.WriteLine("我是人别怕");
}
}
override:在子类中想定义同父类方法名相同的方法,我们需要用override重写父类的方法。
public class Teacher : Person
{
//子类会调用父类的构造方法
public Teacher(string name)
: base(name)
{
}
//重写Show方法
public override void Show()
{
Console.WriteLine("我叫{0},年龄{1},是{2}老师",this.Name);
}
}
调用方法时,父类会调用父类的Show方法,子类会调用子类的Show方法.方法名相同,但是表现行为却不同。
static void Main(string[] args)
{
Person p=new Person() ;
p.Show();
Teacher tea = new Teacher("李娜");
tea.Show ();
Console.ReadKey();
}
二:用抽象类实现多态
什么时候使用抽象类以及抽象方法?
举个例子:
现在有Animal,Cat,Dog,Pig,Cow五个类,我们发现Animal拥有的属性和方法,Cat,Dog,Pig,Cow都有,这是我们就想着吧Animal作为其他几个类的父类,让其他几个类来继承这个父类,减少代码量。但当我们定义Animal的方法的时候,如定义一个叫(shout)的方法,我们会发现这四个子类Cat,Dog,Pig,Cow虽然都有叫这个方法,但怎么叫(表现)不一样。所以我们在父类中定义shout方法的时候,不需要对shout这个动作进行修饰叙述,把动作写死。这时我们就在父类中定义了对象的抽象方法,只有方法名,不用声明主体。
怎么使用?
1.用abstract修饰
2.抽象方法必须存在在抽象类中,抽象类不能实力化为对象,所以本身不能使用方法,抽象类的方法是给子类使用的,抽象类一定是父类,当时父类不一定是抽象类。
3.抽象方法不用声明主体
4.当父类是抽象类时,子类继承了这个类,必须把抽象类中的方法重写
具体使用:
abstract:我们定义父类为抽象类,方法Shout为抽象方法,用abstract修饰。
//定义Animal父类为抽象类
public abstract class Animal
{
//构造函数
public Animal(string name)
{
this.name = name;
}
string name;
public string Name
{
get { return name; }
set { name = value;}
}
public abstract void Shout();//抽象方法
}
override:在子类中,必须用override重写方法。
//猪子类
public class Pig : Animal
{
public Pig(string name): base(name)//有参数的构造函数
{
}
public override void Shout() //重写方法
{
Console.WriteLine("{0}哼哼叫...",this.Name );
}
}
方法的调用:当我们把各个子类的实例放到animal数组中的时候,想要调用各个子类的方法的时候,直接调用Shout方法即可,代码的冗余大大减小。
for (int i = 0; i < animal.Length; i++)
{
animal[i].Shout();
}
虚方法与抽象方法区别:
总结:
多态是面向对象一个非常重要的概念,通过多态,可以很简单地就可以实现子类的多个不一样的行为,父类方法与子类方法相同,使用时子类中的方法必须重写,或用new来重新定义。