继承
子类继承父类,具有父类的所有非私有成员(构造函数、析构函数除外)。派生类只可以从一个类中继承。
修饰符 class 派生类:基类
class Dog:Animal
修饰符:
- protected 声明是保护成员,表明它能被类和派生类的成员函数使用。保护成员具有继承性,而私有成员不具有继承性。
- sealed 作用是防止继承。
继承的规则
- object类是所有类型的基类
- 有些成员不能被继承,如父类的构造函数、析构函数和私有成员。子类在定义自己的构造函数时,可以用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
- 类型兼容性:在实例化时,可以构造父类实例化子类,反之不可,如
Animal animal=new Dog();
多态
编译时的多态:用哪个方法。是通过多个同名方法的不同声明实现。
运行时的多态:用哪些数据。直到运行时,才根据实际情况确定实现何种操作。
抽象类和接口仅仅是父类不同。
修改父类成员
- 使用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();}
- 使用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();的执行。
接口的特点
- 一个类可以继承多个接口,但只能继承一个类
- 接口不具备继承的任何具体特点,仅仅承诺了能够调用的方法