c#基础-继承,派生类,派生类的构造 方法

原创 2013年12月02日 21:32:16
一、基本概念
首先我们来了解两个基本概念:实现继承和接口继承
(1)、实现继承,表示一个类派生于一个基类型,并拥有该基类型的所有成员字段和函数。
(2)、接口继承,表示一个类型只继承了函数的签名,没有任何实现的代码。在需要指定该类型具有某些可用的特性时,最好使用这种继承。
注意,在C#中,不支持多重继承,但一个类却可以实现多个接口。同样,结构总是派生于System.ValueType , 他们还可以派生于任意多个接口。


二、实现继承。

(1)、我们先来看个例子。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication8
{
    class test
    {
        public class baseClass
        {
            public string getUrl()
            {
                return "www.baidu.com";
            }
        }
        public class testt:baseClass
        {                    
            static void Main(string[] args)
            {
                testt testClass = new testt();
                Console.WriteLine(testClass.getUrl());
                Console.ReadKey();
            }
        }
    }
}
在上面的例子中,public class test : baseClass 就是声明了类test 继承自baseClass。这样,在类test 中也就具有了父类的方法,getUrl() 。在上例中输出结果是 www.baidu.com


(2)虚方法

把一个基类中的方法声明为 virtual ,则该函数可以在任何派生类中重写了。
在C#中,函数默认下不是虚拟的,需要显式的声明。但在java 中,所有函数都是虚拟的。C#中,派生类的函数重写另一个函数时,要使用override 关键字显式的声明。如果声明了override 函数,但在基类中如果没有可以重写的函数,编译器就会报错了。
注意,成员字段和静态函数都不能声明为 virtual ,因为这个概念只对类中的实例函数成员有意义。
我们来看个例子。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication9
{
    class test
    {
        public class baseClass
        {
            public virtual string getUrl()
            {
                return "www.cnblog.cn";
            }
        }

        public class baseClass2 : baseClass
        {
            //public new string getUrl()  
            public override string getUrl()
            {
                //return "baidu.com";
                string url = "http://";
                url += base.getUrl();
                return url;
            }
        }
        public class testClass : baseClass2
        {
            static void Main(string[] args)
            {
                testClass testtry = new testClass();
                Console.WriteLine(testtry.getUrl());
                Console.ReadKey();
            }
        }
    }
}
结果为:http://www.cnblog.cn


(3)隐藏方法

在上例中,baseClass2 类的getUrl()方法,如果没有override 关键字,则baseClass2 类的getUrl()方法就会隐藏基类的getUrl()方法。在编译的时候,系统会给予警告。

(4)、调用函数的基本版本
还是看上一个例子,我们稍作修改,如下:


(5)、抽象类和抽象方法。
C#允许把类声明为 abstract ,抽象类不能实例化,抽象方法不没有执行代码。
我觉得抽象类和抽象方法没有什么用,一般我们用接口就可以了。搞不太明白C#中这个抽象类和抽象方法到底想用来干什么。

(6)、密封类和密封方法。
如果把类声明为 sealed 即标明该类不可以被继承,如果是方法,则方法不可以被重写。

(7)、派生类的构造方法。
在派生类中,构造方法是依次从基类中执行,最后到派生类本身的构造函数。
我们来看下面的例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication10
{
    public class userBase
    {
        //私有变量username
        private string username;
        //默认构造方法
        public userBase()
        {
            Console.WriteLine("i'm good man.");
        }
        //有参数的构造方法
        public userBase(string user)
        {
            //this.username = user;
            this.username = user + " is";
            Console.WriteLine(username + " a good man too!");
        }
    }

    public class oneMen : userBase
    {
        //三个构造方法
        public oneMen()
        {
            Console.WriteLine("yes,i'm very good man!");
        }
        //继承基类的构造方法,间接地给基类中的的私有字段赋值了
        public oneMen(string username)
            : base(username)
        {
            Console.WriteLine(username + " is a good man!");
        }
        public oneMen(string username, string hisWebsite)
            : base(username)
        {
            Console.WriteLine(username + "'s website is " + hisWebsite);
        }
        static void Main(string[] args)
        {
            oneMen classOne = new oneMen();
            oneMen classTwo = new oneMen("Steven");
            oneMen classThree = new oneMen("Threek", "www.aidream.net");
            //userBase classFour = new userBase("sunshine");
            //基类的构造方法,先执行,再执行继承类的构造方法。继承类的参数会传递给基类吗?
            Console.ReadKey();
        }
    }
}
我们先声明了一个 userBase 类,其有个私有成员变量,还有两个构造函数。oneMen 类派生自userBase 类。并且oneMen 类有其自己的三个构造函数。public oneMen(string username):base(username)这个构造函数继承了基类中的构造函数,间接的给基类中的私有字段赋值了。public oneMen(string username,string hisWebSite):base(username) 这个构造函数也继承了基类的构造函数,在Main()函数中我们依次通过三种方式实例化oneMen 类的时候,依次输出的结果是:



对下面这句有点不解:

this.username = user;
是把参数传递给变量,不写也能运行,为啥要写?

下面还有个例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication11
{
    class Program
    {
        public class Hide
        {
            public int HideYou()
            {
                int global = 3;
                return global;
            }
        }

        static void Main(string[] args)
        {
            int global = 5;
            Hide hide = new Hide();
            int ret = hide.HideYou();
            Console.WriteLine(ret);
            Console.ReadKey();
        }
    }
}
结果为3,定义的global的值5哪里去了?是被重新复制了么?





版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C#控制台基础 关于派生类构造函数的注意事项

镇场诗:慈心积善融学习,技术誓为大家学。善心速造多好事,前人栽树后乘凉。我今于此写经验,愿见文者得启发。 ——————————————————————————————————————————————...

黑马程序员_学习日记5_C#基础归纳总结之派生类的构造函数

---------------------- Windows Phone 7手机开发、.Net培训、期待与您交流! ---------------------- 派生类的构造函数       我们...

关于C#中派生类调用基类构造函数的理解[转]

写的非常细 本文中的默认构造函数是指在没有编写构造函数的情况下系统默认的无参构造函数 1、  当基类中没有自己编写构造函数时,派生类默认的调用基类的默认构造函数 Ex:  ...

C#中基类和派生类的构造函数以及变量的执行顺序整理

整理了下C#中基类以及派生类的构造函数,变量声明的执行顺序。   先上试验代码:     1 class Program  2     {  3  ...

C#中基类和派生类的构造函数以及变量的执行顺序整理

转自http://www.cnblogs.com/aaronbao/archive/2010/04/01/1702183.html整理了下C#中基类以及派生类的构造函数,变量声明的执行顺序。  先上试...

【Linux基础】派生类的构造过程和析构过程

基类的构造函数和析构函数都不被继承,需要在派生类中重新定义。由于派生类继承了基类的成员,在初始化时,也要同时初始化基类成员。可通过调用基类的构造函数对完成初始化。 派生类的构造过程 派生类构造函数...

C++语法基础--派生类的构造函数,赋值操作符,析构函数,虚析构函数

1.如果派生类定义了自己的构造函数(复制构造函数)或赋值操作符,该构造函数(复制构造函数)或赋值操作符一般应显式使用基类构造函数(复制构造函数)或赋值操作符初始化基类部分、   Eample:  ...

c++多态之继承3-派生类的构造次序

上篇文章中我介绍了一些c++中继承的基本知识,本文我们将更近的观察下当派生类被实例化的时候发生的一些事。 首先,我们引用一个新的类来说明一些重要知识点。 class Base { public: ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)