C#学习笔记(二)--- 封装、继承、多态


 封装、继承、多态是面向对象的三大特点,而在C#也是不例外,这篇文章将阐述封装、继承、多态的用法和思想。

1. 封装

1.1 定义

 封装,就是将类的属性和方法封闭起来,外部成员不可直接调用,只能通过预留的接口访问。
 封装允许类自身的属性和方法被一些可信对象操作,如继承自该类的对象,而一些不可信的类则不允许其修改。在一定程度上保证了类内数据的稳定性。
 同时,封装也能够简化编程——有时候我们并不想知道其原理,只需要会调用即可。外部的对象只需要访问一个简单的接口函数,就可以完成一件任务,很轻松的一件事。

1.2 途径

访问修饰符 class 类名
{
访问修饰符 类的成员1;

访问修饰符 类的成员n;
}

 类的访问修饰符可以定义为private、protected、public,通过访问修饰符,类的属性或方法可以选择是否允许被外部访问,从而限制了外部的权限,保护了内部的数据的稳定性。

1.3 类的属性

访问修饰符 class 类名
{
private 数据类型 字段名;
public 数据类型 属性名
{
get { return 字段名;}
set {字段名=value;}
}

类的成员;
}

 属性是对象的性质与对象之间关系的统称。和字段一样,属性是类的成员,有访问修饰符,有类型。
 通常,定义字段为私有,然后再定义一个与该字段对应的属性,具有对外的set和get方法。如下图:

public class Guy
{
	private string name;
	public string Name
	{
		set
		{
			name = value;
		}
		get
		{
			return name;
		}
	} 
}

 Guy是一个类,name是其字段,而Name是与其对应的属性,Name能够被外部访问,就好像对应name为public一样,直接访问。
 get和set是属性访问器,get和set访问器有预定义的语法格式,可以把属性访问器理解为方法。
 set访问器用于设置数据,value是调用属性是赋给属性的值;get访问器用于返回数据,必须有return语句,其返回值与属性类别是一致的。
 在set和get方法里,可以做相应的判断和操作,可以将set和get看做一个方法,在里面做需要的操作。

当然,属性也可以简化:

public class Guy
{
	public string Name { set; get; }
}

2. 继承

2.1 定义

 继承就是在已存在的类基础上,建立一个新类,保留原有类的属性和方法,同时又可以增加新的内容。
 已存在的类称为基类或父类,新建的类称为派生类或父类。

2.2 实现代码

//基类
public class Animal
{
	public string Name { get; set; }
	public Animal(string name)		//构造函数
	{
		Name = name;
	}
}
//派生类
public class Dog : Animal
{
	public Dog(string name) : base(name)	//调用基类的构造函数
	{
		
	}
}

 上面的代码实现了Dog类继承自Animal类,子类自动继承了基类的属性Name。
 调用base(参数列表)实现调用基类的带参数的构造函数。即使不使用base(),编译器也会先调用基类的不带参构造函数,再执行子类的构造函数。

2.3 C#继承特性

2.3.1 单一性

 和C++不同,在C#中一个子类只能有一个父类,而C++是可以继承多个父类的。继承的单一性也使得C#的基础关系比较简单,易于管理维护。

2.3.2 共同父类

Object类是所有类的基类。CLR运行时,要求所有的类型,不管是系统定义的类还是用户自定义的类,都必须从Object派生。

//1.隐式派生
class Guy
{

}
//2.显式派生
class Guy : System.Object
{

}
//两者实际上是一样。

2.3.3 传递性

 当一个子类被一个新类继承时,新的类不仅继承子类的属性和方法,子类的父类的内容也将继承下来。
 C#继承的单根性与传递性的继承关系,形成了树状层次结构,基类和它的派生类存在一种层次关系。

在这里插入图片描述

2.4 继承和访问修饰符

之前,关于类的定义时有讲到访问修饰符。在C#中,有4中不同的访问修饰符:
(1)pirvate:只能在本类中被访问,只可以被本类所存取,不能被继承。
(2)public:可以在项目外被访问,任意存取,可以被继承。
(3)protected:只能在本类中被访问,可以被继承。
(4)internal:只能在同一程序集中被访问,可以跨类。可以被继承。

 在C#中,新增了internal这一关键字。internal的作用域为同一程序集。程序集的概念可以理解为一个工程、项目,编译后的dll文件或exe文件。也就是说,internal修饰符修饰后,该类只能在单一工程内访问,如果其他项目访问是不行的。
这位博主关于internal的总结不错

如果没有显式地定义访问修饰符,则C#的默认访问权限如下。
(1)在namespace中的类、接口默认为internal。如果不是嵌套的类,命名空间或编译单元内的类只可以显式地定义为public、internal类型,不允许是其他访问类型。
(2)在类中,所有的成员均默认为private。可以显式地定义为public、private、protected、internal或protected internal访问类型。

2.5 里氏替换原则

 任何基类可以出现的地方,派生类一定可以出现。也就是说,可以用派生类对象代替基类对象,可以让一个基类的引用指向一个派生类的对象。

//基类
public class Animal
{
	public string Name { get; set; }
	public Animal(string name)		//构造函数
	{
		Name = name;
	}
}
//派生类
public class Dog : Animal
{
	public Dog(string name) : base(name)	//调用基类的构造函数
	{
		
	}
}

//栗子
Dog dog = new Dog();	//实例化对象
Animal animal = new Dog();	//使用里氏替换原则,基类对象指向派生类

3. 多态

3.1 定义

 在面向对象编程中,多态(Polymorphism)是类的三大特性之一,从一定角度来看,封装和继承几乎都是为多态而准备的。
 封装、继承、多态这三大特性是相互关联的,封装是基础,继承是关键,多态性是补充。
 多态性存在于继承性之中,它是继承性的进一步扩展。没有继承就没有多态。通过多态可以实现代码重用,减少代码量,提高代码的可扩展性和可维护性。

3.2 分类

多态性分为编译时的多态性和运行时的多态性

3.2.1 编译时的多态性

 编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。具有运行速度快的特点。

//基类
public class Animal
{
	public void Hello()
	{
		Console.WriteLine("我是一只小动物");
	}
}
//派生类
public class Dog : Animal
{
	public new void Hello()
	{
		Console.WriteLine("我是一只小狗");
	}
}

 重载是通过new修饰符来实现的,这样Dog类调用hello()时将覆盖掉Animal类的hello函数,调用自身的hello()函数。

3.2.2 运行时的多态性

 运行时的多态性是指直到系统运行时,才根据实际情况决定实现何种操作。C#中运行时的多态性是通过重写实现。具有高度灵活和抽象的特点。

//基类
public class Animal
{
	public virtual void Hello()
	{
		Console.WriteLine("我是一只小动物");
	}
}
//派生类
public class Dog : Animal
{
	public override void Hello()
	{
		Console.WriteLine("我是一只小狗");
	}
}

 重写,需要将父类的Hello()加上修饰符virtual,而子类的Hello()加上修饰符override,表示重写基类的虚方法。

3.2.3 区别

 如果使用里氏替换原则,即使用基类对象指向子类对象,那么会出现问题:究竟是调用哪个函数呢?
 (1)使用new重载,那么还是调用基类的方法。
 (2)使用virtual和overide重写,那么将调用子类自己的方法。
也就是说,基于重写可以实现多态,而重载方法不行。



  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗夜无风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值