面向对象概述
三个重要概念:类(重要)、对象(重要)和实例化(将类创建为对象的一个过程)。
保留关键字:this关键字。
什么是对象:对象是一个抽象概念,英文叫Object,表示现实中任意存在的事物。
eg:杨工是人类的一个对象。

对象的概念:对象是人们要进行研究的任何事物。
两台车就是两个对象,有各自基本特征和他们的动作。

对象的组成
对象分类:
静态部分(属性)
动态部分(行为)
什么是类:
车是对象,有自己基本特征及行为。从基本特征和行为抽象出(产地、颜色、行为(行驶)--封装基本思想。
封装
在使用电脑时候只需要敲击键盘电脑操作就行,不需要知道计算机里面如何工作,只知道用键盘操作就行。
面向对象(封装)思想基本提现:对客户实现隐藏细节,只要操作他的表面就可以。主要是通过类进行封装,为用户提供对象的属性和行为的接口,用户通过这些接口使用这些类,不需要知道类的内部结构怎么样。
继承
解决代码复用问题。
信鸽送信:信鸽属于鸟类,信鸽肯定与鸟类有相同的属性和行为,创建一个信鸽类,将这个鸟类拿来复用,保留鸟类所具有的属性和行为。并不是所有的鸟都具有的属性和行为,可以在信鸽类里面定义一些独特的属性和行为。信鸽类保留鸟类属性和行为。节省定义鸟类和信鸽类共同的属性和行为的时间。 --继承基本思想。
软件代码使用继承思想可以缩短软件的开发时间,可以复用那些已经定好的类,提高系统的性能,减少系统在使用过程中出错的几率。继承主要是使用的是特定对象之间的一些共有的属性。
定义图形类:定义图形类共有的属性,定义其它图形的时候(比如三角形、四边形或多边形时候都可以继承这个图形类,把图形类中定义的所有的图形共有的一些属性和行为给继承下来,在这些类不需要定义共有的属性。 定义具体图形:等边三角形、等腰三角形可以继承三角形类,把三角形图形共有的一些属性给继承下来,不用在重复定义了。 同样道理:定义正方形、平行四边形的时候可以直接继承四边形类,免去定义四边形公有属性的代码,提高程序开发效率。
---继承基本思想
继承主要体现代码复用的特性。
继承两个主要概念:父类和子类。
初始类叫父类,继承类叫子类,子类下面也可以有子类,子类在一定程度上也可以称作父类。三角形类四边形类可以叫做等边三角形、等腰三角形的父类,同时又是图形这个类的子类。
多态
概念:将父类对象应用于子类特征。
猫狗羊三个类都是哺乳动物,哺乳动物相当于一个父类,下面的猫狗羊属于它的子类。如何通过哺乳动物这个类确定各种动物的叫声呢?每一种动物叫声不一样用多态。
多态主要特征:以父类身份出现,以自己的方式来工作。
直接通过父类这个对象直接调用子类的方法来实现各种动物的叫声。 --多态基本思想,面向对象编程里面得到充分体现。
面向对象三个基本特征:封装、继承、多态。

面相对象与面向过程编程的比较
面向过程编程
主要思想:先做什么、后做什么。
在一个过程中实现特定功能时可以把一个过程分成各个模块,各个模块又可以按功能进行划分。组合在一起形成一个特定的功能。
各个模块可以是整个行数,也可以是整个原文件。

通过变量、函数来进行实现。
面向过程的缺点:
1.软件重用性(同一事物不经过修改或稍加修改就可以多次重复使用的性质)差,软件重用性是软件功能追求的主要目标之一。面向过程编程中每一个模块都是独立的,当软件发生改变时整体结构也需要改变。如果使用面过编程的软件,前期开发的时候肯定不能得到充分的再利用。
2.软件可维护性差主要是重用性差导致的,由于重用性差造成维护的时候费用和成本较高,大量修改代码也可能存在未知的漏洞,需要重复进行测试。
3.稳定性差,面向过程编程往往会描述软件的具体层,会针对不同领域设计不同的结构及指针,当用户需求发生变化时只需要修改最底层的结构,导致他稳定性无法保证。
面向过程编程语言:C、Bsaic
面向对象编程:
以对象为核心,在对象里封装属性和行为,

建模主要是通过对象抽象出类,通过类定义属性和方法,再选择面向对象语言执行求解。
抽象各种对象时已经在实现功能了,各个对象完成后整体的工作任务也完成了,大大降低程序开发人员的工作难度,降低出错的机会。
面相对象编程优点:
1.代码容易修改(面向对象编程代码大多封装在类里面,类的某个属性发生变化时,只需要修改类中的属性成员就可以,其它都不用动。)
2.代码复用性高,面向对象编程的类都具有特定功能的封装,如果想要使用类中的特定功能只需要声明类的对象然后用它封装的方法就可以实现,如果需要的功能不再同一个类还可以通过继承提高代码的复用性。
3.满足用户的需求,由于面向对象编程代码复用性高当用户需求发生变化时只需要修改发生变化的这个类,功能没有发生变化的类就可以直接拿来使用,可以及时响应用户需求变化。
面向对象和面向过程的区别(面对相对于面过几个主要的优点):
(2)--通过类来体现。


eg:现在面临一只大雁要从北方飞往南方这样一个实际问题,尝试以面向对象的思想来解决这一实际问题。
类的概念
面相对象编程的核心内容。
主要内容:类的概念、类的声明、类的数据成员、类中构造函数和析构函数、对象的创建及使用、this关键字(类中保留关键字)、类与对象的关系。
类的基本概念:
类是一种数据结构,可以包含数据成员【变量和常量都是类的成员】(常量和域)、函数成员(方法、属性、事件、索引器、运算符、构造函数和析构函数)和嵌套类型。
类(class):实际上是对某种类型的对象定义变量和方法的原型,表示对现实生活中一类具有共同特征的事物的抽象(记) ,是面向对象编程的基础。
现实世界中水果时一个类,苹果、香蕉、葡萄是水果这个类中的一个子类,
类是同一类事物的统称,如果将现实世界中的一个事物抽象成对象,类就是这类对象的统称。


cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 类
{
internal class Program//创建完一个C#程序后会自动生成一个类,在这个类里面自动有一个Main方法,Main方法就是类里面的成员,
{
int i = 0;//讲变量常量时int i=0;i 就属于是这个类中的成员
const double PI = 3.14; //常量也是同样的道理 定义的常量PI也是类中的成员,
static void Main(string[] args)
{
int i = 1;
Console.WriteLine(i);
}
}
}
类的声明
声明类用class关键字。
class 类名 //类修饰符 类的名称
{
类中的代码
}
类修饰符:主要用来控制类的访问范围。(类可以定义为公有的(也就是所有的都可以访问它);也可以定义为私有的不允许别的类再来访问它。)
标准类的声明:
第一行:类修饰符--公有的 声明类的关键字 类的名称(只要符合前面讲的标识符命名规则就可以随便定义。)
大括号里面:类的内部可以声明类的成员。
类的成员



访问权限修饰符
public:公有的。 不限制对该类的访问。
private:私有的。 只有其所在类才能访问。
protected:受保护的。 只能从其所在类和所在类的子类(派生类)进行访问。
abstract:抽象类。 不允许建立类的实例。
sealed:密封类。 不允许被继承。
new:仅在嵌套类生命时使用,表明类中隐藏了由基类继承而来,与基类成员同名的成员。
internal:同一程序集的任何代码都可以访问。
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 类
{
class Program//创建完一个C#程序后会自动生成一个类,在这个类里面自动有一个Main方法,Main方法就是类里面的成员,class必须有是声明类的关键字。 Program是类的名称。
{
int i = 0;//讲变量常量时int i=0;i 就属于是这个类中的成员
const double PI = 3.14; //常量也是同样的道理 定义的常量PI也是类中的成员,
static void Main(string[] args)
{
int i = 1;
Console.WriteLine(i);
}
}
}
构造函数和析构函数--类的两个特殊成员
类中比较特殊的两种成员函数。 --主要是对对象进行初始化和回收对象的资源。
对象的生命周期从构造函数开始,到析构函数结束。
构造函数
创建给定类型的对象时执行的类方法,构造函数具有与类相同的名称,它通常初始化新对象的数据成员。
中间是一对构造函数的内容。
构造函数program跟类的名称一样,前面加一个修饰符。




析构函数
类名加~来命名。
~ +类的名称()
{
大括号内是:析构函数内容 //为了看清楚析构函数自动调用后的的调用效果,在析构函数里面编写了一条输出语句。
}
析构函数一般不用手动来编写都是自动来调用,主要功能是资源的回收
下面的代码:代码中使用Program创建了一个类的对象,并没有进行任何的输出,但由于构造函数中有一个输出语句,所以自动输出构造函数i的值为10。
析构函数为什么没有输出:代码中创建完Program对象后写了CRL()方法,这个方法代表程序并没有完成执行,所以就没有调用析构函数。
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 构造函数和析构函数
{
class Program //Program是一个类
{
int i = 0;//定义int i=0;
public Program()//编写构造函数
{
i = 10;//重新给i赋一个值
Console.WriteLine(i);//重新输出它的值
}
~Program()//定义一个析构函数
{
Console.WriteLine("析构函数");//看清析构函数自动调用效果写一条输出语句
}
static void Main(string[] args)
{
Program pro = new Program();//创建类的对象 pro是对象名称 new关键字创建类的对象 //这样就创建了一个类的对象
Console.ReadLine();
}
}
}
如果复制到析构函数里创建一个构造函数的对象,之后就没有其它任何操作,.Net会自动调用析构函数进行垃圾回收。 注:为什么闪了退?调用析构函数,由于析构函数会执行一个垃圾回收功能,默认程序已经执行完,输出析构函数读取下一行字符就自动关闭程序。

注:实际开发程序中析构函数一般不用自己写,会自动执行垃圾回收功能。
实际开发中最常用到构造函数,析构函数一般不用自己编写。



属性
数据安全性问题
这是刚才创建student类,在类里面定义name字段和age字段,在使用类age字段时候可以直接对其进行赋值,但赋值的时候可以赋值成-2没有问题。
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 属性__数据安全性问题
{
internal class Program
{
class Student//创建Student类
{
public string name;
public int age;
}
public enum MRKJ
{
CS,
C,
Java,
}
class program
{
static void Main(string[] args)
{
Student stu=new Student();//Main方法使用时创建类的对象用new关键字来创建
stu.age = -2;//调用age字段赋值成-2
Console.WriteLine(stu. age);//可以正常输出但-2年龄是非法数据
Console.ReadLine();
}
}
}
}
-2是非法数据,年龄不是-2;有时候将类中的字段公开是不安全的因为可以随便进行赋值,即使不合法数据编译器也识别不出来。
把age设置成private,问题是在其他地方使用就访问不了。因为设置成私有只能在Student这个类里面进行访问,下面会出现红色波浪线不可访问,因为受保护级别限制。
设为private会导致:无法正常赋值和无法获得数据。
属性定义:属性是对现实实体特征的抽象,提供对类或对象的访问。
主要描述类或对象的实体特征。
C#中定义属性:
定义一个字段,通过属性来操作字段,{}里是指定属性,,定义get和set,get是获取,return是返回字段的值。set用于设置,隐含参数是value。
定义属性:修饰符 类型(跟字段类型一致) 属性名称(定义get和set访问器,分别获取字段的值和给字段设置值)
get和set不是必须有。
只有get:只能获取值。
只有set:只能赋值不能获取值。
都有是读写属性,既可以获取又可以赋值。
使用属性控制年龄输入范围
第一行:只能在当前类中使用,
下面定义Age属性,这个属性用来操作age字段
get访问器返回age获取它的值,set访问器设置age取值范围,只能取0-100之间范围,超出范围后会把他的默认值设置为18,属性设置成公有的,set访问区保护内部数据安全。
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 使用属性控制年龄输入范围
{
internal class Program
{
class Student//创建Student类
{
public string name;
private int age;//age字段定义成私有
public int Age//定义公有类型和age一样
{
get { return age; }
set//设置age字段取值范围 用隐含参数value
{
if (value > 0 && value < 100)//如果vlaue>0并且value<100才正常给age字段赋值
age = value;
else
age = 18;//如果超出范围给age字段设一个初始值
}
}
}
public enum MRKJ
{
CS,
C,
Java,
}
class program
{
static void Main(string[] args)
{
Student stu = new Student();
stu.Age = -2;//给age属性赋值再赋值-2 输出Age属性
Console.WriteLine(stu.Age);//可以正常输出但-2年龄是非法数据
Console.ReadLine();//初始化为默认值18 如果输入0-100之间比如80就是输入80
//通过属性保护内部数据安全
}
}
}
}
属性特点:
1.封装字段,将类中的字段与属性绑定到一起。
2.避免非法数据的访问。 比如设置成-2
3.保证数据的完整性。
使用属性需要注意的地方: --(属性的使用错误)
第一段代码:
代码定义一个类,在这个类定义两个私有字段,定义两个属性来操作来操作两个字段。
定义id是get访问器。
第二段代码:创建类的对象,通过对象调用属性进行赋值。 --这段代码错误
设置id属性使用对象调用id访问器由于进行赋值必须用到set访问器才能进行赋值,所以会发生错误。如何改正:加一个set访问器就可以赋值。
都存在才能进行读写操作。

方法--类的另外一种非常重要的成员
为什么要使用方法?方法的声明?方法的参数?方法的重载?
方法:用来定义类可执行的操作,定义人这个类--说话行为定义一个方法,唱歌行为定义一个方法,吃饭行为定义一个方法。
为什么使用方法?--税率
计算缴税--有规律和重复额代码通过方法来进行封装。
方法基本概念:方法就是类的行为,便于修改、增加可读性、可重用、封装...
(声明类或结构中)
声明语法:

访问修饰符:前面讲的。
返回类型:任何数据类型都可以。
方法指定为void类型说明是无返回值方法。
方法名符合标识符命名规则就可以。
参数列表见上面~
有方法就可以将计算税后工资的重复性代码封装为方法。
自定义一个方法--访问级别在本类中访问
返回值是float类型
Getpay--方法名称
这里面两个参数传入税前工资及税率
没加访问修饰符默认private类型。
这段代码:
先定义一个方法,无返回值类型,方法参数列表没有直接省略,定义一对{方法要执行的代码 输出"学生姓名 Name属性 年龄 Age属性"}
定义完方法后在其他类中使用类的对象来访问方法,定义public在program这个类中Main方法里面创建student类的对象,使用student方法SI对象来输出信息。
定义成private只能在student类的内部使用,program调用提示不可访问--受保护级别限制,运行不能运行。
定义方法时未加访问修饰符提示错误,受保护级别限制,默认是private私有类型。
定义方法制定返回值比如int在方法体内使用return来返回int,否则会提示错误。并非所有代码路径都有返回值,因为定义一个返回值,必须使用return关键字返回int类型的值 0。定义string类型返回一个string类型的值。--定义方法需要注意的。
方法返回值问题
如果定义方法返回值一定要定义一个return返回相应类型的值。
方法的参数个数问题
定义一个返回值为int类型的Add方法,他有三个参数,Main方法中调用的时候调用Add只传入两个参数,如果遇到传入参数个数跟定义的参数个数不相同时候将出现这样的错误。
使用方法时传入的参数个数一定要跟方法中定义的参数个数相同,并且参数类型也要一致。定义int类型不能传入字符串值,否则就会出现错误。
方法的参数

1.参数全是int类型在参数个数确定情况下可以这样写
2.参数个数不确定使用params参数。
3.ref参数。
params参数
一维数组,主要来指定参数数目可变时使用的方法参数。
Add方法计算指定类型参数个数的和,由于参数个数不确定定义params参数和一个int类型的一维数组。第二行代码调用它时候可以直接传入一个值,也可以传入两个值,也可以传入多个值。
记说明
ref:引用参数。
out:输出参数。
只要传入int类型输入多少个都可以
cs
class program
{
int Add(params int[] x);//在program里面定义方法及返回值 计算多个int类型的和定义为params int一维数组
{
int result = 0;//定义int类型变量result记录结果
for(int i=0;i<x.Length;i++)//遍历params参数数组
{
result+=x[i];//result+=遍历到的元素
}
return result;//返回定义到的result变量
static void Main(string[] args)
{
Program pro = new Program();//使用它创建这个对象
pro.Add(new Student()); //传入任意参数计算两个数的和
//剩下未写完的见下面

//主要针对参数数目可变时使用params参数
3.交换两个数的值这样写,首先编写一个方法,方法中传入两个数num1和num2,通过一个临时变量来调换这两个元素的值,在Main方法里面调用这个方法--交换两个数的值最后输出。
实际运行效果一样说明不对。交换两个数值定义int类型,int类型按值传递,按值传递时对形参的修改并不会影响到实参。在方法小括号中定义的参数叫形参,方法体中定义的变量叫实参,对实参修改并不会影响到实参,并没有发生真正的改变。交换用ref参数来实现。
定义方法时在ref前加关键字,调用时也加ref关键字,这样运行出来的效果会发行变化。
值发生交换。

ref参数作用:可以使形参按照引用进行传递,即使形参是值类型也可以按引用进行传递。
效果:在方法中对形参做的任何更改都可以反应到实参里面,使用ref参数调用时就必须显示来制定ref关键字。
没加ref不能发生交换,加上ref调用这块不加ref会错误,需显示指定ref关键字,值发生交换。
两种传值方式比较,num1和num2初始值都是68,调用方法给num2指定ref关键字,说明num2可以按引用进行传递,调用num1和num2同时进行修改,输出的值num1不会发生变化,由于num2使用ref关键字它的值就会发生变化。第一种形式是值传递,第二种由于加了ref关键字会按引用进行传递。
ref参数使用注意事项:
1.参数列表中想对哪个参数进行引用传递时就必须给哪个参数加ref关键字,在一个参数列表后面加关键字,整个都会按引用传递。
2.ref关键字形参是什么类型传入实参也是什么类型。
3和4.见上。
方法中返回多个值--out参数
用来定义输出参数,会导致修饰的参数通过引用进行传递,
out和ref关键字不同:ref关键字传递之前必须进行赋值,使用out关键字定义的参数不用赋值就可以使用。因为out本身是输出参数,即使不赋值由于使用out进行修饰执行完方法之后out修饰的参数也会进行初始化,使用之前不一定非要要求进行初始化,
定义三个变量第三个变量没有赋值就输出是错误的。
使用out参数修饰这几个变量,调用方法使用out参数修饰z变量它就是正确的。
out参数作用:可以使用未经初始化变量。使用out参数可以在一个方法中返回多个值。
c用out修饰c是一个输出参数,Main方法创建Program对象定义int变量c不初始化,输出c的值会报错,如果调用Add方法加Add关键字可以输出c的参数。
返回多个参数借助out参数可以实现。
返回多个值使用out定义两个参数,如果flag等于0结果说明被录用,写原因 如果不是结果就是未录用写原因。 通过定义这个方法返回两个值,result和reason两个值都是用out参数来修饰。其他地方调用可以直接定义两个变量,方法传入进去返回链各个变量就是返回的两个值。
重载
int定义两个方法返回num1+num2的值,计算两个int值直接调用就行,两个doublie相加不能,不能转换。如果是double调用double类型方法,是其他调用其他类型方法,
什么是重载方法
定义两个同名方法,方法参数类型成double类型,计算两个double类型和。传入double自动调用double,传入int调用int类型形式,这样比较方便。
--通过重载方法。
如果不同方法判断传入参数类型再确定调用哪种方法。
重载方法两种形式:参数类型不同的重载;参数个数不同的重载。
program类里面调用sum方法,计算链各个数据类型时计算a+b,计算方法时
1-4为不同类型参数。
4以后第二种。
传入相应的值就行,调用哪种形式会自动来区分。
重载两种形式:参数类型不同和参数个数不同。
定义重载方法时一定不能只是返回值类型不同,参数类型或个数一定不相同才行。
对象的创建及使用
三个主要概念:类、对象、实例化。
将类创建为对象叫实例化。
闯将对象两种方法:
第一种:调用类的构造函数来创建。
第二种:构造方法里面有参数
使用Program类的构造方法创建Program类的对象并且命名一个名称
2.定义有参数构造方法定义z输出z的值使用Program创建一个对象,使用有参构造方法创建。使用int类型值传入50,定位窗体。
第一行10:无参构方输出的语句。
第二行20:参数里传入50,由于构造方法中重新赋值成20输出20的值。

构方和构造函数是一个意思。
两种创建对象方法:一种使用无参,一种有参。
访问对象属性和行为:首先使用构造函数或构造方法创建类的一个对象,然后使用对象名调用属性和方法就行。
访问对象属性和行为没有加static就可以直接使用对象的名称. 这种形式来使用。--智能提示有
如果加static可以直接使用。
静态方法加static关键字。通过静态属性和变量都可以加static关键字。
对象的引用
C#里面一切可以看做对象,操作标识符实质上是引用。
引用以这种方式来体现:
类名 引用名称
或
构造函数创建的引用名称
引用只是存放对象的一个内存地址,其实并不是存放一个真正的对象。--这种区别可以忽略掉。
book是Book这个类的一个对象,实际上book是包含Book这个对象的一个引用。
实际操作和1差不多,可以忽略这种区别。 book是对象也可以是一个引用。
对象的销毁
C#带自动销毁功能。
使用构造函数创建一个对象,在{}内可以使用,超过{}之后不需要做任何操作会被自动销毁。
类的静态成员--突出static关键字(知道该关键字用法就行)
很多时候不同的类成员需要对同一个变量进行操作,定义成静态成员。
水池入水口和出水口--水共享
操作都是水池中的水,水池中的水--共享变量。
程序中遇到共享变量定义成静态变量(static)
使用static修饰被称为静态。

static不能修饰常量。
静态成员好处:静态成员是属于类所有的,调用时,直接使用类名调用
输出:Console这个类调用的Write或WL方法,W和WL方法其实就是静态方法。
使用类名调用年龄属性,年龄属性也是一个静态成员,这种成员叫静态调用。
通过new关键字创建对象的这种方法,通过对象来调用类中的成员,这种叫实例调用。
静态调用主要是把类的成员加static关键字变类的静态成员直接使用类名来静态调用。
未加static关键字就是实例方法,实例方法调用时需要使用类关键字创建类的对象,然后通过对象调用相应方法。
如果加static查看代码使用对象调用会报错,说明当前方法已经变成静态方法。
前面都加static关键字,这时候使用Program这个类调用红色波浪线会消除。
Main方法默认静态的,静态方法调用静态成员时类名可以省略,前Program.删除掉程序不会出错。
静态成员属于类所拥有的,在调用时注意需要使用类名来直接调用。
类前加static关键字类变成静态类,静态类定义注意事项:

运行会报错,
下面属性、字段、构造函数、方法都是实例方法,下面都会报错。
改正:每一个静态成员前加static变静态成员,字段波浪线就会去掉。

如果把一个类定义成静态类,定义的成员一定都是静态的,不能定义实例成员。
this关键字--类中保留关键字

定义一个方法,方法中使用this.name调用类中定义的name变量然后赋一个参数中传入的name值。
开发环境:定义int变量i=0,在构造函数中使用i对他进行赋值,this.智能提示定义的所有成员都可以调用包括大写的ID属性都能调用,this相当于对象的一个名称。this.id=100;如果输出i的值肯定输出i的初始值0,这块使用this关键字调用的id进行赋值。
this关键字使用:
this相当于对象的一个名称,


Main方法使用this关键字进行调用,由于Main方法是static,使用this关键字无任何智能提示,表示类的对象引用,在其它非静态方法可以直接使用,
this在静态方法中不能使用,表示类中对象引用,在其它非静态方法可以使用。
定义方法没加static关键字使用this.来调用所有的成员,对它进行赋值每一个都可以进行调用。

类和对象的关系

人类可以看成一个类,我和你都是一个具体的对象。
封装的实现
按顺序结构执行下来的结果。
切葱花、做肉丝--看得见的属性,容易乱。
C#通过类和属性进行封装,用户就看不到属性和行为。
通过封装思想就可以把我和厨师封装成两个类,我是顾客只能让厨师做东西,厨师执行它自己的操作,厨师类回答叫什么名字,厨师切葱花只能执行切葱花操作。
使用电脑开发不需要知道底层CPU工作。
封装思想:
我直接访问厨师这个类无法访问,通过对象去访问。--封装思想
封装思想具体实现
封装:通过类将用户行为和属性进行封装起来
面向对象主要通过类来进行封装,通过对象调用类里面的属性和方法。
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 封装
{
class Test//C#中第一一个类,想计算两个数的和定义属性
{
public int X
{
get;
set;
}
public int Y//定义第二个属性说明是可读可写的两个属性
{
get;
set;
}
public int Add()//定义一个方法公有类型别人可以调用
{
return X + Y; //返回值
}
}
//定义一个类封装两个int类型参数表示两个加数,封装一个Add方法计算两个加数的和。
internal class Program
{
static void Main(string[] args)
{
Test test = new Test();//调用时候使用它建议的名称,默认构造函数创建它的对象。
test.X = 5;//给属性赋值
test.Y = 8;//第二个加数属性
int result = test.Add();//使用int类型变量来记录结果 使用Test对象调用封装的Add方法
Console.WriteLine(result);//输出result 可以执行--具体怎么相加不用关心细节,细节已经封装到上面的类里面。
//最简单面向对象封装思想提现(在实例里通过一个类封装两个加数,封装一个加法方法,具体怎么使用不用关心。只要结果就可以。
//其他地方可以调用这个类
}
}
}
继承
面向对象编程非常重要的特征之一,任何一个类都可以从另外一个类继承,C#里面只支持单继承不支持多继承(一次只允许继承一个类,不能继承多个类),多继承用接口。
继承的基本思想是基于某个基类(父类)的扩展,制定出一个新的派生类(子类),派生类可以继承基类原有的属性和方法,也可以增加原来基类所不具备的属性和方法,或者直接重写基类中的某些方法。(可以把人定义成一个基类,定义成某些公有的东西头发皮肤;定义一个小王类,小王类有自己的一个名字,有自己的一些特长,可以把基类的共同特征给继承下来,然后再编写特有的特征,也可以编写小李类、小刘类,都可以把人这个共有的特征给继承下来,然后再编写自己特有的特征。 --继承基本思想)
基类和派生类是继承中两个非常重要的概念,基类是父类,派生类是子类。
继承后用:后跟一个要继承的类
表示定义一个Test2类继承自Test类。示意图:
首先Test这个类就是基类或父类,Test类里有构造方法然后有Test类的一些特征。
Test2继承自test类时候,Test2中具有基类所具有的特征,还可以自定义自己的特征。 --继承基本思想。
cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 继承
{
class Program
{
static void Main(string[] args)
{
JHInfo info = new JHInfo();//Main方法创建进货类对象 使用new关键字创建它的对象
info.code = "0001";//对象名info调用
info.Name = "手机";//
info.JHid = "JH0001";
info.ShowInfo();//调用方法
Console.ReadLine();
}
}
class Goods//自定义一个商品类定义两个成员
{
public string code { get; set; }
public string Name { get; set; }//基类中定义商品编号和商品名称
}
class JHXI:Goods//定义一个进货信息类它继承自商品类
{
public string JHID { get; set; }//这个类中输出进货信息 定义一个进货编号
public void ShowInfo()//定义一个方法输出进货信息
{
Console.WriteLine("进货编号:{0} 商品编号{ 1} 商品名称{ 2}", JHID,code,Name); //输出进货编号用占位符表示 输出商品编号
}
}
}
//可以把商品信息输出出来,商品标号和商品名称其实是在父类中定义的成员,但由于进行继承可以访问这里面成员
//父类中定义成员用public公有访问,改成private再运行会报错,如果继承类中某个成员定义私有类型是不能被继承过来,改成protected运行也会报错,Main方法调用也会报错,
//code方法没报错,使用类继承时候可以继承protected或public成员,对于private成员不能被继承。如果放到方法里面在方法里进行赋值可以进行正常输出
code改成protected属性,同样在派生类里面可以访问code属性。在实现类的继承只能继承基类中protected成员或public成员,不能继承私有成员。
base关键字

基类中定义构造函数,在构造函数中对基类属性进行初始化,在派生类中继承基类构造函数可以直接用base来继承基类构造函数 base两个参数是基类的两个参数{把派生类中新的属性给初始化一下就行,基类属性不用在初始化,因为是继承自基类的构造函数}
--base关键字作用
继承中的构造函数与析构函数执行顺序(从下往上和从上往下)
基类--图形类
三角形类继承自图形类
定义两个派生类都继承自三角形类
在几个类都编写构造函数和析构函数:构造函数执行顺序:先执行上层基类构造函数,再执行一级派生类构造函数,最后再执行最下层派生类构造函数。
析构函数执行顺序:和构造函数相反。会执行最下层派生类析构函数,一层一层往上最后执行基类析构函数。
多态


基类定义虚方法使用virtual关键字,派生类中使用override关键字重写基类虚方法实现多态目的。
定义这个类,定义属性;在虚方法中定义Move方法后输出。
占位符表示车的名称可以移动传入Name属性。定义子类class火车类继承自刚定义的基类,在基类重写虚方法。弄完后按空格直接写出。
定义汽车类。
定义基类,基类中有一个虚方法,输出可以移动,定义两个子类都继承这个类,两个类中都是用override关键字对虚方法进行重写。
Main方法中创建它的对象,先创建基类,再创建子类对象。使用三个对象创建一个基类数组直接赋值,火车和汽车都继承这个类,创建基类数组直接赋值默认这个对象。使用三个对象名默认属性进行赋值。
三个对象创建对象数组默认使用第一个调用Move方法。

--会自动区分要调用的哪个方法--基类数组调用,类的多态性。
抽象类与抽象方法

不能实现:只能定义方法名称,无任何具体实现。
定义后重写

抽象方法无任何实现,抽象方法只能包含在抽象类里面,不能包含在其它的类里面。
密封类和密封方法(了解)
定义密封类或密封方法加sealed关键字。
定义sealed一定和override关键字同时出现。
重点了解继承、多态及抽象方法使用。
结构与接口
结构是一种值类型(类:引用类型),通常用来封装一组相关的变量,结构中可以包括构造函数、常量、字段、方法、属性、运算符、事件和嵌套类型等。结构实际是将多个相关的变量包装成为一个整体使用。在结构体中的变量,可以是相同、部分相同,或完全不同的数据类型。
C#中使用struct关键字来声明结构。
枚举:封装一组相关变量,里面变量完全相同。结构体中变量可以是相同、部分相同,或完全不同的数据类型。

定义Employee结构存储职工信息

定义结构,封装两个成员变量,定义构造函数,定义构造函数是构造函数必须有参数,否则会报错。在里面可以定义方法。
区别(结构与类)
结构是值类型,类是引用类型,传值方式不一样。
结构中定义成员变量不能进行初始化。
定义成员变量时不能赋值,定义构造函数时候必须有参数列表。在类里定义构造函数可以有参数列表也可以没有参数列表。