320 likes | 425 Views
.NET 平台和 C# 编程. 信息工程系:罗明刚. 第五章 . C# 中的继承. 回顾. 类是 C# 中的一种结构,用于在程序中模拟现实生活的对象 成员变量表示对象的特征 方法表示对象可执行的操作 如果类中未定义构造函数,则由运行库提供默认构造函数 析构函数不能重载,并且每个类只能有一个析构函数 可以根据不同数量的参数或不同数据类型参数对方法进行重载,不能根据返回值进行方法重载 命名空间用来界定类所属的范围,类似于 Java 中的包. 目标. 理解继承 在 C# 中使用继承 在 C# 中使用接口 在 C# 中使用方法的重写. 继承 2-1.
E N D
.NET平台和C#编程 信息工程系:罗明刚
第五章 C# 中的继承
回顾 • 类是 C#中的一种结构,用于在程序中模拟现实生活的对象 • 成员变量表示对象的特征 • 方法表示对象可执行的操作 • 如果类中未定义构造函数,则由运行库提供默认构造函数 • 析构函数不能重载,并且每个类只能有一个析构函数 • 可以根据不同数量的参数或不同数据类型参数对方法进行重载,不能根据返回值进行方法重载 • 命名空间用来界定类所属的范围,类似于Java中的包
目标 • 理解继承 • 在C# 中使用继承 • 在C#中使用接口 • 在C#中使用方法的重写
继承 2-1 基类 派生类 Class Base { // 成员变量 int basevar; // 成员函数 Base_fun1() { //定义 } ……. ……. Class Derived : Base { // 成员变量 int derivedvars; // 成员函数 Derived_fun1() { //定义 } ……. ……. 无需重新编写代码 void main() { Derived dr_obj = new Derived() ; dr_obj.Base_fun1(); }
继承 2-2 Class Animal { // 成员变量 int eyes, nose; Animal() { eyes = 2; nose = 1; } Pet_Animal() { //定义 } } 继承的层次结构示例 基类 基类 动物 派生类 Class Dog : Animal { // 成员变量 // 成员函数 private Barking() { //定义 } private Wagging_Tail() { } } 狗 马 派生类
X 继承 C# 中的类 多重继承 public classGraduate: Student, Employee { // 成员变量 // 成员函数 } 允许多重接口实现
public class Student:Person { private string _school; private uint _eng; private uint _math; private uint _sci; public void GetMarks() { Console.WriteLine(“请输入学校名称"); _school = Console.ReadLine(); Console.WriteLine("请分别输入英语、数学和自然科学的分数。"); _eng = uint.Parse(Console.ReadLine()); _math = uint.Parse(Console.ReadLine()); _sci = uint.Parse(Console.ReadLine()); Console.WriteLine(“所得总分为:{0}",_eng+_math+_sci); } } public class Person { private string _name; private uint _age; public void GetInfo() { Console.WriteLine("请输入您的姓名和年龄"); _name = Console.ReadLine(); _age = uint.Parse(Console.ReadLine()); } public void DispInfo() { Console.WriteLine("尊敬的 {0},您的年龄为 {1} ", _name, _age); } } 基类 派生类 调用的基类成员 无法实现GetInfo() 和 DispInfo()方法 static void Main(string[] args) { Student objStudent = new Student(); objStudent.GetInfo(); objStudent.DispInfo(); objStudent.GetMarks(); } 演示
public class Person { private string _name; private uint _age; public void GetInfo() { Console.WriteLine("请输入您的姓名和年龄"); _name = Console.ReadLine(); _age = uint.Parse(Console.ReadLine()); } public void DispInfo() { Console.WriteLine("尊敬的 {0},您的年龄为 {1}", _name, _age); } } public class Student:Person { private string _school; private uint _eng; private uint _math; private uint _sci; private uint _tot; public uint GetMarks() { Console.WriteLine(“请输入学校名称"); _school = Console.ReadLine(); Console.WriteLine("请分别输入英语、数学和自然科学的分数。 "); _eng = uint.Parse(Console.ReadLine()); _math = uint.Parse(Console.ReadLine()); _sci = uint.Parse(Console.ReadLine()); _tot = _eng + _math + _sci; Console.WriteLine("所得总分为:{0} ",_tot); return _tot; } } 派生类 基类 public class UnderGraduate:Student { public void ChkEgbl() { Console.WriteLine("要上升一级,要求总分不低于 150"); if(this.GetMarks() > 149) Console.WriteLine("合格"); else Console.WriteLine(“不合格"); } } 派生类 public static void Main(string[] args) { UnderGraduate objUnderGraduate = new UnderGraduate(); objUnderGraduate.GetInfo(); objUnderGraduate.DispInfo(); objUnderGraduate.ChkEgbl(); } 演示
关键字 base • 用于从派生类中访问基类成员 • 可以使用 base 关键字调用基类的构造函数
调用base 构造函数 public classStudent:Person { private uint id; //调用 Person 构造函数 publicStudent(stringname,uintage,uintid):base(name,age) { this.id = id; Console.WriteLine(id); } } :base关键字将调用 Person 类构造函数
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); } } static void Main(string[] args) { //构造 Student Student objStudent = new Student("XYZ", 45, 001); } public class Student:Person { private uint _id; public Student(string name, uint age, uint id):base(name, age) { this._id = id; Console.WriteLine(_id); } } 还将调用 Base构造函数 演示
关键字 override 基类 派生类 Class Base { // 成员变量 int basevar; // 成员函数 GetInfo() { //定义 } ……. ……. base 方法的新实现 Class Derived : Base { // 成员变量 int derivedvars; // 成员函数 override GetInfo() { //定义 } ……. …….
关键字 virtual [Access modifier] virtual [return type]name ( [parameters-list] ) { ... //Virtual方法实现 ... } publicvirtualvoid Func() { Console.WriteLine(“这是 virtual 方法,可以被重写"); }
关键字 new 相同字段 隐藏继承成员 //要求 new 访问修饰符 new //将执行派生类的变量 将输出派生类中的 val
class Employee { public virtual void EmpInfo() { Console.WriteLine(“此方法显示职员信息"); } } class DervEmployee: Employee { public override void EmpInfo() { base.EmpInfo(); Console.WriteLine(“此方法重写 base 方法"); } } static void Main(string[] args) { DervEmployee objDervEmployee = new DervEmployee(); objDervEmployee.EmpInfo(); Employee objEmployee = objDervEmployee; objEmployee.EmpInfo(); }
抽象类和抽象方法 2-1 访问修饰符 abstract class ClassOne { //类实现 } 不能实例化 派生类的基类
抽象类和抽象方法 2-2 abstract class Base { //成员变量 int basevar; // 成员函数 abstract void base_fun1(parameters); //无法实现 ……. } 抽象类 派生类 提供 class Derived : Base { // 成员变量 int derivedvars; // 成员函数 overridevoid Base_fun1(parameters) { //实际实现 ... } 重写方法 抽象方法 原型 必须重写
using System; namespace Example_5 { abstract class ABC { public abstract void AFunc(); public void BFunc() { Console.WriteLine(“这是一个非抽象方法!"); } } class Derv : ABC { public override void AFunc() { Console.WriteLine(“这是一个抽象方法! "); } } 抽象类 –不能实例化 派生类 –重写方法 static void Main(string[] args) { Derv objB = new Derv(); objB.AFunc(); objB.BFunc(); } 演示
abstract class MyAbs { public abstract void AbMethod(); } //派生类 class MyClass : MyAbs { public override void AbMethod() { Console.WriteLine(“在 MyClass中实现的抽象方法"); } } //派生自 MyClass 的子类 class SubMyClass:MyClass { public void General() { //未实现 AbMethod 抽象方法 Console.WriteLine("在 SubMyClass 中未实现的抽象方法 "); } } static void Main(string[] args) { SubMyClass objSubClass = new SubMyClass(); objSubClass.General(); }
接口 4-1 请按开关按钮:ON/OFF OFF • 两种方法 • ON • OFF ON
OFF ON 接口 4-2 ISwitch ON() OFF()
接口 4-3 • class IBase • { • void method1(); • int method2(); • int method3(float); • //没有实现 • ……. • } interface 接口 只有方法声明 没有实现
接口 4-4 隐式声明为 public publicinterface IPict { int DeleteImage(); void DisplayImage(); } 无访问修饰符 示例中的 IPict 接口用于演示接口
派生自IPict接口 public class MyImages : IPict { //第一个方法的实现 public int DeleteImage() { Console.WriteLine(“DeleteImage实现!"); return(5); } //第二个方法的实现 public void DisplayImage() { Console.WriteLine("DisplayImage实现!"); } } static void Main(string[] args) { MyImages objM = new MyImages(); objM.DisplayImage(); int t = objM.DeleteImage(); Console.WriteLine(t); } 演示
public class BaseIO { public void Open() { Console.WriteLine("BaseIO 的 Open 方法"); } } public interface IPict { int DeleteImage(); void DisplayImage(); } public class MyImages : BaseIO, IPict { public int DeleteImage() { Console.WriteLine(“DeleteImage 实现!"); return(5); } public void DisplayImage() { Console.WriteLine(“DisplayImage 实现!"); } } static void Main(string[] args) { MyImages objM = new MyImages(); objM.DisplayImage(); int val = objM.DeleteImage(); Console.WriteLine(val); objM.Open(); } 演示:示例 10
多重接口实现 • C# 不允许多重类继承 • 但 C# 允许多重接口实现 • 这意味着一个类可以实现多个接口
static void Main(string[] args) { MyImages objM = new MyImages(); objM.DisplayImage(); objM.DeleteImage(); objM.Open(); objM.ApplyAlpha(); } public interface IPictManip { void ApplyAlpha(); } //第二个接口 public interface IPict { int DeleteImage(); void DisplayImage(); } public class BaseIO { public void Open() { Console.WriteLine(“BaseIO 的 Open 方法"); } } 演示:示例 11
显式接口实现 在 C# 中,只要不发生命名冲突,就完全可以允许多重接口实现 public interface IPictManip { void ApplyAlpha(); } public interface IPict { void ApplyAlpha(); } public class MyImages : BaseIO, IPict, IPictManip { public int ApplyAlpha() { ....... ....... } } ? 使用显式接口实现
static void Main(string[] args) { MyImages objM = new MyImages(); IPict Pict = objM; //IPict 引用 Pict.DisplayImage(); IPictManip PictManip = objM; //IPictManip 引用 PictManip.DisplayImage(); } public class MyImages : BaseIO, IPict, IPictManip { public int DeleteImage() { Console.WriteLine(“DeleteImage 实现!"); return(5); } public void ApplyAlpha() { Console.WriteLine(“ApplyAlpha 实现!"); } void IPict.DisplayImage() { Console.WriteLine(“DisplayImage 的 IPict 实现"); } void IPictManip.DisplayImage() { Console.WriteLine(“DisplayImage 的 IPictManip 实现"); } } 显式接口实现 演示:示例 12
public class MyImages:IPictAll { public int DeleteImage() { Console.WriteLine(“DeleteImage 实现!"); return(5); } public void ApplyAlpha() { Console.WriteLine(“ApplyAlpha 实现!"); } public void ApplyBeta() { Console.WriteLine(“ApplyBeta 实现!"); } public void DisplayImage() { Console.WriteLine(“DisplayImage 实现!"); } } public interface IPict { int DeleteImage(); } public interface IPictManip { void ApplyAlpha(); void DisplayImage(); } //继承多重接口 public interface IPictAll:IPict, IPictManip { void ApplyBeta(); } static void Main(string[] args) { MyImages objM = new MyImages(); objM.DisplayImage(); int val = objM.DeleteImage(); Console.WriteLine(val); objM.ApplyAlpha(); objM.ApplyBeta(); } 演示:示例 13
总结 • 继承是获得现有类的功能的过程 • 创建新类所根据的基础类称为基类或父类,新建的类则称为派生类或子类 • base关键字用于从派生类中访问基类成员 • override 关键字用于修改方法、属性或索引器。new 访问修饰符用于显式隐藏继承自基类的成员 • 抽象类是指至少包含一个抽象成员(尚未实现的方法)的类。抽象类不能实例化 • 重写方法就是修改基类中方法的实现。virtual 关键字用于修改方法的声明 • 显式接口实现是用于在名称不明确的情况下确定成员函数实现的是哪一个接口