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

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

C#面向对象的概念

上一篇:ubuntu16.04更换清华源


下一篇:C#.Net ComboBox控件设置DropDownList之后背景颜色问题,以及发现的微软的一个BUG