深入.NET平台和C#编程1-6

深入.NET平台和C#编程1-6

一、深入.net框架

1.1、Microsoft .NET介绍

1、.NET框架结构

.NET框架运行在操作系统之上,是.NET最基础的框架。它提供了创建,部署和运行.NET应用的环境,主要包括含公共语言运行时(CLR)和框架类库(FCL),并且支持多种开发语言。CLR是.NET框架的基础。

2、CLR

CLR全称公共语言运行时,由两部分组成:CLS(公共语言规范)和CTS(通用类型系统)

1、CLS(公共语言规范)

编译语言的区别不仅在于类型、语法或者说语言规范也有很大的区别,CLS是一种最低级的语言标准,它制定了一种以.NET平台为目标的语言所必须支持的最小特征,以及该语言与其它的语言之间实现互操作性所需要的完备特征。

2、CTS(公共语法规范也称为通用类型系统)

通用类型系统(CTS)用于解决不同语言数据类型不同的问题,如C#中的int,VB.NET中的整型是integer,通过CTS,我们把他们两个编译成通用的类型Int32;所有的.NET语言共享这一类型系统。在它们之间可以实现无缝互操作。

3、MSIL

MSIL是微软中间代码,它由JIT编译器转换成机器代码。

中间代码的出现是为了实现跨语言开发和跨平台的战略目标,.NET所有编写的应用都不编译成本地代码,所以出现了中间代码。

3、FCL(框架类库)

.NET框架另外一个重要的部分是FCL(框架类库),框架类库是一些已经被封装好的功能集合;像System.Data.SqlClient和System.Data;在WinForms应用程序开发中我们用到过System.Windows.Forms;FCL提供了对系统功能的调用,是建立.NET应用程序,组件和控件的基础。

1.2、回顾类和对象

1、类和对象

类和对象的关系:类是对象的抽象化,对象是类的实例化;

类的属性:get 和 set

1、只写属性:只有set访问器

2、只读属性:只有get访问器

3、读写属性:同时存在get访问器和set访问器

类的三大特性:封装(将内部代码私有化)、继承(子承父)、多态(一件事物的多种形态)

2、封装

1、封装概念

封装又称之为信息隐藏,是指利用抽象数据类型将数据和数据的操作结合在一起,使其构成一个不可分割的独立实体,尽可能的隐藏内部细节,只保留一些对外接口,使之与外部发生联系

2、封装的优点

1)、保证数据的安全性。

2)、提供清晰的对外接口。

3)、那内部实现可任意修改,不影响其它类。

注意:将字段封装为属性是封装的一种方式,类的私有方法也是一种封装,封装的范围不仅限如此。

3、类图

1、类图的作用

类图将类的属性和行为以图的形式展现出来,是读者不用阅读大量代码即可明白类的功能和类之间的关系。

2、类图的图标

类中的成员在图中都用不同的图标表示。私有成员会在图标的右下方有一个“小锁”。字段属性放在方法前面,变量类型和返回值放在冒号后面,而私有成员前面加一个减号"-",公有成员前面再加一个加号"+"。

二、深入C#数据类型

2.1、值类型和引用类型

1、值传递

1、值类型属于System.ValueType命名空间,存储在栈中;值类型只要包括基本数据类型和枚举类型;这里还要介绍一种数据类型:结构:struct。

2、值传递的特点:

1、值传递,传递的是基本数据类型时,形参所作修改不会影响实参;

举例:

//在类中的方法
public static void Run(int a)   //形参
{
    a = 100;
}
public static void Main(string[] args)
{
    int a = 0;
    Run(a);  //实参
    Console.WriteLine(a);
}
//最后输出a的值为0;

2、值传递,传递的是引用数据类型时,形参所做修改会影响实参;

举例

//在类中的方法
public static void Run(int[] a)//形参
{
    a[0] = 100;
}
public static void Main(string[] args)
{
    int[] a = {1,2};
    Run(a);  //实参
    Console.WriteLine(a[0]);
}
//最后输出a的值为100;
2、引用传递

1、引用类型属于System.Object命名空间,存储在堆中;引用类型主要包括数组、类、集合、接口;引用传递又称为地址传递;

2、引用传递的特点:引用传递要在形参和实参前面加ref,并且形参所做修改会影响实参。

举例:引用数据类型的引用传递

//在类中的方法
public static void Run(ref int[] a)//形参
{
    a[0] = 100;
    a = new int[5];
}
public static void Main(string[] args)
{
    int[] a = {1,2};
    Run(ref a);  //实参
    Console.WriteLine(a[0]);
}
//最后输出a的值为100,并且数组的长度为5

基本数据类型的引用传递

//在类中的方法
public static void Run(ref int a)//形参
{
    a = 100;
}
public static void Main(string[] args)
{
    int a = 0;
    Run(ref a);  //实参
    Console.WriteLine(a);
}
//最后输出a的值为100;
3、数组复制

数组的复制可以利用循环实现;设两个数组array1和array2(array2的长度不小于array1的长度),将数组array1中的元素的值复制到array2中。可以利用以下代码实现:

for(int i = 0;i < array1.Length;i++)
{
    array2[i] = array1[i];
    //将数组array1中的元素的值复制到array2中
}
4、结构:struct

结构是一种基本数据类型,结构和类相似,

语法:

访问修饰符 struct 结构名

{

​ //结构体

}

结构的定义和特点

1、结构中可以有字段,也可以有方法;

2、定义时,结构中的字段不能被赋初值;

3、结构使用时,可以不用new,直接定义结构的对象就可以了;

4、声明结构的对象后,必须给结构的成员变量赋初值;

结构的注意点:

1、结构不能手写无参构造函数;

2、结构里有多少个字段,定义构造函数式就要有多少个参数

5、装箱和拆箱

装箱:将基本数据类型转化为引用数据类型

拆箱:将引用数据类型转化为基本数据类型

举例:

static void Main(string[] aegs)
{
    int i = 123;
    object o = i;   //装箱
    int j = (int)o;  //拆箱
}

三、使用集合组织相关数据

3.1、集合

1、集合的概念

集合就是用来存储长度不固定的一连串数据,并且具有一定的逻辑性和数据存储结构。集合分为泛型集合和非泛型集合。

2、ArrayList

ArrayList非常类似数组,称为数组列表;ArrayList可以动态维护,ArrayList提供了一系列方法对其中的元素进行访问、增加和删除的操作。

ArrayList类属于System.Collections命名空间,这个命名空间包含接口和类;

定义ArrayList的语法

using System.Collections;  //命名空间
//创建容量为0的ArrayList对象
ArrayList stu = new ArrayList();
//创建容量为5的ArrayList对象
ArrayList teach = new ArrayList(5);

注:ArrayList是动态可维护的,所以定义时可以指定容量,也可以不指定容量。

ArrayList的常用方法及属性表

属性名称说明
Count获取ArrayList中实际包含的元素数
返回值类型方法名称说明
intAdd(Object value)将对象添加到ArrayList的结尾处
voidRemoveAt(int index)移除ArrayList中指定下标的元素
voidRemove(Object value)移除ArrayList中特定的对象
voidClear()清空

ArrayList中也有下标,也称为索引,下标从0开始;

举例:

static void Main(string[] args)
{
    ArrayList arraylist = new ArrayList();
    arraylist.Add("人间");
    arraylist.Add(2310);
    arraylist.Add(3.14);
    arraylist.Add("bu zhi de");
    //上面是用Add方法添加元素,并且添加的元素不是同一数据类型
    arraylist.RemoveAt(2); 
    //删除下标为2的元素,也就是3.14
    arraylist.Remove(2310);
    //删除对象名为2310的元素
    //遍历方法一
    for(int i = 0 ;i <arraylist.Count; i++)
    {
        Console.WriteLine(arraylist[i]);
    }
    //遍历方法二
    foreach(Object obj in arraylist)
    {
         Console.WriteLine(obj);
    }
    //清空
    arraylist.Clear();
    
}

注意:在删除一个元素之后,后面的元素会自动向前移,所以注意不要数组越界了。

3、Hashtable

Hashtable数据结构,通常称为哈希表,Hashtable的数据结构是通过键(Key)和值(Value)来组织的;Hashtable也属于System.Collections命名空间,并且它的每个元素都是一个键/值对。

Hashtable常用的方法和属性表

属性名称说明
Conut获取Hashtable中键/值对的数目
Keys获取Hashtable中键的集合
Values获取Hashtable中值的集合
返回值类型方法名称说明
voidAdd(Object key,Object value)添加带有指定键和值的元素到Hashtable中
voidRemove(Object key)移除Hashtable中带有特定键的元素
voidClear()清空

注:这里键是唯一的,并且不可以用null作为键。

举例:

//SE类中写字段和属性
public class SE
{
    public SE(){}    //无参构造函数
    //字段
    private string name;  //姓名
    private int age;  //年龄
    private string id;  //学号
    //属性
    public string Name { get => name; set => name = value; }
    public int Age { get => age; set => age = value; }
    public string Id { get => id; set => id = value; }
    
}
//在Main方法中调用
static void Main(string[] args)
{
    Hashtable hash = new Hashtable();
    SE se = new SE();  //初始化一
    se.Name = "人间";
    se.Age = 25;
    se.Id = "211";
    SE joe = new SE();  //初始化二
    joe.Name = "鲸落";
    joe.Age = 20;
    joe.Id = "110";
    SE ema = new SE();
    ema.Name = "赤怜";
    ema.Age = 18;
    ema.Id = "120";
    //用Add添加三个元素
    hash.Add(se.Id,se);
    hash.Add(joe.Id,joe);
    hash.Add(ema.Id,ema);
    //删除一个元素,删除一个键是211的对象
    hash.Remove("211");
    //遍历键
    foreach(Object obj in hash.Keys)
    {
        Console.WriteLine((string) obj);
    }
    //遍历值
    foreach(Object obj in hash.Values)
    {
        SE se = (SE)obj;
        Console.WriteLine(se.Name);
    }
    //遍历方式三
    foreach(DictionaryEntry en in hash)
    {
        Console.WriteLine(en.Key);  //输出键
        Console.WriteLine(((SE) en.Values).Name);   //输出值
    }
    //清空
    hash.Clear();
}

DictionaryEntry是一个结构,定义可设置或检索的Hashtable的键/值对;具体可以通过查阅MSDN了解;

3.2、泛型和泛型集合

泛型:泛型引入一个概念:类型参数。

泛型集合比较经典的有两种List<T>和Dictiona<T>,"<T>"可以对集合中的元素类型进行约束,T表示集合中管理的元素类型。

1、List <T>

1、List泛型集合和ArrayList集合差不多,当也是有区别的;List泛型集合的命名空间是:System.Collections.Generic;这个命名空间定义了许多的泛型集合类;

2、List泛型集合的语法:

List<T> 对象名 = new List<T>();

3、List泛型集合和ArrayList集合的区别

1)、ArrayList可以添加任意类型的元素,List不可以,List会对数据类型进行约束

2)、ArrayList在添加/读取值类型元素时要拆箱和装箱,List在添加/读取值类型元素时不需要拆箱和装箱

3)、ArrayList和List的通过索引访问元素、添加方法、删除方法和遍历方法都是一样的。

举例:

//SE类中写字段和属性
public class SE
{
    public SE(){}    //无参构造函数
    //字段
    private string name;  //姓名
    private int age;  //年龄
    private string id;  //学号
    //属性
    public string Name { get => name; set => name = value; }
    public int Age { get => age; set => age = value; }
    public string Id { get => id; set => id = value; }
    
}
//在Main方法中调用
static void Main(string[] args)
{
   List<SE> list = new List<SE>();
    SE se = new SE();  //初始化一
    se.Name = "人间";
    se.Age = 25;
    se.Id = "211";
    SE joe = new SE();  //初始化二
    joe.Name = "鲸落";
    joe.Age = 20;
    joe.Id = "110";
    SE ema = new SE();  //初始化三
    ema.Name = "赤怜";
    ema.Age = 18;
    ema.Id = "120";
    //用Add添加三个元素
    list.Add(se);
    list.Add(joe);
    list.Add(ema);
    //删除一个元素,删除一个键是211的对象,也就是初始化一se,se后面的元素会往前移
    list.Remove("211");
    //删除一个元素,删除下标为1的元素,也就是初始化三ema
    list.RemoveAt(1);
    
     //遍历方法一
    for(int i = 0 ;i <list.Count; i++)
    {
        Console.WriteLine(list[i]);
    }
    //遍历方法二
    foreach(SE obj in list)
    {
         Console.WriteLine(obj);
    }
    //清空
    list.Clear();
}
2、Dictionary<K,V>

1、Dictionary和Hashtable差不多,Dictionary编译时检查类型约束,获取元素时无须类型转换,Dictionary也是通过Key/Value(键/值)对元素进行保存。

2、Dictionary<K,V>的语法:

Dictionary<K,V> 对象名 = new Dictionary<K,V>();

说明:K表示集合中Key的类型,V表示Value的类型集合。

3、Dictionary和Hashtable的区别

1)、Hashtable可以添加任意类型的元素,Dictionary不可以,Dictionary会对数据类型进行约束

2)、Hashtable在添加/读取值类型元素时要拆箱和装箱,Dictionary在添加/读取值类型元素时不需要拆箱和装箱

3)、Hashtable和Dictionary的通过索引访问元素、添加方法、删除方法和遍历方法都是一样的。

举例:

//SE类中写字段和属性
public class SE
{
    public SE(){}    //无参构造函数
    //字段
    private string name;  //姓名
    private int age;  //年龄
    private string id;  //学号
    //属性
    public string Name { get => name; set => name = value; }
    public int Age { get => age; set => age = value; }
    public string Id { get => id; set => id = value; }
    
}
//在Main方法中调用
static void Main(string[] args)
{
   Dictionary<string,SE> dic = new Dictionary<string,SE>();
    SE se = new SE();  //初始化一
    se.Name = "人间";
    se.Age = 25;
    se.Id = "211";
    SE joe = new SE();  //初始化二
    joe.Name = "鲸落";
    joe.Age = 20;
    joe.Id = "110";
    SE ema = new SE();
    ema.Name = "赤怜";
    ema.Age = 18;
    ema.Id = "120";
    //用Add添加三个元素
    dic.Add(se.Id,se);
    dic.Add(joe.Id,joe);
    dic.Add(ema.Id,ema);
    //删除一个元素,删除一个键是211的对象
    dic.Remove("211");
    //遍历键
    foreach(string obj in dic.Keys)
    {
        Console.WriteLine((string) obj);
    }
    //遍历值
    foreach(SE obj in dic.Values)
    {
        Console.WriteLine(se.Name);
    }
    //遍历方式三
    foreach(KeyValuePair<string,SE> en in dic)
    {
        Console.WriteLine(en.Key);  //输出键
        Console.WriteLine(en.Values.Name);   //输出值,这里不需要类型转换
    }
    //清空
    hash.Clear();
}

KeyValuePair<TKey,TValue>是 一个泛型结构,定义可设置或检索的键/值对,具体可以通过查阅MSDN了解;

3、泛型类

定义泛型类的过程和定义一个类相似。不同的是尖括号里定义了类型参数;

1、语法:

public class 类名<T>

{

​ //……

}

说明:T指类型参数,代表具体的数据类型,可以是类类型,也可以是基本数据类型;泛型类支持任意的数据类型。

2、泛型类优点

1)、性能高

2)、类型安全

3)、实现代码重用

举例:

class ComboBoxItem<T>
{
	private string _itemText;  //显示文字
	public string ItemText
	{
		get{return _itemText;}
		set{_itemText = value;}
	}
	private T _itemValue;  //实际的对象
	public T ItemValue
	{
		get{return _itemValue;}
		set{_itemValue = value;}
	}
}

四、深入方法的类

4.1、构造函数

1、构造函数是什么,用来干什么

用来创建类实例的方法称之为构造函数;构造函数主要是用来new对象的,构造函数还有一个兼职是:给成员变量赋值;

2、构造函数的特点

类的构造函数是类中一个特殊的方法,它的特点如下:

1、方法名和类名一致;

2、没有返回值类型;

3、主要完成对象的初始化工作;

3、构造函数的分类

构造函数的分类主要分为两种:显示分类和参数分类

1、显示分类:

显式构造函数:手写的构造函数

隐式构造函数:在没有手写构造函数时,系统会给一个默认的无参构造函数,这就是隐式构造函数。

2、参数分类:

无参构造函数:小括号里面不带参数

无参构造函数语法:

访问修饰符 类名()

{

​ //方法体

}

有参构造函数:小括号里带参数

有参构造函数语法:

访问修饰符 类名(参数列表)

{

​ //方法体

}

参数列表一般用来给类的属性赋值。

4.2、方法重载

1、方法重载

多态的实现方式为:重载和重写

重载和重写的区别:重载是在同一个类中;重写是在不同类中。

重载方法概念:多个构造函数提供了多种实例化一个类的方法就是方法重载;

重载的意义:为解决方法名不足;

2、方法重载的特点

1、在同一个类中;

2、方法名相同;

3、方法的参数的不同:参数的数据类型不同或参数个数不同;

注:不可以以方法的返回值类型的不同来判断是否是重载,也不可以以方法的访问修饰符的不同来判断是否是重载。

3、方法重载的实例
public static void Main(string[] args)
{
	Console.WriteLine(8);  //一个参数,int类型
    Console.WriteLine(10.83);  //一个参数,double类型
    Console.WriteLine("HelloWord");  //一个参数,string类型
    Console.WriteLine("HelloWord,{0}",name);  
    //两个参数,string类型,变量
}

重载方法的调用规则:根据参数[个数+数据类型]调用

//假设有一个Stu类,重载方法
public string Run(string name)
{
   return "这是一个参数的,string类型的";
}
public int Run(int a,int b)  //这是两个参数的,int类型的
{
    int num = a+b;
    return num;
}
//在Main方法里调用
public static void Main(string[] args)
{
    Stu stu = new Stu();
    Console.WriteLine(stu.Run(10,20));  //输出结果:30
    Console.WriteLine(stu.Run("狗子"));   //输出结果:这是一个参数的,string类型的
}

4.3、对象交互

1、概述:在面向对象的世界里,一切皆为对象。对象与对象相互独立,互不干涉,但在一定外力的作用下,对象开始共同努力。
2、交互图:在这里插入图片描述

3、举例:顾客点菜

1、顾客对象顶了菜单对象,并选中服务员对象为自己服务

2、服务员对象将菜单信息告诉厨师对象

3、厨师对象根据菜单做菜,做完菜

4、厨师对象通知服务员对象菜做完了,服务员对象取菜送给顾客对象。

上面有四个对象,顾客、菜单、服务员、厨师,上面的过程就是对象的交互;

五、初识继承和多态

5.1继承概念

1、移除类的冗余代码

1、冗余代码:两个或两个以上的类有完全相同的属性;以前就是会两个类单独写属性,这样不利于代码的复用。

解决冗余代码:新建一个公共类,将其他两个类的相同部分抽取出来,放到公共类里面;在使用公共属性时要使用到继承;要将公共类作为父类,其他两个类作为子类;

2、继承的概念:被继承的类称之为父类或基类,继承的类称之为子类或派生类;继承时使用已经存在的类的定义作为基础新建类的技术,新类的定义可以直接增加的数据或新的功能,也可以用已存在的类的功能。

继承的语法:

public class B:A
{
	//A类就是父类
	//继承要用 ( :)来表示
}
2、base关键字和protected修饰符

1、base:base表示父类,可以用于访问父类的成员;像调用父类的属性、方法是可以的;base关键字还可以调用父类的构造函数;

base调用构造函数有两种:

1、 :base() 这是调用父类无参构造函数 ;

2、:base(参数列表) 这是调用父类的有参构造函数;

注:base可以访问父类所有的非private成员;

2、访问修饰符

访问修饰符:private(私有的)、protected(受保护的)、public(公开的)

在继承中这三个访问修饰符有不同程度的访问限制

private:在父类中用private修饰的,只能在本类中使用;

protected:在父类中用protected修饰的,可以在本类中和继承该类的子类中使用;

public:在任何一个类中都可以使用。

3、子类构造函数

1、隐式调用父类的构造函数

在默认的情况下,子类会先调用符类的无参构造函数,然后再调用子类的构造函数;这是因为说明调用的是哪一个构造函数,所以系统隐式调用父类的无参构造函数;

2、显示调用父类的构造函数

调用父类的有参构造函数,可以使用::base(参数列表),这要就可以调用指定的有参构造函数了。这样就可以实现继承属性的初始化。

5.2继承的特性

1、继承的特性

继承有两个特性:传递性和单根性;

1、传递性:传递性就像是孙子会遗传爷爷的基因一样,假设 B:A,C:B,这两组继承,B会继承A的基因,C会继承B的基因,那么C会继承A的部分基因;

2、单根性:单根性就像是一个人只能由一对亲身父母一样,一个子类只能由一个父类,但是可以有多个接口,就像一个人可以有多个干爹干妈一样;

注:C#中还用一个特殊的关键字 sealed,使用这个关键字修饰的类是不能被继承的,这种类也称为密封类。

2、is a 的应用

1、is a :is a是用来判断真正的数据类型的,is a属于bool类型;

语法:引用名(或者是对象名) is 数据类型

这里通常用于方法重写时,来判断调用哪一个类的方法;

2、还有一个 as a,as a:是用来强转的。

语法:数据类型 变量名 = 对象名 as 数据类型

3、继承的价值

1、继承模拟了现实世界的关系,OOP中强调一切皆对象;

2、继承实现了代码的重用,合理的使用继承,会使代码更加简洁;

3、继承使得程序结构清晰,子类和父类的层次结构清晰,最终的目的是使子类只关注子类的相关行为和状态,无须关注父类的行为和状态。

5.3多态

1、解决继承带来的问题

我们在遍历方法时会使用到is a ,方法不多还好,方法多了就每次都要判断就会很麻烦,也会增加代码的负担;

要解决这个问题就要用到虚方法;

1、虚方法:用virtual修饰,子类用override声明

语法:

父类:访问修饰符 virtual 返回值类型 方法名()

{

​ //方法体;

}

子类:访问修饰符 override 返回值类型 方法名()

{

​ //方法体;

}

像这种通过override关键字来修饰的方法就是重写;使用虚方法就无须考虑子类是什么类型的了。

虚方法的特点:

1、相同的方法名,相同的参数,在不同类中;

2、不强制子类实现父类中virtual方法;

3、virtual方法一定要有方法体;

2、实现多态

1、实现多态的方法:重载、重写(虚方法和抽象方法);

父类中用virtual修饰的方法称为虚方法;子类用override修饰方法来实现方法的重写;

2、定义父类变量,用子类对象初始化父类变量;

六、深入理解多态

6.1里氏替换原则

1、概念:原则上子类对象可以赋给父类对象,也可以说子类代替父类并出现在父类能够出现的任何地方,且程序不会受影响,但是反过来父类对象不能替代子类出现,这就是里氏替换原则;简单来说就是,子类可以替代父类,但是父类不能替代子类。

2、is 和as的使用:is是用来检查对象和指定的数据类型是否兼容的,as是用来两个类之间的数据类型转换;

注:用as操作符进行类型转换时不会产生异常,但是这并不代表不需要异常处理。

6.2、抽象类和抽象方法

1、抽象类和抽象方法的使用

1、抽象方法:抽象方法是一个没有实现的方法,通过在定义方法时增加关键字abstract可以声明抽象方法。

语法:访问修饰符 abstract 返回值类型 方法名();

注:抽象方法没有方法体,也就是没有大括号,直接在小括号后面跟分号(;);

2、抽象类:含有抽象方法的类就是抽象类,定义抽象方法和定义抽象类是一样的;但抽象类是定义类;

语法:访问修饰符 abstract class 类名{}

注:抽象类提供抽象方法,这些方法只有定义,如何实现都是由抽象类的非抽象子类完成。

2、抽象方法和抽象类的应用

1、如何在子类中实现抽象方法

一旦确认继承关系,抽象类中的抽象方法就必须在子类中实现;除非抽象类的子类也是抽象类。在子类中声明抽象方法也是用override关键字;

语法:访问修饰符 override 返回值类型 方法名()

{

​ //方法体

}

举例

//抽象类和抽象方法
public abstract class Tube
{
    public Tube(){} //无参构造函数
    //抽象方法
    public abstract void Run();
    
}
//子类
public class Teach:Tube
{
    public Teach(){}  //无参构造函数
    public override void Run()
    {
    	Console.WriteLine("子类实现抽象方法");
    }
}
3、抽象方法和虚方法的区别

抽象类、抽象方法和虚方法都可以实现多态,但是还是由区别的;

虚方法抽象方法
用virtual修饰用abstract修饰
要有方法体,哪怕是一个分号不允许有方法体
可以被子类override必须被子类override
除了密封类外都可以定义只能在抽象类中定义
2、面向对象的三大特性

面向对象的三大特性是:封装、继承、多态

封装:保证对象自身数据的完整性和安全性;

继承:建立类之间的关系,实现代码复用、方便系统的扩展;

多态:相同的方法调用可实现不同的实现方式。

抽象方法,这些方法只有定义,如何实现都是由抽象类的非抽象子类完成。

2、抽象方法和抽象类的应用

1、如何在子类中实现抽象方法

一旦确认继承关系,抽象类中的抽象方法就必须在子类中实现;除非抽象类的子类也是抽象类。在子类中声明抽象方法也是用override关键字;

语法:访问修饰符 override 返回值类型 方法名()

{

​ //方法体

}

举例

//抽象类和抽象方法
public abstract class Tube
{
    public Tube(){} //无参构造函数
    //抽象方法
    public abstract void Run();
    
}
//子类
public class Teach:Tube
{
    public Teach(){}  //无参构造函数
    public override void Run()
    {
    	Console.WriteLine("子类实现抽象方法");
    }
}
3、抽象方法和虚方法的区别

抽象类、抽象方法和虚方法都可以实现多态,但是还是由区别的;

虚方法抽象方法
用virtual修饰用abstract修饰
要有方法体,哪怕是一个分号不允许有方法体
可以被子类override必须被子类override
除了密封类外都可以定义只能在抽象类中定义
2、面向对象的三大特性

面向对象的三大特性是:封装、继承、多态

封装:保证对象自身数据的完整性和安全性;

继承:建立类之间的关系,实现代码复用、方便系统的扩展;

多态:相同的方法调用可实现不同的实现方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值