从C/C++到C# (2)

    本系列的第二篇主要针对类的继承

  • C#中只允许从一个基类派生,而C++可以从多个基类派生;而且C#的继承永远是public的,C++的继承可以是public/private/protected中的一种。
  • C#的子类自动包含了父类的所有field,子类的构造函数必须调用基类的构造函数,子类使用base关键字来显式调用基类构造函数;如果你没有显式调用基类构造函数,编译器会试图隐式调用基类的缺省构造函数;如果基类没有一个public的缺省构造函数,子类就必须显式调用基类某个构造函数

            class IdentifierToken : Token

            {

                public IdentifierToken(string name)

                       : base(name) // calls Token(name)

                {

                    ...

                }

                ...

            }

  • 可以将基类的变量赋值成子类,但是这时只能访问基类中定义的methodfield

            IdentierToken it = new IdentifierToken();

            Token t = it; // legal as Token is a base class of IdentifierToken

  • 如果基类和子类定义了具有相同签名(相同的方法名、同样数量和类型的参数)的方法,子类中的方法会屏蔽基类的方法,如果你确定要这样做且不希望受到编译器的警告,可以使用new关键字

            class Token

            {

                ...

                public string Name() { ... }

            }

            class IdentifierToken : Token

            {

                ...

                new public string Name() { ... }

            }

 
  • C#中可以通过virtual方法来实现多态性,在基类中使用virtual修饰函数,在子类中使用override来定义重新实现;virtual不可以和private共存,子类override的函数自动是virtual的,但是不能使用virtual关键字;子类和基类的两个函数必须具有相同的访问权限。

class Mammal

{

    ...

    public virtual string GetTypeName()

    {

        return "This is a mammal";

    }

}

class Horse : Mammal

{

    ...

    public override string GetTypeName()

    {

        return "This is a horse";

    }

}

class Whale : Mammal

{

    ...

    public override string GetTypeName ()

    {

        return "This is a whale";

    }

}

class Kangaroo : Mammal

{

    ...

}

Mammal m;

Horse h = new Horse();

Whale w = new Whale();

Kangaroo k = new Kangaroo();

m = h;

Console.WriteLine(m.GetTypeName()); // This is a horse.

m = w;

Console.WriteLine(m.GetTypeName()); // This is a whale.

m = k;

Console.WriteLine(m.GetTypeName()); // This is a mammal.

 

  • Interface可以将方法的名称和实现完全切分,Interface只包含方法的名称、返回值、参数,不包含实现,不包含public等访问修饰符(所有方法缺省都是public的);Interface中不能包含field,即使是static的也不行;Interface不能包含析构函数;Interface内不能嵌套类型(enum, struct, class, interface, delegate);Interface不能从struct/class继承。

interface IComparable

{

    int CompareTo(object obj);

}

  • 要实现一个Interface,你声明一个class或者struct继承这个Interface,并在其中实现所有的接口方法
  • 在实现接口的时候,如果使用了interface名称限定,称为explicit interface implementation,这种情况下不能使用public等修饰,自动拥有public属性,同时这种情况下方法不能作为virtual方法;如果一个类继承的多个接口中有相同的方法,只能使用这种方法实现,同时在调用的时候也只能通过interface调用;

interface IToken

{

    string Name();

}

class Token : IToken

{

    ...

    string IToken.Name() 

    {

        ...

    }

}

  • C#中的类可以同时继承基类和接口,但是基类必须位于继承列表中的第一个,后面可以跟多个interfaceInterface不能继承class,但是可以继承interface

interface IToken

{

    ...

}

class DefaultTokenImpl 

{

    ...

}

class IdentifierToken : DefaultTokenImpl , IToken

{

    ...

}

  • 你可以使用一个interface变量来引用实现了这个接口的类,但这时你只能调用这个interface中可见的方法。

IdentifierToken it = new IdentifierToken();

IToken iTok = it; // legal

  • 抽象类是不可以实例化的类,只能作为其他类的基类,使用abstract关键字修饰。
  • C#允许使用sealed关键字修饰类,这种类不能被继承,这种类中不能包含任何virtual方法;Struct全都是sealed的,不可被继承;sealed关键字也可以用于修饰单独的方法,表示这个方法不能被派生类override,你只能对override的方法使用sealed关键字。
(待续,下一篇将主要描述 C# 中的垃圾回收机制)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值