一、类的继承
class A
{
......
}
class B : A
{
......
}
如此,则称B是A的子类/派生类,A是B的父类/基类。
所有类的基类都是object类。
派生类的内部原理其实是,先调用基类构造器,再一层一层往下调用,即在内部过程会创造一个基类的实例。因而修改子类对象时,创建的那个基类对象也会相应地被修改。同时,基类对象的东西如果没被修改,就会一直保存原来的值。
base与this相对,引用的是上一层基类的对象,base只能引用一层。
派生类在基类的基础上进行了横向拓展(成员数量上)和纵向拓展(类的重写)。
派生类会继承基类的所有内容
注:除了构造器。如下例:
class Vehecle
{
public string VehiecleName { get; set; }
public Vehecle(string name)
{
this.VehiecleName = name;
}
}
class Car : Vehecle
{
}
这时候,编译器会报错。需改成如下形式:
namespace ConsoleAppPractice
{
class Program
{
static void Main()
{
Car car = new Car("Baoma");
Console.WriteLine(car.VehiecleName);
}
}
class Vehecle
{
public string VehiecleName { get; set; }
public Vehecle(string name)
{
this.VehiecleName = name;
}
}
class Car : Vehecle
{
public Car(string name) : base(name)
{//此处构造器内内容为空即可。是把name传到了基类构造器
}
}
}
此时base向上传递,将name赋给了基类对象。因而,接下来就可以不必对子类对象进行修改。这一点很神奇。
一个子类的实例也是一个父类的实例。所以可以用父类变量引用子类的对象。
static void Main()
{
Vehecle car = new Car("Car");
Console.WriteLine(car is Car);
}
sealed修饰符用在类,可以让这个类不能作为基类。
子类的访问级别不能超过父类
类成员的访问级别以类为上限
namespace MyLib.MyNameSpace
{
public class Vehecle
{
private int _fuel;
protected int rpm { get; set; }
public void AddOil()
{
_fuel += 100;
}
protected void Burn()
{
_fuel--;
}
public void Accelerate()
{
Burn();
rpm += 1000;
}
public int Speed { get { return rpm / 1000; } }
}
public class Car : Vehecle
{
public void AnotherAccelerate()
{
Burn();
Burn();
rpm += 2000;
}
}
}
public:可以在程序集间自由使用
interval:只能在该程序集之间自由使用
protected:可以跨程序集,只在类继承链上使用 一般用于方法
private:只能在该类体里面使用,派生子类也用不了 一般用于私有字段
protected和interval可以公用,表示或的关系,即既可以被派生类访问,又可以被该程序集所有访问
二、类的重写
namespace ConsoleAppPractice
{
class Program
{
static void Main()
{
Vehicle v = new Car();
v.Run();
Console.WriteLine(v.Speed);
}
}
class Vehicle
{
private int _speed;
public virtual int Speed { get { return _speed; } set { _speed = value; } }
public virtual void Run()
{
Speed += 100;
Console.WriteLine("A vehicle is running!");
}
}
class Car : Vehicle
{
private int _rpm;
public override int Speed { get { return _rpm / 100; } set { _rpm = value * 1000; } }
public override void Run()
{
_rpm += 5000;
Console.WriteLine("A car is running!");
}
}
}
注意virtual、override关键字的使用
称virtual修饰的为虚成员/虚函数。virtual应该理解为“名存实亡的”,“可被重写的”。
三、类的多态
类的多态基于重写机制。
函数成员的具体行为(版本)由对象决定
还是因为C#的变量和对象有自己的类型,因而存在“代差”