温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

[C#学习笔记] 面向对象

发布时间:2020-10-26 01:46:20 来源:网络 阅读:231 作者:haixin3036 栏目:编程语言

编写程序只不过是对象堆砌而成的,这些对象可以是独立的,也可以是从另外一个对下岗继承过来,对

象之间可以传递消息,并通过消息来改变自身的状态.

类是对象的模板.即类是对一组由相同数据和相同操作的对象的定义,一个类所包含的方法和数据描述

一组对象的共同属性和行为.类是在对象之上的抽象,对象则是类的具体化. 类可以有其子类,也可有

其他类,形成类层次结构.

类是对具有相同属性和行为的一组形似的对象的抽象.


面向对象的基本特征: 封装,继承,多态

Object是所有的类的基类.


定义类与创建类的对象

class Myclass{

//类的主题

}


★★★★类的修饰符

在定义类是,可以在类的前面添加访问修饰符,类的修饰符用于控制被访问的范围.默认情况下,类的修


饰符为private

new仅允许在嵌套类定义时使用,以表明类中隐藏了由基类中继承而来的与基类中同名的成员


public类可以在任何地方访问


protected只能从所在类和所在类的派生出来的子类进行访问,不能实例化,只能继承.



★★★★创建类的对象

MyClass myclass = new MyClass();


结构的定义:

结构与类相似,主要区别在于:类是存储在堆上的引用类型,而结构式存储在堆栈上的值类型,以及访问


方式和一些特征(例如:结构不支持继承);


定义结构:

在语法上,定义结构和定义类非常相似,主要区别是定义结构使用struct关键字代替class关键字.对于


类和结构,都是用new关键字生声明实例


struct FirstStruct{  //声明结构

//代码

}

FirstStruct first = new FirstStruct(); //实例化结构


类的数据成员:

构造函数,析构函数,常数,字段,方法,属性,索引器,运算符,事件,委托,类,接口,结构.


方法:

public string FangFa(){

return "返回值";

}


public void FangFa(){

Message.Show("无返回值");

}




★★★★ref关键字

可以通过引用为方法传递参数,不过若通过引用为方法传递参数,需要使用ref关键字.

string sex ="www";

Person  p = new Person();

string name = p.GetName(ref sex);  //这里将会把sex值改为女

Console.WriteLine("");


class Person {

public void GetName(ref string sex)

{

sex="女";

}

}


★★★★out关键字

out关键字和ref关键字很相似,out关键字也会导致参数通过引用来传递.与ref关键字不同之处在于


ref要求变量必须在传递之前进行初始化.如果使用out关键字,方法定义和调用方法都必须显示使用


out关键字.尽管作为out参数传递的变量不必再传递之前进行初始化,但必须在方法中为out参数赋值.

在方法中传递参数时使用out关键字,便是这个变量要回传值.最简单的运用时除法,例如你需要一个除


法方法,同时得到余数和商.但是普通的方法只能返回一个值,这个时候就可以使用out参数,把另一个


值返回.


int i = 15;

int j = 6;

int yushu;

Person p = new Person();

Consol.WriteLine();


class Person{

public int GetShangYuShu(int i,int j, out int yushu){

yushu = i%j;

return i/j;

}

}



★★★★重载

在C#中,类成员都有一个唯一的签名,而方法的签名由名称\参数个数和参数数据类型组成.只要签名不


同,就可以在一种类型内定义具有相同名称的多种方法.当定义两种或多种具有相同名称的方法时,就


称重载.

通俗的讲: 方法重载就是方法名相同,参数个数或参数类型不同.


string name ="小米";

int age = 21;

Peson p = new Person();

p.GetName();

p.GetName(name,age);


class Person{

public void GetName(){//重载方法1

//代码

}

public void GetName(string name){ //重载方法2

//代码

}

public void GetName(string name,int age){ //重载方法3

//代码

}

}


★★★★静态方法

定义静态方法和定义非静态方法相似,只是在定义静态方法时,需要在返回类型前加static关键字.静


态放在程序启动时系统会在内存里为静态方法创建一个实例,不需要再手动去实例静态方法.通过类名


可以直接调用静态方法,还有就是静态方法会在内存中占一定的内存空间.


在类中一旦定义了静态方法,name在类中就可以直接通过类名调用静态方法,并不需要通过实例化对象


访问静态方法.


注意:系统一旦为静态方法分配了内存空间,静态方法就会一直占用.所以在系统内存比较小时,尽量少


用静态方法.


public static string GetName(){

return"www";

}


扩展方法使你能够向现有类型"添加",而无需创建新的派生类型\重新编译或以其他方式修改原始类型


.扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.因此,通过扩咱方法


,就可以在不修改一个类型的前提下对一个类型进行功能上的扩充.


★★★★扩展方法

扩展方法使你能够向现有类型"添加"方法,而无需创建新的派生类型,重新编译或以其他方式修改原始类型.扩展方法时一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用.它定义在静态类中,但可以在其他类的对象上像调用实例方法那样进行调用.因此,通过扩展方法,就可以在不修改一个类的前提下对一个类进行功能扩充.

扩展方法和一般的静态方法的定义类似,唯一区别是在第一个参数的前面加上关键字this作为修饰符,同时第一个参数也决定了扩展方法可以扩展的类型.


public static class AddClass{

public static string GetLower(this string str)

{

return str.ToLower();

}

public static string GetName(this Student stu)

{

return "扩展方法";

}

public static string GetCanShu(this Student stu,string str) //带参数的扩展方法

{

return str;  //返回参数str

}

}


public class Student{

//这里没有代码

}


//----------调用代码


string URL = "HTTP://WWW.XXX.COM"; //要转化为小写字母的字符串

URL.GetLower(); //结果: http://www.xxx.com

Student s = new Student();  //实例化Student类

s.GetNme(); //结果: 扩展方法

string str = "扩展方法参数"  //结果:扩展方法参数



//------------扩展方法的特点

1.扩展方法是给现有类型添加一个方法.

2.扩展方法是通过制定关键字this修饰第一个参数

3.扩展方法必须声明在静态类中.

4.扩展方法要通用对象来调用.

5.扩展方法可以带参数.



★★★★属性


在C#编写的程序中,属性提供灵活的几只读取或编写私有字段的值.使用属性可以像使用公共数据成员一样使用属性,单实际上它们是称作"访问器"的特殊方法.这使得可以轻松访问数据,此外还有助于提高方法的安全性和灵活性.

对于类的实例化对象,属性显示为字段.对于类的构造来说,属性是一个或两个代码块:表示一个get访问器和set访问器.当读取属性时,执行get访问器的代码块;当向属性分配一个新值时,执行set访问器的代码块.value关键字用于定义set索引器分配的值.


语法格式

public string PropertyName

{

get{

return "返回私有变量的值或返回其他一些有意义的值";

}

set{

//为属性相关的私有变量赋值

}

}


例子:

public class Student{

string _name; //声明私有字段

public string Name{

get{

return _name

}

set{

_name = value;

}

}

}


Student stu = new Student();

stu.name = "属性";


//------set索引器可以进行判断,改写代码如下


set{

if(value=="属性"){

_name = "你是输入的是属性,符合要求"

}else{

_name = "你输入的非法";

}

}


以上看出在使用set索引器为属性赋值时,可以对赋值的数据进行判断,提高安全性.



★★★★自动属性

当属性访问器中不需要其他逻辑时,自动实现的属性可以使属性声明变得更加简洁.

一旦在类中声明了自动属性,那么编译器将创建一个私有的匿名后备字段,但是这个私有字段只能通过属性的get和set访问器进行访问.

自动属性必须同时声明get和set访问器.若要穿件只读自动属性,必须在set访问器前加private关键字.


声明:

public class Student

{

public int Age{

set;

get;

}

}

Student stu = new Student();

stu.Age = 15;


//感觉自动属性没什么用!




★★★★构造函数

构造函数具有与类相同的名称,他通常初始化新对象的数据成员.在类中不带参数的构造函数为类的默认构造函数,除非类是static(即静态类)的,否则C#编译器将为无构造函数的类提供一个公共的默认构造函数,一便该类可以实例化.无论何时,只要使用new关键字实例化对象,不提供参数就会调用默认构造函数.

注意: 如果构造函数设置了私有构造函数(使用private关键字),那么该类不能被实例化.

如果声明的构造函数带有参数,那么我们在实例化时也必须提供相应的参数,否则会出错.但是同时有声明了不带参数的构造函数,就调用该构造函数,也就是说的重载.


构造函数的特征:

1.类的构造函数函数名与类名相同

2.构造函数没有返回值

3.一般情况构造函数为public



★★★★对象初始化器

对象初始化器(Object Initializers)和集合初始化器(Collection Initializers)就是简化代码,让本来几行才能写完的代码一行写完.

作用:可以在创建对象时向对象的任何可访问的字段或属性赋值.


例子:

class Student{

public string name;

public string sex{get; set;} //自动属性

}


Student stu = new Student{name = "名字",Sex = "男"}; //使用{}以;结束

Student stu = new Student{Sex = "男"}; //也可以只为其中一个字段赋值



★★★★析构函数

在C#中很少使用析构函数,但是,当应用程序疯长窗口,文件,网络连接等这类非托管资源时,应当使用析构函数释放这些资源.


1.不能再结构中定义析构函数,只能对类使用析构函数

2.一个类只能有一个析构函数

3.无法继承或重载析构函数

4.无法调用析构函数,他们被自动调用

5.析构函数没有修饰符,也没有参数


例子:

public class Student{

~Student(){

//和类名相同,前面加~符合

}

}


★★★★readonly关键字

readonly修饰符只能用于字段(不能用于局部变量),只能在构造函数和声明中赋值.


例:

public class RendKey{

public readonly string Name;//声明没有赋值,只能在构造函数中进行赋值

public readonly string Age = 15; //声明时赋值(正规书写格式首字符大写)

}


与const修饰符的区别

1.readonly修饰的字段即使在声明时赋值了也可以在构造函数中对其进行更改. const修饰符声明时必须赋值,以后任何情况下都不允许更改.readonly修饰符即可以是实例字段也可以是静态字段.

2.将readonly应用于一个数组,不会冻结数组的内容.它只会冻结数组中的元素数量,因为现在无法将只读字段重新赋值为一个新的实例,数组中的元素仍然是可写的.



★★★★类的继承

类了除了继承于类还可以继承于接口,C#中类只能继承一个类,多重继承使用继承多个接口来实现.

子类从父类中继承了所有非私有数据和行为(属性,方法),可以说子类是对父类的扩展,但是构造函数和析构函数是不会被继承的.


语法格式:

public class BaseClass{

//父类

}

public class MyClass : BaseClass{

//子类

}


★★★★虚方法

在一个基类中,使用virtual修饰符修饰方法,属性,索引器或事件声明,那么他们就可以在派生类中被重写.使用


virtual关键字在基类中修饰的方法,就是平常所说的虚方法.在派生类中使用override关键字重写虚方法.


注意:成员字段和静态方法都不能声明为virtual,因为这个概念只对类中实例成员有意义.


class Person {

public virtual void Work(){

Console.WriteLine("这是一个虚方法");

}

}


class Student : Person{

public override void Work(){

Console.WriteLine("通过override关键字重写Work虚方法");

}

}

Student stu = new Stutent(); //实例化Student类

stu.Work();


★★★★调用方法的基类版本

在派生类中,可以使用base关键字访问基类成员,base关键字指定创建派生类实例时应用调用的基类构造函数,但


是不能在静态方法中使用base关键字.

1.关键字用于从派生类中访问基类的成员:

2.调用基类上已被其他方法重写的方法。

3.指定创建派生类实例时应调用的基类构造函数。


4.基类访问只能在构造函数、实例方法或实例属性访问器中进行。


★★★★隐藏方法

在派生类中,使用new关键字可以显示隐藏从基类继承的成员.若要隐藏继承的成员,请使用相同名称在派生类中


声明该成员,并用new修饰符修饰它,该成员就是独立于基类的方法.

例子:

class Person{

public string name = "小王";

public string sex ="男";

public void WriteInfo()

{

Console.WriteLine("人员信息:姓名{0},性别:{1}",name,sex);

}

}

class Student : Person

{

new public void WriteInfo(){

Consol.WriteLine("学生信息:姓名{0},性别:{1}",name,sex);

}

}


Student s = new Student();

s.WriteInfo();//这里调用子类的WriteInfo()方法



★★★★C#中重写父类方法的几种情况

关键字:virtual、abstract、override、new。

1. virtual:标识可能但不是必须被子类重写的方法,父类必须给出默认实现,子类可以重写(使用


override,new,或无特殊标识的普通方法),也可以不重写该方法。


2. abstract:标识必须被子类重写的方法,父类并不给出实现,子类必须用override关键字重写该方法。


3. override:标识重写父类的方法,父类方法必须是用abstract,virtual,override之一声明,运行时将根


据  实例的类型而不是引用的类型调用对象的方法。


4. new:标识重写父类的方法,父类方法可以用virtual、override、new之一声明,也可以是没有特殊标识的


普   通方法,运行时会根据引用的类型选择调用父类还是子类的方法,重写父类方法时,使用new关键字与使


用没   有特殊标识的普通方法是等效的,但是后者会给出一个编译警告。



★★★★抽象类和抽象方法

抽象类是一种特殊的类,他可以拥有数据成员,可以是其他类的子类.但是和具体类(非抽象类)不同,抽象类的某


些行为故意留给其子类来定义.


在C#中使用abstract关键字声明抽象类.abstract关键字可以和方法,属性,索引器及事件一起使用.标记为抽象


或包含在抽象类中的成员必须通过从抽象类的子类中在实现.

注意:抽象类不能够实例化,需要通过子类重写抽象类中的成员方法,然后实例化子类来实现.


抽象方法也是由关键字abstract声明,抽象方法需要使用;号结束,这和常规定义的方法块不同.抽象方法只能在


抽象类中声明.


例子:

class Person{

public abstract void Work();  //定义了一个抽象类

}

class Student{

public override void Work(){//使用override关键字重写抽象类

Console.WriteLine("重写抽象方法");

}

}

Student s = new Student();

s.Work();



★★★★密封类和密封方法

在应用程序中,有时候开发人员编写的类,并不希望被继承或没有必要被继承,为此C#提出了密封类的概念,密封


类在声明中使用sealed关键字.这样就可以防止类别其他类继承.

密封类可以组织其他开放人员在无意中继承,而且密封类可以起到运行时优化效果.

如果视图将一个密封类作为其他类的基类,C#将提示出错.密封类不能同时又是抽象类,因为抽象类是需要被继承


的,可以说sealed关键字不能喝abstract关键字一起使用.

密封类不可能有派生类,如果密封类实例中存在虚成员函数,该成员方法可以转化为非xude ,方法关键字将不再


生效.


class Person{

public virtual void Work(){

Console.WriteLine("声明封闭类时需要继承一个父类,不能直接声明");

}

}


sealed class Student : Person //使用sealed关键字声明封闭类

{

public sealed override void Work(){

Console.WriteLine("使用sealed关键重写父类的方法");

}

}

Student s = new Student();

s.Work();



★★★★部分类




★★★★接口

在应用程序中,接口就是一种规范,接口封装了可以被多个类继承的一些公共部分.但是接口不能包含字段.声明


接口使用interface关键字,接口中的成员默认是public,所以在声明成名方法时不需要加public关键字.接口中


的成员必须是非静态的.

例子:

interface Person{

//string name; 如果包含字段,程序将会报错.

void Work();

}


class Student : Person{

public void Work(){

Console.WriteLine("这个类继承与接口类Person");

}

}


Student s = new Student();

s.Work();



向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI