C#面向对象的三大特征:
封装、继承、多态
封装:
保证对象自身数据的完整性和安全性
1.完整性:封装就是把一些散的代码包装起来,让他们共同去完成一个功能
如:类、属性、方法都是封装的一种形式
2.安全性:如:我们在创建一个对象或调用一个方法时,只需要实例化一个类对象
或调用一个方法名就可以完成我们需要的功能,而他内部是怎么实现的,我们无法看到
继承:
C#继承的语法:
public class 子类:父类
{
//继承使用 : 符号
}
概念:
建立类之间的关系(父类与子类),实现代码复用,方便系统的扩展
1.在继承中分为父类(基类)和子类(派生类),也就是说当子类继承了父类以后,
那么子类就拥有了父类中非private的成员(属性、方法等)
例子:
学生类 有姓名、年龄...
员工类 有姓名、年龄...
那么如果这个时候,我们还要添加男人类、女人类等,
那是不是又要去写姓名 和 年龄等这些属性...这样就会很麻烦
然而 学生类和员工类 他们都共有 姓名、年龄这两个属性
之所以,他们都有这两个属性是因为他们都属于人类
所以这个时候我们就可以把他们共有的属性等提取出来共同封装
在一个Person类中,然后让学生类和员工类都继承Person类
这样,学生类和员工类就都拥有了姓名和年龄这两个属性,
他们共有的属性、方法就交给了Person类来管理,而他们只需要管理
自己特有的属性、方法就可以了
这样做的好处就是实现了代码的复用,方便了系统的扩展,
如:
以后我们还要再添加一个男人类或者女人类等,
就不用再去写姓名、年龄等这些他们共有的成员了,只需要继承Person类就可以了,
同样,如果要添加一个他们共有的成员时,只需要在父类Person中添加就可以了
而不必去在他们每个类中都去添加新增的成员。
例子:
public class Person //人类(这里他是父类)
{
public string Name{get;set;} //姓名
public int Age{get;set;} //年龄
}
public class Student:Person //学生类 继承 人类
{
//当Student继承了Person后,Student就自动拥有了Person类的非private成员
}
public class Employee:Person //员工类 继承 人类
{
//当Employee继承了Person后,Employee就自动拥有了Person类的非private成员
}
当我们创建一个Student对象和Employee对象时:
Student stu = new Student();
Employee emp = new Employee();
就可以使用:
stu.Name="张三";
stu.Age = 20;
emp.Name = "李四";
emp.Age = 30;
这就是因为他们都继承了Person类的原因
2.继承要符合 "子类 is a 父类" 的关系,就是说 子类是一个父类
例子:同上面所说,要想实现继承,就必须要符合 子类 is a 父类的关系,
如:学生是一个人,学生 is a 人 员工是一个人 员工 is a 人
3.继承的单根性,在C#中一个子类只能继承一个父类(就像一个儿子不能拥有多个父亲一样)
4.子类可以替换父类并且出现在父类能够出现的任何地方,且程序的行为不会发生变化,但是
反过来,父类对象不能替换子类对象,这种特性被称作 "里氏替换原则(Liskor Subsitution Principle)"
例子:
上面的例子创建对象也可以这样写:
Person p1 = new Student();
Person p2 = new Employee(); //里氏替换原则
而下面这样写就会报错:
Student stu = new Person();
Employee emp = new Person(); //报错
里氏替换原则中可以使用 is 和 as 操作符
is:用于去判断一个类型是否是给定的类型,返回bool值
如:p1 is Student //判断p1是否是Student类型 true:是 false:不是
as:用于把一个类型转换为另一个类型,类似于强制转换,但是在强制转换中,
如果给定的转换类型不兼容(转换失败),则会报错,但是 as 转换失败的话,
不会报错,会返回null
如:p1 as Student //把p1转换为Student类型,如果失败返回null
多态:
概念:多态是指两个或多个属于不同类的对象,对于同一个消息(方法调用)
作出不同响应的方式。
实现多态的方式:
1.重载
2.虚方法
3.抽象方法(还有抽象属性) → 抽象的成员没有主体
4.泛型如:<T>
定义虚方法语法:
访问修饰符 virtual 返回类型 方法名()
{
//方法体
//注意:虚方法不能是private
}
定义抽象方法语法:
访问修饰符 abstract 返回类型 方法名(); //没有方法体、不能是privatte
定义抽象属性语法:
public abstract 数据类型 属性名
{
get;set; //不能带有字段
}
子类中重写虚方法和抽象方法语法:
访问修饰符 override 返回类型 方法名()
{
//方法体
//注意:子类中重写父类的方法必须要:返回类型、方法名、参数都一样
}
子类中重写抽象属性例子:
public override int Age
{
get{return age;}
set{age = value;}
}
虚方法 和 抽象方法 区别:
虚方法:
1.用virtual修饰
2.要有方法体
3.可以被子类override(重写)
4.除了密封类、静态类外都可以写(虚方法)
抽象方法:
1.用abstract修饰
2.没有方法体
3.必须被非抽象的子类override(重写)
4.必须存在于抽象类中
抽象类:
1.有抽象方法(属性)的类一定是抽象类
2.抽象类不仅可以包含抽象方法、抽象属性,同样也可以包含其他属性、方法和构造函数
3.抽象类不能被实例化
4.抽象类不能是静态或者密封的,因为静态类和密封类都不能被继承
例子:
public abstract class Person //抽象类 Person 为父类
{
//定义了一个抽象方法
public abstract string Test();
}
public class Employee:Person //继承了Person类
{
//由于Employee类不是抽象类,所以必须重写override父类Person的Test()方法
public override string Test()
{
//方法体
return ""; //override 必须要方法名、参数、返回类型都相同
}
}
记住:抽象类不能被实例化
Person p = new Person(); //这样写会报错
但是,可以这样写:
Person p = new Employee(); //这样写是正确的
那么调用p.Test() 方法 会执行Employee里面的Test()方法,
也就是说,父类的方法一旦被子类重写override以后,那么创建
的父类对象就会去调用它实际类型对象的方法(就是被重写后的方法)
PS:抽象成员必须被非抽象子类override重写
当然,如果是虚方法的话,在子类中没有被重写,那么就会调用父类的方法
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。