• C#面向对象的概念


    在前面的学习中,我间接提到了一些关于方法,类和面向的对象的一些概念,但是所描述的概念并不是很专业,并且很肤浅。也是鉴于本人水平并不高,如果哪里有错误,也请大家具体指出。

    起初我刚接触到面向对象这个概念时候,感觉和PLC中写的FB块很像,就是将一些数据,和一下业务逻辑封装到一起,组成一个方法

    方便我们重复的使用。稍微有点不同的是,C#中的方法依存于类中,我们要在类中创建方法才有意义。

    我们把这些具有相同属性和相同方法的对象进行进一步的封装,抽象出类的概念。类就是个模子,确定了对象应该具有的属性和方法。对象是根据类创建出来的。

    所有面向对象的编程语言,都是我们吧要处理的“数据”和“行为”(方法)封装到类中。

    类的语法

    [public] class 类名

    {

        字段;

        属性;

        方法;

    }

    写好一个类后,我们需要创建这个类的对象,这个过程为类的实例化。this关键字表示当前类的对象。

    创建流程如下:

    1.设计类:就是根据需求设计各种类,为每一个类设计对应的“数据存储”和“操作内容”

    2.关联类:我们所设计的对象,他们之间是有一定关联的,正是按照这种关系,完成对象的交互。

    3.使用类:根据我们的需要,使用我们所设计的类,使用的时候通过对象的方式调用。

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 草稿
     8 {
     9     public class Person
    10     {
    11         public string _name;
    12         public int _age;
    13         public char _gender;
    14 
    15         public void CHLSS()
    16         {
    17             Console.WriteLine("我叫{0},我今年{1}岁了,我是{2}生,我可以吃喝拉撒睡~~~",this._name,this._age,this._gender);
    18         }
    19     }
    20 }
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 草稿
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             //创建对象
    14             Person LXB = new Person();
    15             LXB._name = "LXB";
    16             LXB._age = -23;
    17             LXB._gender = '';
    18             LXB.CHLSS();
    19             Console.ReadKey();
    20         }
    21     }
    22 }

    类是不占内存的,对象是占内存的。我们在仔细观察上面程序,在实际变成当中,年龄是不许有负数的,是非法的。这时,我们需要引入属性这个概念,他的作用就是保护字段,对字段的赋值和取值进行限定。创建对象要在方法中。

    属性的语法;

    public string Name

    {

        get{return _name;}

        set{_name=value;}

    }

    属性的使用:

    作用:在OOP中主要用来封装数据。

    要求:一般采用Pascal命名法,数据类型和字段要一致,使用public修饰。

    其实C#发展至今,属性的语法写法如下:

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 草稿
     8 {
     9     public class Ticket
    10     {
    11         //C#2.0时代标准属性
    12         private double _distance;
    13 
    14         public double Distance
    15         {
    16             get { return _distance; }
    17             set { _distance = value; }
    18         }
    19 
    20         //C#3.0时代,对标准属性做了简化(以后,标准属性,都可以这样用)
    21         public int Price { get; set; }      
    22 
    23         //C#4.0时代,增加属性表达式(下面写法不常用)
    24         private double unitPrice=4000;
    25         public double UnitPrice { get => unitPrice; set => unitPrice = value; }
    26 
    27         //C#4.0时代以后,可以直接赋值。
    28         public string Type { get; set; } = ".Net开发系列";
    29 
    30     }
    31 }

    在这几种方法中,没有显示写出对应的私有字段,编译器都会帮我们自动生成。可以通过reflector查看。

    属性的本质就是两个方法,一个叫get(取值)一个叫set(赋值)。在我们实际应用中,不是所有属性都有get和set方法,要过呢据实际情况而定。外界不能随便访问到我们的字段,所以更改如下

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 草稿
     8 {
     9     public class Person
    10     {
    11         private string _name;
    12         public string Name
    13         {
    14             get { return _name; }
    15             set { _name = value; }
    16         }
    17 
    18         private int _age;
    19         public int Age
    20         {
    21             get { return _age; }
    22             set
    23             {
    24                 if (value<0||value>100)
    25                 {
    26                     value = 0;
    27                 }
    28                 _age = value;
    29             }
    30         }
    31 
    32         private char _gender;
    33         public char Gender
    34         {
    35             get { return _gender; }
    36             set { _gender = value; }
    37         }
    38 
    39         public void CHLSS()
    40         {
    41             Console.WriteLine("我叫{0},我今年{1}岁了,我是{2}生,我可以吃喝拉撒睡~~~",this.Name,this.Age,this.Gender);
    42         }
    43     }
    44 }
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 草稿
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             //创建对象
    14             Person LXB = new Person();
    15             LXB.Name = "LXB";
    16             LXB.Age = 23;
    17             LXB.Gender = '';
    18             LXB.CHLSS();
    19             Console.ReadKey();
    20         }
    21     }
    22 }

    当我们创建好一个类的对象后,要给这个对象的每个属性去赋值,这个过程叫对象的初始化。

    读取:属性通过get方法,返回私有字段。

    赋值:属性通过set方法,借助value给私有字段赋值。

    本质:属性本身其实并没有保存数据,而字段才是真正数据的存储单元。在属性get和set方法中添加业务逻辑。

    对象创建,成员变量的定义,可以在类中直接定义。但是对象属性的使用,方法的调用,必须放到方法中。 

    总结:属性和字段

    字段(成员变量)

    (1)内部使用:字段主要是为类的内部数据交互使用,字段一般为private.

    (2)数据存储:字段只是用来存储数据,如果不是静态数据,生命周期和对象共存亡。

    (3)读写不限:我们可以给字段赋值,也可以获取字段的值(readonly除外)。

    属性(字段封装)

    (1)外部使用:属性一般是向外提供数据访问,属性是public修饰,用来对外表示对象的静态特征。

    (2)业务扩展:属性内部可以添加我们需要的业务逻辑,可以避免非法数据,或完成其他相关任务。

    (3)读写可控:属性可以根据需要设置为只读属性,更好地体现面向对象的“封装特性”!也就是安全性!

    使用

    (1)常规化使用:对象本身的“对外”数据保存,都是通过属性完成的,调用者都可以使用

    (2)强制性使用:公有化字段,在很多时候是无法被解析的。(比如dgv,combobox的显示问题)。


    静态方法和非静态方法区别

    (1)在非静态类中,既可以有实例成员,也可以有静态成员。

    (2)在调用实例成员的时候,需要使用对象名.实例成员。

         在调用静态成员的时候,需要使用类名.静态成员名。

    总结:静态成员必须使用类名去调用,而实例成员使用对象名。静态函数中,只能访问静态成员,不允许访问实例成员。

    1)如果想要将你的类当作一个“工具类”,可以考虑将类写成静态类。

    2)静态类在整个项目中资源共享。(静态存储区)只有在程序全部结束轴,静态类才会释放资源。

    在给对象初始化的时候,我们可以用构造函数。

    构造函数是一个特殊的方法

    (1)构造函数没有返回值,连void都不能有。

    (2)创建对象的时候会执行构造函数。

    (3)类当中会有一个默认的无参的构造函数,当你写一个新的构造函数之后,不管有参无参,那个无参的构造函数都会被干掉。

    this关键字的作用:

    1.代表当前类的对象。

    2.在类当中显示嗲用本类的构造函数。:this

    析构函数的概念:

    当程序结束的时候,析构函数才能执行。帮助我们释放资源。

    下面我们做一个练习:写一个Ticket类,有一个距离属性(只读),在构造方法中赋值。不能为负数,有一个价格属性,并根据距离distance计价Price(1元/公里)

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 草稿
     8 {
     9     public class Ticket
    10     {
    11         private double _distance;
    12 
    13         public double Distance
    14         {
    15             get { return _distance; }
    16         }
    17 
    18         private double _price;
    19 
    20         public double Price
    21         {
    22             get
    23             {
    24                 if (_distance>0 && _distance<= 100)
    25                 {
    26                     return _distance * 1.0;
    27                 }
    28                 else if (_distance>=101 && _distance<200)
    29                 {
    30                     return _distance * 0.95;
    31                 }
    32                 else if (_distance>=201 && _distance<300)
    33                 {
    34                     return _distance * 0.9;
    35                 }
    36                 else
    37                 {
    38                     return _distance * 0.8;
    39                 }
    40             }
    41         }
    42 
    43         public Ticket(double distance)
    44         {
    45             if (distance<0)
    46             {
    47                 distance = 0;
    48             }
    49             this._distance = distance;
    50         }
    51 
    52         public void ShowTicket()
    53         {
    54             Console.WriteLine("{0}公里需要{1}元",Distance,Price);
    55         }
    56 
    57 
    58     }
    59 }
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace 草稿
     8 {
     9     class Program
    10     {
    11         static void Main(string[] args)
    12         {
    13             Ticket t = new Ticket(90);
    14             t.ShowTicket();
    15             Console.ReadKey();
    16         }
    17     }
    18 }

     C#构造方法的补充

    构造方法的作用:

    因为构造方法是在对象创建的时候被调用的,所以,我们在创建的时候,可以完成一些初始化的任务。

    初始化:包括给对象的属性赋值,或从其他对象,文本等获取基础数据。

    构造方法的类型:

    (1)无参数的构造方法:一个类中,如果没有显示的写出构造方法,编译器会默认生成一个无参的构造方法。我们也可以 随时显示添加一个无参数的构造                        方法。通常是用来直接初始化对象的属性或“某些不变的数据”。

    (2)有参数的构造方法:让对象创建者,自己传递要初始化的相关数据。

    对象初始化器的使用

    引入:C#3.0时代开始

    作用:更加灵活的初始化对象的“属性”

    语法:

     对象类型 对象名=new 对象类型()

    {

           成员名1=value1,

           成员名2=value2,

    }

    构造方法

    1)存在的必要性:一个类中,至少要有一个构造方法。(可以无参数,也可以有参数的)

    2)调用的特殊性:只能在对象创建的时候,通过new关键字调用。

    3)使用的强制性:对象的创建,必须调用指定的构造方法,也就是参数必须统一。

    4)语法的特殊性:不能有返回值,构造方法必须和类名一样。

    构造方法PK对象初始化器

    相同点:都可以完成对象“属性”初始化

    不同点:1.有无强制性:构造方法有强制性,对象初始化器没有强制性,随意使用。

            2.使用的范围:对象初始化器只能完成属性初始化,而构造方法可以完成任何需要的初始化任务。

            3.使用的位置:对象初始化器在创建对象的时候使用,而构造方法必须提前写在类中。

            4.出现的时间:构造方法在.Net1.0版本就有,而对象初始化器只能在.Net3.0以上版本才能使用。

    注意:成员变量和局部变量同名时,一般实就近原则取变量,如果我们舍近求远,则必须添加this。


    对象的生存周期

    对象在内存中不断的“生生死死”,具有生命周期。

    对象在内存中的状态

    正在引用:程序正在使用对象。

    游离状态:没有引用对象,已经使用完毕但依然占用空间。

    我们可以显示的清除对象的引用,也就是仅为一个变量名,没有具体对象指向。对象名称=null

    托管运行环境下对象的销毁由虚拟机负责,析构函数没多大用途。

  • 相关阅读:
    面试中要注意的 3 个 JavaScript 问题
    angularJS遇到的坑
    为什么你的前端工作经验不值钱?
    ceph pg常见的几种状态
    k8s网络之flannel
    k8s流量访问之service
    lvs+keepalived高可用
    iptables【学习笔记】
    Linux和OpenStack中的网络知识【学习笔记】
    服务器BIOS设置
  • 原文地址:https://www.cnblogs.com/LiyuLi/p/12166549.html
Copyright © 2020-2023  润新知