Web应用开发技术教学课件面向对象特性.ppt_第1页
Web应用开发技术教学课件面向对象特性.ppt_第2页
Web应用开发技术教学课件面向对象特性.ppt_第3页
Web应用开发技术教学课件面向对象特性.ppt_第4页
Web应用开发技术教学课件面向对象特性.ppt_第5页
免费预览已结束,剩余122页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

2019年2月5日,计算机学院,第 3 章 c#的面向对象特性,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,在前一章的例子中,我们已经定义了一些简单的类,如hello 类。 程序 3.1: hello.cs using system; namespace mynamespace class myclass static void main() console.writeline(“hello, wellcome to c# world !“); 可以看出,一个类的实现包含两部分的内容,即类声明和类体,类的定义,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,类的定义其基本格式如下: class 类名 /类声明部分 /类体部分 类体内容 例如: class book /这个类定义一本书 /类体 其中,class是关键字,用来标识类定义的开始,class关键字后面跟着用户定义的类的名称,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,类声明 类是通过关键字class来声明的,以下是类声明的两个例子: class student public class bankcard ,“class student”, “public class bankcard”是类声明,student,bankcard是类的名称,通常类名的第一个字母大写,但这并不一定是必须的。,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,类体 类的定义中,类体用一对大括号括起来 类体由成员变量(简称变量,又称为域)定义和成员方法(简称方法)定义两部分组成,其中变量对应类的静态属性,方法对应类的动态属性,即类的行为和操作。 通常变量在方法定义前定义(并不一定要求),2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,类体 class classname member varible declarations /成员变量声明 method declarations() /成员方法声明 ,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,类体的定义见例子程序 3.2。 程序 3.2:student.cs,using system; namespace mynamespace class student /变量定义部分 public string s_id, s_name, s_sex; public float english, math; /方法定义部分 public void natural(string x, string y, string z) /方法1 显示学生的基/本信息 s_id = x; s_name=y; s_sex=z; console.writeline(s_id+s_name+s_sex); ,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,类体的定义见例子程序 3.2。 程序 3.2:student.cs,public float grade(float x, float y) /方法2 计 /算学生的成绩 float sum; english = x; math = y; sum = english + math ; return sum; ,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,修饰符用于限定类以及类的成员变量和方法的声明。c#中有十余种修饰符,按功能可分为三部分:访问修饰符,类修饰符和成员修饰符。 访问修饰符 访问修饰符用于控制类及其成员被访问的范围,有四种访问修饰符: public:存取不受限制; private:只有包含该成员的类可以存取; internal:只有当前工程可以存取; protected:只有包含该成员的类以及继承的类可以存取。,c#修饰符,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,类修饰符 类修饰符用于表示类的特殊属性,有两种类修饰符: abstract:指定一个类只能作为其它类的基类; sealed:表示一个类不能被继承。,c#修饰符,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,成员修饰符 成员修饰符用于对类成员变量或成员方法进行声明,有八种成员修饰符: abstract:表示该方法没有实现,即没有定义方法体; const:指定域或局部变量的值不能被改动,用于定义常量; event:声明一个事件; extern:指该方法在外部实现;,2019年2月5日,计算机学院,3.1 类的定义与c#修饰符,成员修饰符 override:对由基类继承成员的新实现; readonly:指示一个域只能在声明时以及相同类的内部被赋值; static:指示一个成员属于类型本身,而不是属于特定的对象; virtual:指示一个方法或存取器的实现可以在继承类中被覆盖。,2019年2月5日,计算机学院,3.2 创建对象与构造方法,创建一个对象包括对象的声明、为对象分配内存空间与初始化两个步骤。 声明对象与声明基本数据类型的变量类似,首先说明新建对象所属的类名,然后说明新建对象的名字。对象声明的一般格式如下: 类名 对象名; 例如 student student1;,创建对象,2019年2月5日,计算机学院,3.2 创建对象与构造方法,下面语句为声明的对象分配内存与初始化: 对象名 = new 构造方法(); 例如: student1 = new student();,创建对象,2019年2月5日,计算机学院,3.2 创建对象与构造方法,声明对象和分配内存空间一步完成: 类名 新建对象名 = new构造方法(); 例如: student student1 = new student(); 注意:如果创建了一个类的多个对象,则每个对象将在内存中拥有自己的与其他对象无关的变量和方法,并由自己的方法来操纵自己的变量,这就是面向对象的封装特性的体现。,2019年2月5日,计算机学院,3.2 创建对象与构造方法,要访问或调用一个对象的变量或方法需要首先访问这个对象,然后用算符“.”连接这个对象的某个变量或方法,从而实现对变量的访问和方法的调用。 例如: x = student1.english; y = student1.math; student1.grade(x,y);,访问对象成员,2019年2月5日,计算机学院,3.2 创建对象与构造方法,构造方法的特殊性 构造方法的方法名与类名相同,除了使用类名作为构造方法的名称外,与普通方法的声明类似。 构造方法没有返回类型。 构造方法的主要作用是完成对类的对象的初始化工作。 构造方法由系统调用来创建对象。除了可以由类的另一个构造方法或子类的构造方法调用外,不能显式地直接调用构造方法。,构造方法,2019年2月5日,计算机学院,3.2 创建对象与构造方法,构造方法的特殊性 在创建一个类的新对象的同时,系统会调用该类的构造方法为新对象初始化。 例如: public class myclass public myclass() /构造方法 /初始化代码 ,构造方法,2019年2月5日,计算机学院,3.2 创建对象与构造方法,如果没有为类定义构造方法,系统将自动生成一个默认的无参数的构造方法,并使用默认值初始化对象的成员变量, 构造方法可以带有参数。例如: public class myclass public myclass(int i) /构造方法 /初始化代码 ,2019年2月5日,计算机学院,3.2 创建对象与构造方法,在对象实例化时,使用下面的语句格式: myclass mytest = new myclass(15);,2019年2月5日,计算机学院,3.2 创建对象与构造方法,构造方法可以被重载。一个类中可以定义参数个数不同或参数数据类型不同的同名构造方法(与类同名)。例如:,public class myclass private string p_name; public myclass() /构造方法1,无参数 p_name = “匿名“; public myclass(string str) /构造方法2,有参数 p_name = str; ,2019年2月5日,计算机学院,class point int x, y; point() /构造方法1 x=60; y=100; point(int x, int y) /构造方法2 this.x = x; this.y = y; ,3.2 创建对象与构造方法,构造方法应用举例 例如,假设有一个类point用来描述平面上的一个点,可以为point类定义如下的构造方法,初始化它的域变量x、y:,其中构造方法2定义了两个形式参数,创建对象的语句在调用构造方法时就应该提供几个类型顺序一致的实际参数,指明新建对象各变量的初始值。利用这种机制就可以创建不同初始特性的同类对象。这里,在一个类中定义了两个同名但参数不同的构造方法,使用了方法重载的概念(关于重载以后再详细论述)。 定义了构造方法之后,就可以用如下的语句创建并初始化point对象: point point1 = new point(); point point2 = new point(60,90);,2019年2月5日,计算机学院,3.2 创建对象与构造方法,析构方法用来当对象被使用完了或者不再需要时,释放被对象所占有的系统资源。 关于析构方法,需要说明的是: 一个类只能有一个析构方法。 析构方法不能被继承或重载。,析构方法,2019年2月5日,计算机学院,3.2 创建对象与构造方法,无法显式调用析构方法,它们是被自动调用的。 析构方法既没有修饰,也没有参数,使用“类名”来命名。 例如: myclass() /清理代码 ,析构方法,2019年2月5日,计算机学院,3.2 创建对象与构造方法,abstract 修饰符 凡是用abstract修饰符修饰的类被称为抽象类。 abstract类必须是某一类的父类,它无法直接使用 。抽象类的作用在于给所有子类提供一个统一的接口。 如果属于下列情况,则该类必须被声明为abstract类。 该类中由一个或多个abstract方法(声明但没有定义的方法, abstract修饰的方法将在下节介绍); 该类继承了一个abstract类的一个或多个abstract方法,但并没有提供这些方法的方法体; 该类使用了一个接口,但并没有将该接口的所有方法加以实现。,类的修饰符,2019年2月5日,计算机学院,3.2 创建对象与构造方法,定义一个抽象类的格式如下: abstract class 类名 ,类的修饰符,2019年2月5日,计算机学院,3.2 创建对象与构造方法,sealed 修饰符 由sealed修饰的类叫密封类。如果一个类被sealed修饰符所修饰和限定,说明这个类不可能有子类。 通常,两种情况下需要建立密封类: 没有必要建立类的派生类(子类); 类中只定义了静态变量和静态方法。,2019年2月5日,计算机学院,3.2 创建对象与构造方法,定义一个密封类的格式如下: sealed class 类名 注意:abstract和sealed修饰符不能同时修饰一个类,2019年2月5日,计算机学院,3.2 创建对象与构造方法,在一个类的定义中可以嵌套另一个类的定义。内层类被看作是外层类的一个成员,内层类的方法可以访问外层类的私有成员。当需要访问内层类时,可以使用“.”符号,类的嵌套,2019年2月5日,计算机学院,3.2 创建对象与构造方法,using system; public class vehicles private string stext = “交通工具“; /私有成员 public class autocar /嵌套类 public void run() vehicles av = new vehicles(); console.writeline(av.stext); console.writeline(“car run very fast“); ,类的嵌套,2019年2月5日,计算机学院,3.2 创建对象与构造方法,static void main() autocar acar= new autocar(); acar.run(); /当需要在vehicles类之外访问内层类时,则使用下面的语句: class test static void main() vehicles.autocar acar= new vehicles.autocar(); acar.run(); ,尽管类可以嵌套任意多层,但通常不要使用多层嵌套,以免造成阅读困难。,例子程序 3.4:distance.cs,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,变量及其分类 c#类中的变量按照定义的位置不同,可分为成员变量和局部变量。 在类体中定义变量部分(方法体外)定义的变量称为类的成员变量(简称类变量),在方法体内定义的变量和方法的参数称为局部变量。,变量及其修饰符,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,变量及其分类 成员变量的作用域是整个类,在整个类内部有效,如果一个类中包含多个方法,那么这些方法都可以访问所在类的成员变量; 局部变量则只在它定义的方法内部有效。 成员变量是类的静态属性,可以通过类名.变量名或对象名.变量名访问,而局部变量则不可由其他的类或对象访问。,变量及其修饰符,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,成员变量的修饰符 static 修饰符 常数或者类型声明隐式地是静态成员。 尽管类的实例包含该类所有实例字段的单独副本,但每个静态字段只有一个副本 不能通过实例引用静态成员。然而,可以通过类型名称引用它。 不可以使用 this 来引用静态方法或属性访问器 如果对类应用 static 关键字,则该类的所有成员都必须是静态的。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,成员变量的修饰符 static 修饰符 用static修饰符修饰的变量是仅属于类的静态变量 。 例如:要定义一个类来描述一个班级的所有学生,可以在类的定义中用两个静态变量major 和 grade来描述专业和年级,我们把每个学生看作是这个类的一个对象时,每个学生的专业和年级是相同的,不会因对象的改变而变化。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,成员变量的修饰符 static 修饰符 class computer2006 static string major =“computer”; static int grade=2006; string student_id; string student_name; int student_age; ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,/下面的程序片断定义了两个静态变量来反映某一类卡的共同属性。 class bankcard_bc /定义一个类表示中国银行的中行卡 static string bankname = “bc”; static double poundage ; long cardnumber; int password; double balance; ,上面程序定义的中国银行的中行卡的属性中,每张卡的名称是一样的,都是中行卡,其手续费也是相同的,所以用静态变量表示;但每张卡的卡号、密码和存款余额是不同的,所以用实例变量表示。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,class bankcard_bc static string bankname = “bc“; /静态/变量初值 static double poundage; long cardnumber; int password; double balance; ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,下面的程序 3.5 将验证静态变量是类中每个对象的共享变量。 程序 3.5:teststaticfield.cs public class teststaticfield public static void main() bankcard_bc mybc_1 = new bankcard_bc(); bankcard_bc mybc_2 = new bankcard_bc(); mybc_1.poundage = 0.1; /错误 console.writeline(“第二张bc卡的手续费:“ + convert.tostring(mybc_2.poundage); console.writeline(“bc卡的手续费: “ + convert.string(bankcard_bc.poundage); ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,实例变量和类变量的区别 不同的对象的实例变量将被分配不同的内存空间。 如果类的成员变量中有类变量,那么这个类所产生的所有对象都使用同一个类变量,共享相同的一处内存,改变其中一个对象的类变量的值会直接影响到其他对象的类变量。即同一个类的不同对象共享类变量。例如:,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,class point public static int x = 10; int y; class z point p1 = new point(); point p2 = new point(); p1.x =15; console.writeline(p2.x);/输出为15 ,这里,我们在类point中声明了一个类变量 x, 在另一个类中创建了类point的两个对象p1和p2,如果在程序中使用了p1.x =18;那么这时p1.x和p2.x的值都是18。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,readonly 修饰符 用readonly修饰的变量是只读变量。 例如 readonly float pai = 31.4;,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,readonly 修饰符 using system; public class class1 public readonly string str1=“我是 readonly 变量“; static void main() class1 c=new class1(); console.writeline(c.str1); ,执行程序的输出结果如下: 我是 readonly 变量,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,更改readonly的值 如果在类的定义中显式地定义了一个构造方法,就可以在构造方法中改变readonly 变量的值。 public class class1 public readonly string str1 = ”我是 readonly 变量”; public class1() str1 =”我的值被构造方法修改”; ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,const修饰符 const 关键字用于修改字段或局部变量的声明。它指定字段或局部变量的值是常数,不能被修改。例如: const int x = 0; public const double gravitationalconstant = 6.673e-11; private const string productname = “visual c#“; 常数声明语句中可以声明多个常数,例如: public const double x = 1.0, y = 2.0, z = 3.0;,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,const修饰符 常数可以参与常数表达式,例如: public const int c1 = 5; public const int c2 = c1 + 100; 注意:不允许在常数声明中使用 static 修饰符。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,程序3.6:const_keyword.cs using system; public class consttest class sampleclass public int x; public int y; public const int c1 = 5; public const int c2 = c1 + 5; public sampleclass(int p1, int p2) x = p1; y = p2; ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,程序3.6:const_keyword.cs static void main() sampleclass mc = new sampleclass(11, 22); console.writeline(“x = 0, y = 1“, mc.x, mc.y); console.writeline(“c1 = 0, c2 = 1“, sampleclass.c1, sampleclass.c2 ); 输出 x = 11, y = 22 c1 = 5, c2 = 10,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,该示例说明,如何将常数用作局部变量。 const_keyword_2.cs using system; public class mainclass static void main() const int c = 707; console.writeline(“my local constant = 0“, c); 输出结果如下: my local constant = 707,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,属性访问器 属性是聪明的字段 属性即类的成员变量,用来描述对象的状态,对于public修饰的变量,对外是透明的,可以用“对象名.变量名”访问(静态变量可以用“类名.变量名”访问), 对于用private修饰的变量,在类内部则是通过类的方法属性访问器来访问的,从而实现面向对象的数据隐藏。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,属性访问器 为什么需要属性?,class people private string name; public people(string name) = name; static void main() people p = new people(“zhangsan“); console.writeline(); ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,属性访问器 属性访问器的声明格式如下: 访问修饰符 类型名 属性名 get return 私有变量; set 私有变量 = value; ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,用private修饰的私有变量的值不能被外界直接修改。我们可以为某个类建立一个私有变量及其访问器如下: private string p_name; /声明一个私有变量 public string name /声明一个属性访问器 get return p_name; set p_name = value; ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,方法是类的动态属性,描述了类所具有的功能和操作,即描述类能“做什么”。c方法的定义包括两部分:包括方法的声明和方法体。一般格式如下: method declaration /方法声明部分 methodbody /方法体 ,方法及其修饰符,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,方法声明 最基本的方法声明包括返回类型、方法名和参数列表,格式如下: 返回值类型 方法名(参数列表) 例如: float sum(float x, float y) /方法声明部分 ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,方法体 方法体中包括局部变量的声明和合法的c#语句块。 例如: int times(int x, int y) int s; s = x*y; return s; ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,在声明一个方法时,除包括返回值类型、方法名和参数外,还可以指定方法的修饰符。方法定义的完整结构如下: 修饰符 返回类型 方法名称(参数列表) throw异常列表 /局部变量声明 /c#语句 示例3.7 其中,throw异常列表将在后面程序异常处理中介绍。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,3.方法的修饰符,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,abstract修饰 abstract修饰的方法叫抽象方法。抽象方法是一种只有方法头,没有具体的方法体,其方法体是在继承该方法所在类的子类中实现的。定义抽象方法的目的是给所有子类提供一个统一的接口。例如可以定义一个如下的抽象方法: abstract void print();,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,static 修饰符 用static修饰符修饰的方法称为静态方法,与静态变量类似,静态方法是属于整个类的类方法;而不用static修饰符限定的方法是类的某个具体实例(对象)的方法,又称实例方法。 例子程序 3.8,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,实例方法和类方法的区别 类方法不仅可以由对象调用而且还可以用类名直接调用,而实例方法只能由对象名调用。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,实例方法和类方法的区别 例如: class a int x, y; static float f(int x1, x2) float g(int x1, int x2) ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,class b public void main() a a1=new a(); a.f(2,3); /由类名调用静态方法,合法 a1.f(1,2); /由对象名调用静态方法,不合法 a1.g(3,4); /由对象名调用,合法 a.g(4,5); /由类名调用,不合法 ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,virtual和override修饰符 将一个类中的方法声明为virtual,该方法则可以在该类的子类中被重写。例如: class baseclass public virtual string func1() return “this is in baseclass.“; ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,virtual和override修饰符 当一个子类的方法要重写父类的方法时,要使用override关键字声明。例如: class subclass : baseclass public override string func1() return “this is in subclass.“; 注意:由于virtual只能对类中的实例方法加以定义,因此不能用virtual声明静态的域变量和静态方法。,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,sealed修饰符 用sealed修饰的类是最终类,不能被继承;用sealed修饰的方法不能被子类重写 using system; class baseclass public virtual void final() console.writeline(“this is a base function“); ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,sealed修饰符 class myclass : baseclass public sealed override void final() console.writeline(“this is a final function“); ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,class submyclass:myclass public override void final() console.writeline(“this is a override final function”); /编 译错误 ,2019年2月5日,计算机学院,3.3 类的成员及其修饰符,上例中的final方法必须是另一个类中的方法的重写形式,也就是sealed 必须和override一起定义方法。如果继承父类中的某个方法希望子类中重写的方法是最终的版本,就需要使用sealed定义,这样的方法就不能再被重写了。,2019年2月5日,计算机学院,3.4 访问控制符,访问控制符是一组限定类、变量或方法是否可以被程序里的其他部分访问和调用的修饰符。 类的访问控制符为public 或者internal 变量和方法的访问控制符有五个,分别为 public,protected,internal,private ,protected internal 这些访问控制符在修饰类、变量和方法时,其含是不同的,下面分别讨论这些访问控制符的作用及控制范围。,2019年2月5日,计算机学院,3.4 访问控制符,一个类被声明为公共类,表明它可以被所有的其他类所访问和引用,这里的访问和引用是指这个类作为整体是可见和可使用的,程序的其他部分可以创建这个类的对象、访问这个类内部可见的成员变量和调用它的可见的方法。 如果要访问类中的域或方法,还应将这些域和方法自己的访问控制符也声明为public。 public修饰符会造成安全性和数据封装性下降,所以一般应控制public的使用。,公共访问控制符public,2019年2月5日,计算机学院,3.4 访问控制符,假如一个类没有访问控制符,说明它具有默认的访问控制特性。这种默认的访问控制权规定该类只能被同一个包中的类访问和引用,而不可以被其他包中的类使用。通过声明类的访问控制符可以使整个程序结构清晰、严谨,减少可能产生的类间干扰和错误。 类内的域和方法如果没有访问控制符来限定,也可以被同一个命名空间中的其他类所访问和调用。,默认访问控制符,2019年2月5日,计算机学院,3.4 访问控制符,用protected修饰的成员变量可以被3种类所引用:该类自身、该类的嵌套类及该类的子类。 使用protected修饰符的主要作用是允许其他命名空间中的它的子类来访问父类的特定属性。 protected 标识符使类的成员仅在该类以及当前类的所有派生类中可见,当前类之外的代码无法访问 protected 成员。 类(包括嵌套类)的任何成员都可以使用 protected 修饰符来标记。 不能将 protected 修饰符与其他任何可见性修饰符(public、private)组合。,保护访问控制符protected,2019年2月5日,计算机学院,3.4 访问控制符,用private修饰的域或方法只能被该类自己访问和修改,而不能被任何其他类(包括该类的子类)来获取和引用。 private修饰符用来声明那些类的私有成员,它提供了最高的保护级别。,私有访问控制符private,2019年2月5日,计算机学院,3.4 访问控制符,ae的含义如下: a代表所有的类。 b代表当前类所在的命名空间(也包括当前类)。 c代表当前类的所有子类,它们有的与当前类在同一个命名空间中,有的与当前类在不同的命名空间中。 d代表当前类本身; e代表当前命名空间中的当前类的子类。,综上所述,类、变量和方法的访问控制可以归纳为表3.3 错误众多,2019年2月5日,计算机学院,3.5 c#的继承及其实现,继承实际上是存在于面向对象程序中的两个类之间的一种关系。当一个类拥有另一个类的所有数据和操作时,就称这两个类之间具有继承关系。 被继承的类称为父类或超类、基类,继承了父类或超类的所有数据和操作的类称为子类。 在大多数面向对象语言中,如果类p是子类s的一个父辈,则子类s的一个对象s也是父类p的一个对象。,继承的定义,2019年2月5日,计算机学院,3.5 c#的继承及其实现,继承还有传递性,即如果m1继承m2,m2继承m3,则m1(间接)继承m3。,继承的定义,2019年2月5日,计算机学院,3.5 c#的继承及其实现,当一个子类具有多个父类时,它可以继承它们的结构和方法,这称为多重继承。如图3.2中,m1有父类m2、m3、m4。由此构成的新类具有多个父类的特性与功能,其方法也是所有父类方法的“超集”。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,类的继承 在类的声明中,通过使用关键字“:”来创建一个子类,其格式如下: class sonclass : fatherclass ,继承的实现,2019年2月5日,计算机学院,3.5 c#的继承及其实现,类的继承 如果一个类没有显式地声明继承的父类,那么这个类就默认system.object为父类。,继承的实现,2019年2月5日,计算机学院,3.5 c#的继承及其实现,类的继承 using system; class myclass : object /如果不写object,也默认myclass的/父类是object public void func() console.writeline(“this is a subclass of object“); ,继承的实现,2019年2月5日,计算机学院,3.5 c#的继承及其实现,c#中的继承符合下列规则: 继承是可传递的。如果c从b中派生,b又从a中派生,那么c不仅继承了b中声明的成员,同样也继承了a中的成员。object 类作为所有类的基类。 派生类应当是对基类的扩展。派生类可以添加新的成员,但不能除去已经继承的成员的定义。 构造函数和析构函数不能被继承。除此以外的其他成员,不论对它们定义了怎样的访问方式,都能被继承。基类中成员的访问方式只能决定派生类能否访问它们。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,派生类如果定义了与继承而来的成员同名的新成员,就可以覆盖已继承的成员。但派生类并没有删除这些成员,只是不能访问这些成员。 类可以定义虚方法、虚属性以及虚索引指示器,它的派生类能够重载这些成员,从而实现类可以展示出多态性。 派生类只能从一个类中继承,可以通过接口实现多重继承。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,变量的继承与隐藏 如果子类重新定义一个与从父类那里继承来的域变量完全相同的变量,称为变量的隐藏。这时,子类中定义了与父类同名的变量,即出现了子类变量对同名父类变量的隐藏。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,变量的继承与隐藏 这里所谓隐藏是指子类拥有了两个相同名字的变量,一个继承自父类,另一个由自己定义;当子类执行继承自父类的操作时,处理的是继承自父类的变量;而当子类执行它自己定义的方法时,所操作的就是它自己定义的变量,而把继承自父类的变量“隐藏”起来。 new 关键字可以显式隐藏从基类继承的成员,2019年2月5日,计算机学院,3.5 c#的继承及其实现,变量的继承与隐藏 public class basec public int x; public void invoke() public class derivedc : basec new public int x; ,完整示例,2019年2月5日,计算机学院,3.5 c#的继承及其实现,方法的继承与覆盖 父类的非私有方法作为类的非私有成员可以被子类所继承。 子类也可以重新定义与父类同名的方法,实现对父类方法的覆盖。 子类还可以定义一些父类中没有的方法,以扩展父类的功能。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,方法的继承与覆盖 方法的覆盖与变量的隐藏的不同之处在于:子类隐藏父类的变量只是使之不可见,父类的同名变量在子类对象中仍然占有自己的独立的内存空间;而子类方法对父类同名方法的覆盖将清除父类方法占用的内存,从而使父类方法在子类对象中不复存在。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,方法的继承与覆盖 using system; class baseclass public void draw() console.writeline(“this is in the base”); class subclass : baseclass public new void draw() console.writeline(“this is in the sub”); ,2019年2月5日,计算机学院,3.6 c#语言中的多态与实现,基类的所有成员(实例构造函数、析构函数和静态构造函数除外)都可由其子类继承。 构造方法是类的一种特殊方法,子类调用自己的构造方法时,将追朔到最根部的父类构造方法开始一级一级地调用,基类的构造方法最先调用。,构造方法的继承,2019年2月5日,计算机学院,3.6 c#语言中的多态与实现,using system ; public class person public person( ) console.writeline(“person constructor.“) ; ,构造方法的继承,2019年2月5日,计算机学院,3.6 c#语言中的多态与实现,public class student : person public student( ) console.writeline(“student constructor.“) ; public class mba : student public mba( ) console.writeline(“mba constructor.“) ; ,2019年2月5日,计算机学院,3.6 c#语言中的多态与实现,public static void main( ) mba c = new mba( ) ; ,运行结果如下: person constructor. student constructor. mba constructor.,2019年2月5日,计算机学院,3.6 c#语言中的多态与实现,子类的构造方法可以有如下几种设计方法。 不专门定义自己的构造方法。在这种情况下,每当创建子类对象时,系统自动调用的实际是父类的无参数的构造方法。 定义自己的构造方法并调用父类的含参数构造方法。在这种情况下,子类在父类构造方法定义的初始化操作的基础之上,定义子类自己的初始化操作。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,this与base c#系统默认,每个类都默认具有null、this和base3个成员变量。 其中null代表“空”,代表一个什么也没有的“空”值。在定义一个对象但尚未为其开辟内存单元时,可以指定这个对象为null。 this和base则与继承有密切关系,this和base常用来指代当前对象和父类对象。,更多的情况下,this用来把当前对象的引用作为参数传递给其他的对象或方法。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,this this表示的是当前对象本身,更准确地说,this代表了当前对象的一个引用。利用this可以调用当前对象的方法或使用当前对象的成员变量。例如。 class point int x, y; point(int x, int y) this.x = x; this.y = y; ,更多的情况下,this用来把当前对象的引用作为参数传递给其他的对象或方法。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,this public employee(int weeklysalary, int numberofweeks) : this(weeklysalary * numberofweeks) ,更多的情况下,this用来把当前对象的引用作为参数传递给其他的对象或方法。,2019年2月5日,计算机学院,3.5 c#的继承及其实现,base base表示的是当前对象的直接父类对象,是当前对象的直接父类对象的引用。所谓直接父类是相对于当前对象的其他“祖先”类而言的。 需要注意的是:this和base是属于类的有特指的成员变量,只能用来代表当前对象和当前对象的父对象,而不能像其他类的属性一样随意引用。下面语句中的用法都是错误的。 point p1 = new point(); p1.this.getx(); /错误 p2.base.gety();/错误,2019年2月5日,计算机学院,3.6 c#语言中的多态与实现,所谓多态,是指一个程序中同名的不同方法共存的情况,指同名函数具有不同的行为。 c#中多态的实现可以通过方法的重载和类的继承来实现,什么是多态,2019年2月5日,计算机学院,3.6 c#语言中的多态与实现,重载则是在同一个类中定义多个同名方法的情况。 方法签名由方法名称和一个参数列表(方法的参数的顺序和类型)组成。只要签名不同,就可以在一种类型内定义具有相同名称的多种方法。当定义两种或多种具有相同名称的方法时,就称作重载。 构成重载的条件:参数类型不同,参数个数不同,参数顺序不同,在上面这个例子中,在同一个类myclass中,定义了3个同名的方法print,方法的参数名称与个数也一样都是x,但其参数的类型不同,在主方法main()中调用该方法时所使用的实参类型不同,来区别不同的方法。,使用方法重载实现多态,2019年2月5日,计算机学院,3.6 c#语言中的多态与实现,using system; class mycla

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论