关于aspx页面类继承于cs页面类

cs页面类继承自System.Web.UI.Page类,一般和文件同名,如果遇见关键字的情况才会自动使类名前加个'_',例如:_Default。关于cs页面类我们经常使用,它事实上是一个部分类,除了在cs文件里有一部分以外,在designer.cs文件还有另一部分(声明控件)。我们来谈谈其派生类---aspx页面类(从<%@Page里的Inherits属性可以看出),虽然我们编程的时候主要是针对cs页面类,但事实上在页面运行时,比如说cs页面类有一个Button的单击事件,.NET是到aspx页面类里找的,但由于aspx页面类是继承了cs页面类,所以.NET在aspx页面类里也能找到该单击事件,其他成员也是一样的道理。所以你会发现自动生成的事件的访问级别都是protected。所以你在cs页面类里自定义的方法(当然还有字段,属性等其他成员变量),如果在apsx页面类要使用的话,你也要将该方法的访问级别设为public或protected。这里的使用指1.<%# %>和<%= %>(http://kendezhu.iteye.com/blog/737526)及2.①和②<% %>(①里的代码在aspx页面类里就相当于你在cs页面类的类括号里的代码,写的就是类里的成员方法。②里的代码在aspx页面类里就相当于你在cs页面类的大概是Render方法里的代码,已经位于页面生命周期的Render阶段,已是晚期了,只能写方法里能写的代码。里的代码被编译进aspx页面类里了!<%%>里的代码被编译进该类的Page_PreRender方法(所以同样是对一个Label的text赋值,在<%%>里赋的值会在后面)。http://www.cnblogs.com/Lyhik/archive/2008/02/08/1066113.html及

http://bbs.firnow.com/dview16t27811.html的10楼),1和2里代码就相当于派生类自己的成员,不管这些成员是什么访问级别,在页面执行时肯定会被访问到。而且写在这里面的代码不用重新生成,跟website方式一样(website没cs和designer.cs)。

根据ASP.NET页面对象模型:http://msdn.microsoft.com/zh-cn/library/aa479007.aspx里的真正Page类的说法,我们可以在里的方法里将aspx页面类实例化,这个类名就是其继承的cs类名(一般是小写)_aspx。当然这个类名可以通过Page的ClassName属性来修改。

说到继承我们不得不来讨论一下有关访问限制修饰符的知识:

首先可在命名空间下直接定义的类型有类(顶级类),结构,接口,枚举,委托等。它们只能被修饰为Public和Internal,如果未加任何修饰符,默认为Internal。

类的成员(成员变量,成员方法,属性,嵌套类等)可被修饰为Public,Private,Internal,Protected,如果未加任何修饰符,默认为Private,局部变量只在成员方法内有效,不能被访问修饰符修饰。嵌套类作为类中类,其也是一种成员,所以可以被修饰为Private,嵌套类类内的Private成员在外层类内也是无法访问(将嵌套类在外层类内实例化后再访问)。

Private只能修饰类和结构的成员,这些成员只属于该类,派生类虽然继承了其父类的private成员,但却访问不了(不能直接访问,但有方法,下面会讲到)。

Protected只能修饰类的成员,这些成员只能在父类及其派生类内访问。

Internal修饰的类型只能在同一个程序集内访问。

Public修饰的类型没有访问限制,在同一个程序集里:如果位于同一命名空间,可直接访问,如果位于不同命名空间,先引入该命名空间可访问。在不同程序集里:先引用该程序集再引入相应命名空间就可访问。

关于程序集:http://kendezhu.iteye.com/blog/745411

对于特殊的,如我们使用外部控件,这些控件是一些特殊的类,被编译在组件里,然后组件也有命名空间和程序集,同样要引用程序集,不过对于控件的程序集的引用要通过工具箱的选择项,引用后选择其中的相应组件。之后在我们将该控件拖入页面后就在解决方案资源管理器里就引用了该控件所在的程序集。同时页面上方会出现<%@ Register Assembly="**" Namespace="**" TagPrefix="**" %>这种类似于using的东西,分别是程序集,命名空间,前缀。可以像我们在使用Ajax扩展控件时做的那样,设置一下web.config文件,就不会出现这些注册信息了:http://kendezhu.iteye.com/blog/752240。

前面说了,控件就是一些特殊的类,而我们在cs页面类敲出某个控件的id时,就相当于敲出了其实例(早在我们将控件拖入页面时,该控件就在cs页面类里实例化了,并且该实例化是在cs页面类内直接实例化的,而不是在方法里面实例化的),我们可以在id旁的智能提示里看到该控件是什么命名空间的什么类  类的实例所在的类及类的实例名(这里是控件id)。但有一点要清楚:本类不能在类下直接实例化,因为当该类实例化时里面还有一个本类的实例化,会导致web服务器关闭,可以在类的事件或方法里实例化,或直接用this(this指的是当前类的实例);其子类一样不能在类下直接实例化,因为子类继承了父类除构造函数和析构函数以外的所有东西;其父类可以在类下直接实例化,因为其父类"范围"比它小;其他不相关的类可以在类下直接实例化(这就是控件类的情况)。

下面我们来讲子类访问父类私有变量的问题:

1.将子类的对象作为参数传入父类的方法内,在父类的代码内部就可以通过子类的对象访问父类的Private成员了

子类:

        public class Class1:_Default

    {

        public string sss;

    }

父类:

        public partial class _Default: System.Web.UI.Page

    {

        private string xx = "xxxx";

        public void FangwenPrivate(Class1 cl,out string s)

       {

            s = cl.xx;

       }

        protected void Button1_Click(object sender, EventArgs e)

       {

            Class1 class1 = new Class1();

            FangwenPrivate(class1, out class1.sss);

            Label2.Text = class1.sss;

       }

    }

注意参数前面的out。该处使用了引用传递,只有这样才会改变实参class.sss的值,我们在Label2里才会看到改变后的

class1.sss的值。而我们经常使用的是值传递,无法改变实参的值。引用传递的另外两个关键字是ref和params。值得注意的是无论调用该函数还是原函数都应该在相应位置写明out,ref或params。

关于ref与out的区别:http://www.cnblogs.com/xuezheng/archive/2007/08/20/862769.html

再加上params:http://www.cnblogs.com/greatandforever/archive/2010/04/07/1706001.html

2.这种方法不光是面向有继承关系的类,对任两个类都起作用(一个类的公有方法返回值是该类的私有变量,另一个类调用该类的公有方法):

一个类:

            public class Class2

         {

             private int i;

             public int Getint()

          {

             return i;

          }

        }

另一个类:

               public partial class _Default: System.Web.UI.Page

           {

 

 

               protected void Button1_Click(object sender, EventArgs e)

               {

                      Class2 class2 = new Class2();

                      Label2.Text = class2.Getint().ToString();

                }

           }

3.这种方法也是对任两个类都起作用(在一个类中给私用变量指定一个属性)

一个类:

       public class Class2

    {

        private int i=2010;

        public int I

        {

            get { return i; }

            set { i = value; }

        }

     }

另一个类:

            public partial class _Default: System.Web.UI.Page

           {

 

 

               protected void Button1_Click(object sender, EventArgs e)

               {

                      Class2 class2 = new Class2();

                      Label2.Text = class2.I.ToString();

                }

           }

说到属性,很多书中说其是字段的扩展,我们也可以在vs中用封装字段的来给一个字段添加属性.但其实属性就是一种特殊的方法,它可以跟字段没有任何关系,如http://kendezhu.iteye.com/blog/749036后面个性化WebPart属性里那样用属性。再如:

             public string Attr   

        {

            get { return Label1.Text; }

            set { Label1.Text = value; }

        }

           protected void Button1_Click(object sender, EventArgs e)

        {

            this.Attr = TextBox1.Text;

             TextBox2.Text=this.Attr;

        }

前面说了属性就是一种特殊的方法,this.Attr=TextBox1.Text;设置属性就相当于调用了该属性里的set方法,参数是TextBox1.Text,然后方法里的局部变量就是value(是隐式定义的),这样就把值传给了Label1.Text。 TextBox2.Text=this.Attr;访问属性就相当于调用了属性里的get方法,直接返回值。

 

以前一直不明白为什么要封装字段搞出个属性来,直接把字段设置为public不就完了吗?看一下下面的例子也许会明白:

        private int attr;

        public int Attr1

        {

            get { return attr; }

            set {

                if (value < 0)

                {

                    value = 0;

                }

                attr = value;

            }

        }

          protected void Button1_Click(object sender, EventArgs e)

        {

            this.Attr1 = -1;

        }

可以看出通过字段的属性可以避免对字段进行一些错误的赋值,当然这只是一个方面,等发现其他作用,偶还会及时更新上来。

你可能感兴趣的:(.NET)