C#类的继承、基类构造器、类的赋值、虚方法、Protected、扩展方法
使用继承
使用以下语法声明一个类从另一个类继承:
class DerivedClass:BaseClass
{
...
}
派生类DerivedClass将从BaseClass继承,基类中的方法会成为派生类的一部分.在C#中,一个类最多只允许从一个其他的类派生; 除非将DerivedClass声明为sealed,否则可以使用相同的语法,从DerivedClas派生出更深一级的派生类.
class DerivedSubClass : DerivedClass
{
}
比如哺乳动物,呼吸和哺乳是哺乳动物都有的功能,我们可以创建一个哺乳动物类
class Mammal
{
public void Breathe()//呼吸
{
...
}
public void SuckleYoung()//哺乳
{
...
}
}
然后比如马是哺乳动物,就可以继承Mammal类
class Horse: Mammal
{
public void Trot()//跑
{
}
}
static void Main(string[] args)
{
Horse horse = new Horse();
horse.Breathe();//呼吸
horse.SuckleYoung();//哺乳
horse.Trot();//跑
}
然后在程序中创建Horse对象后,它就可以呼吸,哺乳和跑了.
注意:C#继承总是隐式公共,不需要也不能显示指定继承是公共、私有还是受保护.
…
…
…
调用基类构造器
除了继承得到的方法,派生类还自动包含来自基类的所有字段.
创建对象时,这些字段需要初始化,通常用构造器执行这种初始化。作为好的编程实践,派生类的构造器在执行初始化的时候,最好调用一下基类的构造器:
class Mammal
{
public Mammal(string name)
{
...
}
}
class Horse: Mammal
{
public Horse(string name) :base(name)
{
...
}
}
如果不显示调用基类构造器,编译器会自动插入对基类默认构造器的调用:
class Mammal
{
public Mammal(string name)
{
...
}
}
class Horse: Mammal
{
public Horse(string name) :base()
{
...
}
}
但是记住并不是所有类都有公共默认构造器的,在这种情况下,忘记调用正确的基类构造器会造成编译错误.
…
…
…
类的赋值
class Mammal
{
...
}
class Horse: Mammal
{
...
}
class Whale: Mammal
{
...
}
...
Horse myHorse = new Horse();
Whale myWhale = myHorse;//错误
上面这种赋值是错误的,但是可以将一种类型的对象赋给继承层次结构中较高位置的一个类的变量:
Horse myHorse = new Horse();
Mammal myMammal = myHorse;//合法
因为Mammal是Horse的基类,但是注意如果用Mammal变量引用一个Horse对象,就只能访问Mammal类定义的方法和字段。比如:
Horse myHorse = new Horse();
Mammal myMammal = myHorse;//合法
myMammal.Breathe();//合法
myMammal.Trot();不合法
这就是为什么一切都能赋给object变量,因为所有类都直接或间接继承Object.
反过来不行,不能将Mammal对象赋给Horse变量.
不能直接将Mammal对象赋给Horse变量,除非先进行检查,确认该Mammal确实是Horse.可以使用as或is操作符,通过强制类型转换来进行。
声明新方法
派生类中的方法会屏蔽(或隐藏)基类具有相同签名的方法。
比如:
如果另一个类从Horse派生,并调用Talk方法,它希望调用的可能是Mammal类实现的Talk,但该方法被Horse中的Talk隐藏了,所以实际调用的是Horse.Talk. 如果确实希望两个方法具有相同签名,从而隐藏Mammal.Talk方法,可以使用new关键字消除警告.
使用new关键字,隐藏仍会发生。它唯一的作用就是关闭警报.
声明虚方法
虚方法用virtual关键字标记。比如:
故意设计成要被重写的方法称为虚方法.可以提供同一个方法的不同实现,比如假如我们不想用Object类的Tostring,我们可以对它进行重写
声明重写方法
派生类使用override关键字重写基类的虚方法,从而提供该方法的另一个实现.
比如:
注意:
1.虚方法不能私有,因为虚方法的目的就是通过继承向其他类公开, 重写方法也不能私有,因为类不能改变它继承的方法的保护级别。 但重写方法可用protected关键字实现"受保护"私密性.
2.虚方法和重写方法的签名必须完全一致.必须具有相同的名称和参数类型/数量.以及返回相同的类型
3.只能重写虚方法.
4.如果不使用override关键字,则不是重写,而是隐藏方法.
5.重写方法隐式成为虚方法,可在派生类中被重写,但是不允许使用virtual关键字将重写方法显示声明为虚方法.
…
…
受保护的访问
如果要运训基类的派生类访问基类的部分成员,同时阻止不属于该继承层次结构的类访问。这时就可以使用protected关键字标记成员:
如果类A派生自类B,就能访问B的受保护成员,如果类A不从类B派生,就不能访问B的受保护成员.
注意:不仅派生类能够访问受保护的基类成员,派生类的派生类也能.通俗地说也就是如果是一家人都可以访问,不是一家人就不能访问.
扩展方法
扩展方法允许添加静态方法来扩展现有的类型.引用被扩展类型的数据,即可调用扩展方法。
假定我们要为int类型添加新功能,比如一个名为Negate的方法,它返回当前整数的相反数。我们就可以使用扩展方法.
static class util
{
public static int Negate(this int i)
{
return -i;
}
}
必须附加this关键字,表明这是一个扩展方法;另外,this修饰int,表明扩展的是int类型.
调用Negate方法不需要引用Util类。C#编译器自动检测当前在作用域中的所有静态类,找出为给定类型定义的所有扩展方法.
上一篇: Java中的函数(方法)
下一篇: 最短路