(9)C#传智:类静态与非静态构造函数this与new(第9天)

Posted dzweather

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(9)C#传智:类静态与非静态构造函数this与new(第9天)相关的知识,希望对你有一定的参考价值。

一、类Class

    语法:

    [public] class 类名
    
        字段;//存储数据
        属性;
        方法;
    

    添加类:右击项目,添加->类
        或者:右击项目,添加->新建项->类
    类的后缀名以cs结尾,新建类后缀可加可不加(因vs会自动判断添加)
    
    类的实例化:new
    this:表示当前的类的对象,方便引用当前类的各成员.
    
    类是不占内存的,但是对象是占内存的(字段占内存)
    在.net内CLR中有2个内存管理区域:堆栈和托管堆,
        若是值类型,CLR会在堆栈里面分配一个内存给它,

int x =5;//注意这里是在堆栈,因为int是值类型

 若是引用类型如string,object等等,CLR会在堆栈里面分配一个引用的地址,而new一个对象时
    会在托管堆里面分配一块内存给这个引用,如 string s ="abc";它分成2步:
        1 string s; //先分配一个string的引用,并且并不指向任何托管堆的对象(内存)
        2 s = "abc"; //在托管堆里面分配一块string类型的对象实例的内存,并让s指向这块内存
    
    结构与类的区别:
        形式一样,但结构是面向过程,类是面向对象。两者皆可用this.
    


二、属性

    字段与属性的区别

        字段无法校正限定,比如:年龄可以直接赋值为-23,显然是错误的。
        属性专门对取值进行校正和保护,对"字段"进行限定,它并不存储数据。
    因此,字段应该在内部被保护一般用private;
          属性应该做好沟通工作,与外界进行通信来访问字段,一般public.
          所以:字段一般用在类的内部使用,属性一般供外部类访问。
    另外,字段值可以用作ref、out参数,而属性不能
    
    一个字段对一个属性进行清洗
    
    属性的本质:就是两个方法:set() get()
        set 人去设置这个值;     get 人去取这个值
    属性是中间商,它清洗数据,最终是设置到字段上。
    Field字段、Method方法、Property属性
    
    属性的方式:
    可读可写: 有get()和set()
    只读:    有get(),无set();
    只写:     无get(), 有set()
    
    例:定义类:

    internal class Person
    
        //字段
        private string _name;

        private int _age;
        private char _gender;

        //属性
        public string Name
        //本身无值,对数据清洗,最终用在了字段上
            get  return _name; //取值
            set  _name = value; //设值
        

        public int Age
        
            get  return _age; 
            set
            
                if (value < 0 || value > 100)
                
                    value = 0;
                
                _age = value;
            
        

        public char Gender
        
            get
            
                if (_gender != '男' && _gender != '女') return '男';
                return _gender;
            
            set
            
                if (_gender != '男' && _gender != '女') value = '男';
                _gender = value;
            
        

        //方法
        public void Instru()//此处不能加static否则引用变量也须为static
        
            //this可加可不加,
            Console.WriteLine("我叫0,今年1岁了,我是2生.", this._name, _age, _gender);
        
    

   使用类,实例化

    private static void Main(string[] args)
    
        Person suQuan;//声明,不分配空间
        suQuan = new Person();//实例化
        suQuan.Name = "孙全";
        suQuan.Age = -33;
        suQuan.Gender = '男';
        suQuan.Instru();

        Console.ReadKey();
    

  创建类后,实例化成为对象;对象赋初值,称对象的初始化.


三、静态与非静态的区别

    看是否有static,有则是静态的,否则非静态。
    
    1.非静态类中,可有静态成员,也可有非静态成员.
    
    2.调用实例成员时,使用:对象名.成员名; 
      调用静态成员时,使用:类名.成员名.
    
    3.实例方法(非静态方法),既可使用静态也可使用非静态成员。
      但是,静态方法只能使用静态成员。
      注意:静态类中只允许出现静态成员(字段、属性、方法)
    
    静态类不能被实例化。因为访问成员都是用的类名,实例化后对象访问没有意义。
    而且静态类在程序中始终保持一个单一的存储位置,与实例化后多个位置矛盾。

    internal class Person
    
        private static string _name = "大";//字段可静态/非静态
        private char _gender = '男';

        public static string Name //属性可静态/非静态
        
            get  return _name; 
            set  _name = value; 
        

        public void M1()
        //非静态方法,静态与非静态都可以访问
            Console.WriteLine("非静态,用对象名引用01", _name, _gender);
        

        public static void M2()
        //静态方法,只能访问静态成员
            Console.WriteLine("静态,用类名引用0", Name);
        
    


    实例化使用:

    private static void Main(string[] args)
    
        Person p = new Person();
        p.M1();
        Person.M2();
        Console.ReadKey();
    

    静态类的注意,所有成员全为静态:

    internal static class Student//静态类
    
        private static int _age;//静态字段
        //public string _name; 非静态,错误

        public static int Age//静态属性
        
            get  return _age; 
            set  _age = value; 
        

        public static void M1()//静态方法
        
            Console.WriteLine("静态类中的静态成员");
        

        //public void M2() 非静态,错误
        //
        //    Console.WriteLine("静态中的非静态成员");
        //
    

    静态/非静态在什么时候使用:

    1.若类当作工具类,可以考虑静态。(因为可以不用创建实例就可以使用了,方便)
    2.静态类在整个项目中资源共享。
      静态类在程序越少越好,因其占用内存,它只会在程序结束时才释放资源。
      内存中有三个区域:堆,栈,静态存储区域(存储公共变量)
      
    命名空间:逻辑上的概念,把不同的类划分到不同的命名空间,便于引用管理。
    assembly:程序集,在C#中一个项目表示一个程序集(exe/dll)。跨项目使用须引用另一个项目。
    internal :内部访问,表示在一个项目内(程序集内)可以自由访问。
    例:原程序集(项目一)

    namespace Common
    
        internal class A
        
            public void aa()
            
                Console.WriteLine("只能在本程序集,不能被跨程序集调用.");
            
        
        public class B
        
            public void bb()
            
                A a = new A();//本程序集内,正确
                a.aa();
            
        
      

   
    而另一程序集(项目二):

    using Common;//引用上面dll后,再导入库
    namespace TestWeb
    
        public class Test
        
            public void test_1()
            
                A a = new A();//错误,internal跨程序集了
                a.aa();
     
                B b = new B();//正确,由原程序集内的其它访问,未跨程序集
                b.bb();
            
        
       

 
    内部访问通常用于基于组件的开发,因为它使一组组件能够以私有方式进行合作,而不必向
    应用程序代码的其余部分公开。

    例如,用于生成图形用户界面的框架可以提供 Control和
    Form 类,这两个类通过使用具有内部访问权限的成员进行合作。 由于这些成员是内部的,
    它们不向正在使用框架的代码公开。
    
    protected internal 受保护的,内部访问
    一般一个成员或类型只能有一个访问修饰符,但使用protected internal组合时除外,
    它的访问仅限于从包含类“派生”的当前程序集或类型。

    即我们可以在本程序集中访问,也可以在其他程序集中继承访问。
 

    namespace Common
    
        protected internal class C
        
            public void cc()
            
                Console.WriteLine("受保护的,内部访问,只可在其派生中");
            
        
     
     
    namespace TestWeb
    
        public class TestA
        
            public void test_1()
            
                Common.C c = new Common.C();//错误,非派生
                c.cc();
            
        
        public class TestB : Common.C
        
            public void test_2()
            
                C c = new C();//正确
                c.cc();
            
        
     

   
        
    程序集的特性

    1.程序集是任何 .NET Framework 应用程序的基本构造块。例如,在生成简单的 C# 
      应用程序时,Visual Studio 创建一个单个可移植可执行 (PE) 文件形式的程序集,
      明确地说就是一个 EXE 或 DLL。
    2.包含描述它们自己的内部版本号和它们包含的所有数据和对象类型的详细信息的
      元数据。
    3.仅在需要时才加载。如果不使用程序集,则不会加载。这意味着程序集可能是
      在大型项目中管理资源的有效途径。
    4.可以包含一个或多个模块。例如,计划较大的项目时,可以让几个各个开发人员
      负责单独的模块,并通过组合所有这些模块来创建单个程序集。
    


四、构造函数


    创建对象,并可以在构造函数中对对象进行初始化(方便给属性赋值)。
    
    构造函数是特殊方法
    1.构造函数无返回值,连void也不能写(和类一样);
    2.构造函数的名称必须与类名一样。
    
    创建对象时,会执行构造函数;构造函数可以带参数,以便具体初始化各属性。
    
    构造函数可重载,以应对不同参数的情况。
    系统会给类一个默认的无参构造函数,但是一旦人为添加一个构造函数(无论是
    有参数还是没有参数),原默认的无参构造函数消失。
    


五、关键字New


    Person zs=new Person();
    上面New做的三件事:
    1、在内存中开辟一块空间;
    2、在开辟空间中创建对象;
    3、调用对象的构造函数进行初始化对象。
    
    因此构造函数必须是public,否则上面三个步骤无法完成,也就无法创建对象。
    
    对对象的数据进行清洗的三种方法:
    1.在属性的get()中;
    2.在属性的set()中;
    3.在构造函数中。
    这三种方法可以对数据进行校正保护。


六、关键字this


    this 在引用属性/字段时可以省略,但是若与局部变量相同时须用this来辨识。
    1.代表当前这个对象
    2.在类当中,显式地调用本类的构造函数  :this
      需指定那个构造函数,参数少的调用参数多的构造函数。
      这样重载的构造函数若有相似时,可利用this少写冗余代码。

    internal class Student
    
        private string _name;
        public string Name //属性不能用()
        
            get  return _name; 
            set  _name = value; 
        

        private int _age;
        public int Age
        
            get  return _age; 
            set  _age = value; 
        

        private char _gender;
        public char Gender
        
            get  return _gender; 
            set  _gender = value; 
        

        public Student(string name, int age, char gender)
        
            this.Name = name;//可省this
            Age = age;
            Gender = gender;
        
        public Student(string name) : this(name, 0, '男')
        
        
        public Student(string name, int age) : this(name, age, '男')
        
        

        public void SayText()
        
            Console.WriteLine("我叫0,今年1岁了,是2生", Name, Age, Gender);
        
    


    主函数中调用:

    private static void Main(string[] args)
    
        Student s = new Student("张三");
        s.SayText();//张三,0,男生
        Console.ReadKey();
    

以上是关于(9)C#传智:类静态与非静态构造函数this与new(第9天)的主要内容,如果未能解决你的问题,请参考以下文章

C#图解教程 第六章 深入理解类

静态类的静态方法与非静态类的静态方法 (C#)

C# 一些知识点总结

静态方法与实例方法

不可变类的静态与非静态方法

C#类的初始化顺序