C#基础之继承

http://www.cnblogs.com/fangyz/p/5271780.html

 继承是在类之间建立一种相交的关系,使得新定义的派生类的实例可以继承已有的基类的特征并且还可以添加新的功能。以前对继承的理解仅仅限于定义,下面是我查了些资料、写了点代码的总结。

1.C#继承的特点

(1) 派生类是对基类的扩展,派生类可以添加新的成员,但不能移除已经继承的成员的定义。

(2)继承是可以传递的。如果C从B中派生,B又从A中派生,那么C不仅继承了B中声明的成员,同样也继承了A中声明的成员。

(3)构造函数和析构函数不能被继承,除此之外其他成员能被继承。基类中成员的访问方式只能决定派生类能否访问它们。

(4)派生类如果定义了与继承而来的成员同名的新成员,那么就可以覆盖已继承的成员,但这并不是删除了这些成员,只是不能再访问这些成员。

(5)类可以定义虚方法、虚属性及虚索引指示器,它的派生类能够重载这些成员,从而使类可以展示出多态性。

(6)派生类只能从一个类中继承,可以通过接口来实现多重继承。

2.一个简单的基础实现

//从运行结果可以看到很重要的一点,继承时先执行父类构造函数,
    //接着再执行子类构造函数,最后再执行方法
    class Program
    {
        static void Main(string[] args)
        {
            Man man = new Man();
            man.Eat();
            //在派生类中访问基类中的成员一般有2种方式,一是调用base.<成员> 调用基类的方法,二是显示类型转换为父类
            ((People)man).Eat();
        }
    }
    public class People
    {
        public People()
        {
            Console.WriteLine("父类的构造函数");
        }
        public void Eat()
        {
            Console.WriteLine("父类吃饭");
        }
    }
    class Man:People
    {
        public Man()
        {
            Console.WriteLine("子类构造函数");
        }
        public void WhoEat()
        {
            base.Eat();
        }
    }
3.隐藏基类成员
//当派生类需要覆盖基类的方法时,C#使用new修饰符来实现隐藏基类成员
    class Program
    {
        static void Main(string[] args)
        {
            Man man = new Man();
            man.Eat();
        }
    }
    public class People
    {
        public People()
        {
            Console.WriteLine("父类的构造函数");
        }
        public void Eat()
        {
            Console.WriteLine("我是父类");
        }
    }
    class Man:People
    {   
        public Man()
        {
            Console.WriteLine("子类构造函数");
        }
        public new void Eat()
        {
            Console.WriteLine("我是子类");
        }
    }
4.抽象类、密封类、抽象方法和虚方法

  首先还有一种类需要注意,那就是密封类。如果我们对类不作任何约束,也就是说所有类都可以被继承,这种继承的滥用会导致类的层次结构十分庞大,类与类之间的关系会变得很乱导致无法理解。因此C#提供了密封类,我们只需在父类前加上sealed修饰符,那这个类将不能被继承了。密封方法也是在方法前加上sealed修饰符。

  抽象类和密封类刚好相反,它是为继承而生的。抽象类不能实例化,抽象方法没有具体执行代码,必须在非抽象的派生类中重写。也就是基类并不实现任何执行代码,只是进行定义。这一点和接口有相同的地方。

 class Program
    {
        static void Main(string[] args)
        {
            Man man = new Man();
            man.Eat();
            man.Say();
        }
    }
    public abstract class People
    {
        //注意:如果类中有抽象方法,则类必须声明为抽象类。
        public People()
        {
            Console.WriteLine("父类的构造函数");
        }
        public abstract void Eat();
        //有时候不想把类声明为抽象类,但又想实现方法在基类里不具体实现,
        //而是想实现方法由派生类重写。遇到这种情况时可使用virtual关键字将方法声明为虚方法
        public virtual void Say()
        {
            //注意虚方法必须声明方法主体,抽象方法则不需要
            Console.WriteLine("我是父类的虚方法");
        }
    }
    class Man:People
    {   
        public Man()
        {
            Console.WriteLine("子类构造函数");
        }
        public override void Eat()
        {
            Console.WriteLine("我是子类");
        }
        public override void Say()
        {
            Console.WriteLine("我是子类的Say方法");
        }
    }
5.有参数的构造函数 
    class Program
    {
        static void Main(string[] args)
        {
            Man man = new Man("构造函数");
            //结果仍然是先输出父类构造函数,然后再输出子类构造函数
        }
    }
    public  class People
    {
        public  People(string s)
        {
            Console.WriteLine("父类"+s);
        }
    }
    class Man:People
    {   
        //在继承时,如果基类构造函数是有参数的,子类构造函数也必须有一个有参数的构造函数,否则会报错
        public Man(string s):base(s)
        {
            Console.WriteLine("子类构造函数");
        }
    }
评论:
#1楼   2017-06-03 20:10 |  JerryBiuBiuBiu   
感谢博主的分享,但是还是有一点的小东西比较迷糊,所以请问一下博主,

((People)man).Eat();

是什么意思呢
构造函数
什么是构造函数?通俗的讲,在类中,函数名和类名相同的函数称为构造函数。它的作用是在建立一个对象时,作某些初始化的工作(例如对数据赋予初值)。C++允许同名函数,也就允许在一个类中有多个构造函数。如果一个都没有,编译器将为该类产生一个默认的构造函数。
构造函数上惟一的语法限制是它不能指定返回类型,甚至void 也不行。
不带参数的构造函数:一般形式为 类名 对象名(){函数体}
带参数的构造函数:不带参数的构造函数,只能以固定不变的值初始化对象。带参数构造函数的初始化要灵活的多,通过传递给构造函数的参数,可以赋予对象不同的初始值。一般形式为:构造函数名(形参表);
创建对象使用时:类名 对象名(实参表);
构造函数参数的初始值:构造函数的参数可以有缺省值。当定义对象时,如果不给出参数,就自动把相应的缺省参数值赋给对象。一般形式为:
构造函数名(参数=缺省值,参数=缺省值,……);

析构函数:
当一个类的对象离开作用域时,析构函数将被调用(系统自动调用)。析构函数的名字和类名一样,不过要在前面加上 ~ 。对一个类来说,只能允许一个析构函数,析构函数不能有参数,并且也没有返回值。析构函数的作用是完成一个清理工作,如释放从堆中分配的内存。
一个类中可以有多个构造函数,但析构函数只能有一个。对象被析构的顺序,与其建立时的顺序相反,即后构造的对象先析构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值