C#基础——继承、多态和接口

继承

子类继承父类,具有父类的所有非私有成员(构造函数、析构函数除外)。派生类只可以从一个类中继承。

修饰符 class 派生类:基类
class Dog:Animal

修饰符:

  1. protected 声明是保护成员,表明它能被类和派生类的成员函数使用。保护成员具有继承性,而私有成员不具有继承性。
  2. sealed 作用是防止继承。

继承的规则

  1. object类是所有类型的基类
  2. 有些成员不能被继承,如父类的构造函数、析构函数和私有成员。子类在定义自己的构造函数时,可以用base关键字调用父类的构造函数。
public class Animal
{protect double weight;
public Animal(double w)
{weight=w;}
}

class Dog : Animal
{bool ispet;
public Dog(double w,bool ispet):base(w) //自己的构造函数,先调用父类的,再使用自己的
{this.ispet=ispet;}

在子类中可以使用base.运算符来访问父类的非私有成员。
this.来访问所有自己的成员,区别同名成员/变量
3. 虽然继承不可以多继承,但是可以传递

class C:B
class B:A
//以上方法可以,以下方法不可
class C:A,B
  1. 类型兼容性:在实例化时,可以构造父类实例化子类,反之不可,如
Animal animal=new Dog();

多态

编译时的多态:用哪个方法。是通过多个同名方法的不同声明实现。
运行时的多态:用哪些数据。直到运行时,才根据实际情况确定实现何种操作。
抽象类和接口仅仅是父类不同。

修改父类成员

  1. 使用new修饰符隐藏父类的成员
    使用new,是新建一种子类特有的描述,并不改变父类的结果
class Animal
{	public void Eat()
	{	Console.WriteLine("Animals eat.");}
}
class Dog:Animal
{	new public void Eat()
	{	Console.Writeline("dogs eat bones.");}
}
class Program
{	static void Main()
	{	Dog dog=new Dog();
		dog.Eat();
		Animal animal=dog;
		animal.Eat();}
}
//运行结果
animals eat.
dogs eat bones.
//也可以在子类新方法中直接调用父类
new public void Eat()
{Console.WriteLine("dogs eat bones.").
base.Eat();}
  1. 使用override重载父类的成员实现继承多态
    关键字:
    virtual 供父类函数成员使用,表明是虚拟成员
    override 供子类函数使用,表明是重载成员
    虚拟函数成员包括虚方法、虚属性和虚索引器,没有虚拟字段
    父类的虚拟函数可以被重载,其他成员不可以被重载
class Animal
{	virtual public void Eat()
	{	Console.WriteLine("Animals eat.");}
}
class Dog:Animal
{	override public void Eat()
	{	Console.Writeline("dogs eat bones.");}
}
class Cat:Animal
{	override public void Eat()
	{	Console.Writeline("cats eat fish.");}
}
class Program
{	static void Main()
	{	Dog dog=new Dog();
		Cat cat=new Cat();
		Animal animal=dog;
		animal.Eat();
		animal=cat;
		animal.Eat();}
}
//运行结果
dogs eat bones.
cats eat fish.

重载改变了父类函数,父类函数无法通过base.方法被调用
3. 使用抽象类abstract实现多态性
抽象类只可以在基类中,不能使用new运算符
抽象类包含一些抽象函数成员,还可以包含非抽象函数成员
抽象类不可以是sealed的
抽象类的派生类必须实现抽象类预定义的所有抽象成员

abstract class Animal
{	public abstract void Eat();}
class Dog:Animal
{	public overrride void Eat()
	{	Console.WriteLine("dogs eat bones.");}
}
class Cat:Animal
{	public overrride void Eat()
	{	Console.WriteLine("cats eat fish.");}
}
class Program
{	static void Main()
	{	Dog dog=new Dog();
		Cat cat=new Cat();
		Animal animal=(Dog)dog;
		animal.Eat();
		animal=cat;
		animal.Eat();}
}
//运行结果
dogs eat bones.
cats eat fish.

接口

定义与使用方法

接口和抽象类相似,但又不同。接口提供一类物体的描述,是一种“设计蓝图”。

修饰符 interface 接口名[:基接口列表]
public abstract class Animal
{	public abstract void Eat();
	protected double weight=1;}
public interface IBart
{	void Bark();
}
public class Dog:Animal,IBark
{	public void Bark()
	{	Console.WriteLine("wang wang.");}
	public override void Eat()
	{	Console.WriteLine("dogs eat bones.");}
}

class Human
{	static void BuyPet(IBark pet)
	{	pet.Bark();}
	static void Main()
	{	Dog dog1=new Dog();
		BuyPet(dog1);}
}
//运行结果
wang wang.

实质上是BuyPet(dog1)引发了pet=dog1;pet.Bark();的执行。

接口的特点

  1. 一个类可以继承多个接口,但只能继承一个类
  2. 接口不具备继承的任何具体特点,仅仅承诺了能够调用的方法
发布了7 篇原创文章 · 获赞 2 · 访问量 643

猜你喜欢

转载自blog.csdn.net/qq_41450779/article/details/93177950