《第九章类的封装、继承与多态.ppt》由会员分享,可在线阅读,更多相关《第九章类的封装、继承与多态.ppt(41页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、C#C#面向对象编程面向对象编程(二二)继承、封装和多态继承、封装和多态9 继承、封装和多态l l9.1 封装l l9.2 继承l l9.3 多态l l9.4 this和base关键字l l9.5 接口9.1封装对象的原理l什么是封装(encapsulation)u封装的好处封装的好处l良好的封装能够减少耦合l类内部的实现可以自由地修改l类具有清晰的对外接口 类的封装类的封装改变了用户传统的使用数据和代码的方式.它将方法和数据包含在一起构成一个独立的单元,可以通过设定单元内各个成员的的特性来控制对成员的访问。比如将一个字段定义为private,就可以防止外界直接访问这个字段。数据隐藏l封装性最
2、有用的方式之一l实现方法访问限制修饰符public 无限制,允许任何人来访问protected internal =protected+internalInternal 允许项目或程序内部的类来访问protected 继承时子类可以对基类有完全访问权private 只允许同一个类中的成员访问l属性也用来封装类的细节,并提供公用接口给该类的用户public class Student private string studentname;public string getstudentname()return(studentname);public string setstudentname(s
3、tring na)studentname=na;class App public static void Main()Student s1=new Student();s1.setstudentname(“zhanghua”);Console.WriteLine(s1.getstudentname();不能使用语句s1.studentname=“zhanghua”;继承性(inheritance)l一个类可以有能力直接从另一个类获得其代码和数据l派生类从基类那里获得其所有的成员l l例:例:lGUI设计的Form look and feel都是从.NET Form class继承下来的Syst
4、em.Windows.Forms.FormForm1继承透视图l如果Class Child是继承Class Parent而来Child的对象中包含一个Parent的对象ChildParentpublic class Parent public int X;.public class Child:Parent public int Y;./client.Child obj;obj=new Child();obj.X=10;obj.Y=20;X:X:Y:Y:publicmethods如何访问基类成员?l派生类可以调用基类的方法l通过使用base关键字l派生类在访问基类的时候有一定的限制,不能访问
5、private 的成员;internal的基类成员只能被同一个程序集中的派生类访问public class Accountpublic class Account public double balance;public double balance;public bool Withdraw(double public bool Withdraw(double amt)amt)balance-=amt;balance-=amt;return true;return true;public class CheckAccount:Accountpublic class CheckAccount:A
6、ccount public bool Withdraw(double amt)public bool Withdraw(double amt)if(amt=if(amt=150)Console.WriteLine(“pass);elseConsole.WriteLine(“not pass);派生类public static void Main(string args)UnderGraduate objUnderGraduate=new UnderGraduate();objUnderGraduate.GetInfo();objUnderGraduate.DisplayInfo();objUn
7、derGraduate.Check();ubasel用于从派生类中访问基类成员 l可以使用 base 关键字调用基类的构造函数uthisl用于调用本类的数据成员或方法l也可以不写 关键字 base和this构造函数1.构造函数不能继承2.在实例化子类对象时,会默认调用父类构造函数3.如果父类有多个构造函数,子类会默认调用无参的构造函数4.如果需要调用有参的默认函数,需要显示指明,需要使用base关键字15调用 base 构造函数 public class Student:Personprivate uint id;/调用 Person 构造函数 public Student(string na
8、me,uint age,uint id):base(name,age)this.id=id;Console.WriteLine(id);:base 关键字将调用 Person 类构造函数基类的构造函数先执行再执行派生类的构造函数。16演示public class Person public string _name;public uint _age;public Person(string name,uint age)this._name=name;this._age=age;Console.WriteLine(_name);Console.WriteLine(_age);public cla
9、ss Student:Person private uint _id;public Student(string name,uint age,uint id):base(name,age)this._id=id;Console.WriteLine(_id);还将调用 Base 构造函数static void Main(string args)/构造 Student Student objStudent=new Student(XYZ,45,001);演示演示示例代码示例代码类的多态性(1)l今天你多态了吗?今天你多态了吗?l面向对象程序设计中的面向对象程序设计中的重要概念重要概念多态性。多态性
10、。在运行时,可以通过指向基类的引用,来调用实现派在运行时,可以通过指向基类的引用,来调用实现派在运行时,可以通过指向基类的引用,来调用实现派在运行时,可以通过指向基类的引用,来调用实现派生类中的方法。生类中的方法。生类中的方法。生类中的方法。同一操作作用于不同的对象,可以有不同的解释,产同一操作作用于不同的对象,可以有不同的解释,产同一操作作用于不同的对象,可以有不同的解释,产同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。生不同的执行结果,这就是多态性。生不同的执行结果,这就是多态性。生不同的执行结果,这就是多态性。多态性通过派生类覆写基类中的虚函数型方法来实现
11、。多态性通过派生类覆写基类中的虚函数型方法来实现。多态性通过派生类覆写基类中的虚函数型方法来实现。多态性通过派生类覆写基类中的虚函数型方法来实现。类的多态性(2)l编译时的多态性编译时的多态性 编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。l运行时的多态性运行时的多态性u运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。uC#中,运行时的多态性通过覆写虚成员实现。类的多态性的实现l(1)类内部或子类和和父类类内部或子类和和父类定义同名但参数列表不同的方法,称为方法的重载(overload);l (2)子类
12、和和父类定义同名且参数列表也相同的方法,称为新增,这时应 该在子类的同名方法前面用new修饰符;l (3)子类和和父类定义同名且参数列表也相同的方法,并且父类父类中的方法用abstract/virtual进行修饰,子类子类中的方法用override进行了修饰,称为虚方法的覆盖(覆盖(override)。编译时多态 _重载重载重载重载(OverloadOverload)l重载重载_类中定义的方法可能有不同的版本 public bool Withdraw(double amt,string name)public double Withdraw(double amt)l特点(两必须一可以)1.方法
13、名方法名必须相同必须相同2.参数列表参数列表必须不相同必须不相同3.返回值类型返回值类型可以不相同可以不相同一般用于同一个类中最常用于类的构造函数相同方法new隐藏继承成员关键字 new演示演示示例代码示例代码运行时多态_方法的覆盖(override)l父类父类中的方法用abstract/virtual进行修饰,子类子类中的方法用override进行了修饰,称为虚方法的覆盖(覆盖(override)。运行时多态(1)_虚函数虚函数一般用于继承类关系中1、声明虚方法(在基类中在基类中)n使用virtual关键字 npublic virtual bool Withdraw();2、调用虚方法,运行
14、时将确定调用对象是什么类的实例,并调用适当的覆写的方法。3、虚方法可以有实现体覆写(Override)l子类子类中为满足自己的需要来重复定义某个方法的不同实现覆写l通过使用关键字override来覆写 public override bool Withdraw()l只有虚方法和抽象方法才能被覆写l要求:(三相同)u相同的方法名称u相同的参数列表u相同的返回值类型关键字 override和virtualpublic class Personpublic virtual void WriteInfo()Console.WriteLine(我是人的方法);public class Student:P
15、ersonpublic override void WriteInfo()Console.WriteLine(我是学生的方法我是学生的方法);基类派生类base 方法的新实现class Student public virtual void StuInfo()Console.WriteLine(“此方法显示学生信息);class ExpStudent:Student public override void StuInfo()base.StuInfo();Console.WriteLine(“此方法重写 base 方法);static void Main(string args)ExpStud
16、ent objStudent=new ExpStudent();objStudent.StuInfo();Student objSuper=objStudent;objSuper.StuInfo();演示演示示例代码示例代码抽象类和抽象方法 2-12-1 abstract class ClassOne/类实现访问修饰符派生类的基类不能实例化运行时多态运行时多态(2)_抽象函数抽象函数abstract class Base /成员变量成员变量 int basevar;/成员函数成员函数abstract void base_fun1(parameters);/无法实现无法实现.抽象方法抽象方法cl
17、ass Derived:Base /成员变量成员变量 int derivedvars;/成员函数成员函数override void Base_fun1(parameters)/实际实现实际实现 .抽象类派生类提提供供重写方法原型原型必须重写重写 抽象类和抽象方法 2-2 32演示using System;namespace Example_1abstract class ABCpublic abstract void AFunc();public void BFunc()Console.WriteLine(“这是一个非抽象方法!);class Derv:ABCpublic override v
18、oid AFunc()Console.WriteLine(“这是一个抽象方法!);抽象类 不能实例化派生类 重写方法static void Main(string args)Derv objB=new Derv();objB.AFunc();objB.BFunc();33abstract class MyAbs public abstract void AbMethod();/派生类class MyClass:MyAbspublic override void AbMethod()Console.WriteLine(“在 MyClass 中实现的抽象方法);/派生自 MyClass 的子类cl
19、ass SubMyClass:MyClasspublic void General()/未实现 AbMethod 抽象方法 Console.WriteLine(在 SubMyClass 中未实现的抽象方法);static void Main(string args)SubMyClass objSubClass=new SubMyClass();objSubClass.General();密封类 l不能从密封类派生l防止类在子类中被重载,或被第三方扩展public sealed class MyClass/class members演示演示示例代码示例代码接口 3-2class IBase vo
20、id method1();int method2();/没有实现没有实现.接口接口interface只有方法声明没有实现public interface IPictureint DelImage();void ShowImage();隐式声明为 public无访问修饰符示例中的 IPicture接口用于演示接口接口 3-3演示public class MyPicture:IPicture /第一个方法的实现 public int DelImage()Console.WriteLine(“DelImage 实现!);return(1);/第二个方法的实现 public void ShowImag
21、e()Console.WriteLine(“ShowImage 实现!);static void Main(string args)MyPicture objM=new MyPicture();objM.ShowImage();int t=objM.DelImage();Console.WriteLine(t);派生自 IPicture 接口演示public interface IPictureint DelImage();void ShowImage();public class MyPicture:BaseIO,IPicture public int DelImage()Console.W
22、riteLine(“DelImage 实现!);return(1);public void ShowImage()Console.WriteLine(“ShowImage 实现!);public class BaseIO public void Open()Console.WriteLine(BaseIO 的 Open 方法);static void Main(string args)MyPicture objM=new MyPicture();objM.ShowImage();int val=objM.DelImage();Console.WriteLine(val);objM.Open()
23、;多重接口实现lC#不允许多重类继承l但C#允许多重接口实现 l这意味着一个类可以实现多个接口 演示/第一个接口public interface IPictManip void ApplyAlpha();/第二个接口public interface IPictureint DelImage();void ShowImage();public class BaseIO public void Open()Console.WriteLine(“BaseIO 的 Open 方法);static void Main(string args)MyPicture objM=new MyPiture();objM.ShowImage();objM.DelImage();objM.ApplyAlpha();objM.Open();public class MyPicture:BaseIO,IPicture,IPictManippublic int ApplyAlpha().
限制150内