《Java程序设计及应用031.ppt》由会员分享,可在线阅读,更多相关《Java程序设计及应用031.ppt(31页珍藏版)》请在三一办公上搜索。
1、第6讲:面向对象(1),内容提要,人与计算机的关系物理世界与面向对象 类与对象 面向对象基本特征封装访问修饰符继承多态重载覆盖,教学要求,物理世界与面向对象的思想、方法 计算机面向对象的思想、方法 如何定义一个类以及创建其实例面向对象的三个基本特征,人与计算机的关系,人处于主体地位,计算机只能处于从属地位。计算机必须能够模拟这个物理世界。计算机是个小世界,而物理世界是个大世界,小世界来源于大世界,物理世界的认知,(1)世界由万物构成。(2)事物是运动的、发展的、变化的。(3)事物之间的关系是复杂的、多变的。,事物的基本特征,(1)封装。保护功能相对独立性(2)继承 加快事物发展的速度提高事物发
2、展的质量(3)多态。透过现象抓本质,以不变应万变。,事物间的关系,泛化关系(Generalization)聚合关系(Aggregation)组合关系(Composition)依赖关系(Dependency)关联(Association)。,类与对象,世界由万物构成,经由前面的学习,我们知道研究物理世界要用分类的方法。在面向对象程序设计中用类(class)来模拟一类事物。类的定义需用关键字 class,定义一个简单类的语法如下:class 类名/该行称为类头,大括号之间的部分称为类体 零或多个属性;零或多个方法;其中属性的定义格式有两种,如下:(1)类型 属性名=属性值;(2)类型 属性名1=属
3、性值1,属性名2=属性值2,.;,类定义举例,1 class Student 2 String sno;/学号 3 String name,major;/姓名,专业 4 int age;/年龄 5 6 void showInfo()7 System.out.println(学号:+sno+t姓名:+name+8 t年龄:+age+t专业:+major);9 10 11 Student()/第一种构造方法 12 13 14/*第二种构造方法*/15 Student(String sno1,String name1,String major1,int age1)16 sno=sno1;17 nam
4、e=name1;18 major=major1;19 age=age1;20 21 22,实例对象,实例对象可以使用类的构造方法和new关键字构造出来。语法为:类名 对象引用=new 构造方法;例如:Student t=new Student();,类的成员,1成员属性的定义成员属性也称为成员变量,定义一个成员属性,格式为:修饰符 类型 成员属性名=成员属性值;例如:int a=10;int b;String s1;String s2=new String(abc);其中修饰符暂不讲,详见3.8节。2成员方法的定义语法为:修饰符 返回类型 方法名(形式参数列表)throws 异常类型列表/方法
5、头 执行语句块;/方法体,成员变量的初始化,构造方法,当使用new关键字创建一个类实例对象时,系统(JVM)会自动调用该类的构造方法来完成类实例对象的构建,从而构造方法对类定义来说是必须的。那么我们在类中如何声明一个构造方法呢?如下:访问修饰符 类名(参数列表)/.,构造方法的几点说明,(1)构造方法的访问修饰符可以是public,protected或者缺省(即不用访问修饰符),但不允许private。(2)构造方法的名称和类名相同,但没有返回类型。(3)若没有定义任何构造方法,则在编译阶段编译器会在编译后的字节码文件中插入一个默认的构造方法,默认的构造方法是:无参数列表,访问修饰符和类的访问
6、修饰符相同,方法体内为空。(4)构造方法本身不能递归调用。(5)构造方法体的最后一行语句可以是空的return语句,即“return;”,也可以不用return语句。(6)可在一个类中定义多个构造方法,其区别在于参数列表不同,这是构造方法的重载。关于重载,详见3.5.1节。,封装的Java表达与访问修饰符,封装有两个作用:保护作用和增强对象的独立性。保护作用是通过设置访问修饰符来实现的。访问修饰符有4个:public、protected、默认访问修饰符、private。其中默认访问修饰符就是没有修饰符,即不用public、protected、private中的任何一个。访问修饰符用于对类、成员
7、属性和成员方法设置访问权限,对它们实施保护作用。,访问修饰符,(1)public可用于修饰类、成员变量和方法。表明该成员变量和方法是共有的,能在任何情况下被访问。Java应用程序中的main()方法必须用public来修饰(否则能通过编译,但不能运行),就是为了使JVM能够访问它。在一个源代码文件中最多只能定义一个public类,且该类名必须和源代码文件同名。,(2)protected只能用于修饰成员属性或成员方法,不能修饰类。用protected修饰的成员可以被同包(package)下其他类方法访问,也可以被不同包下的子类方法访问。(3)默认访问修饰符修饰的成员只能被同包下的类方法访问。(4
8、)private修饰的成员只能被同类中的方法来访问。这4种访问修饰符的访问范围由大到小,或安全保护程度由低到高依次是:public、protected、默认访问修饰符、private。,举例,1 class T 2 private String s=abc;3 public String getS()/称作访问方法 4 return s;5 6 7 8 class Test 9 public void func()10 T t=new T();11 String s1=t.s;/非法 12 String s2=t.getS();/合法 13 14,继承,继承的作用:一是提高了软件的开发速度,二
9、是提高了开发软件的质量。继承有广义和狭义之分。广义的继承有些拿来主义的味道,因此在Java中分为横向手法和纵向手法。横向手法是指采用import语句来继承要使用的类或Java接口;纵向手法是指采用extends关键字来实现的手法。狭义的继承就是只指纵向手法。无论是横向手法还是纵向手法都不违背继承的两个作用。在面向对象编程中继承概念通常是指狭义的。,举例,1 class Student 2 public void func()3 System.out.println(Student);4 5 6 7 class Freshman extends Student 8 public static v
10、oid main(String args)9 Freshman b=new Freshman();10 11/*能够调用 Freshman 对象的 func 方法,12*说明 func 来自 Student.13*/14 b.func();15 16,Java不支持多重继承,单继承使Java的继承关系很简单,一个类只能有一个父类,易于管理程序,同时一个类可以实现多个接口(详见3.6节),从而克服单继承的缺点。继承描述的是一种is a关系,例如上例Freshman is a Student,是一种特殊与一般的关系。继承是在两个不同的类之间发生的一种关系,被继承的内容是建立在访问权限(受访问修饰符
11、控制)可访问的基础上的,有以下结论。(1)子类的访问修饰符不小于父类的访问修饰符(private默认protectedpublic)。(2)private修饰的成员不可以被继承。(3)默认访问修饰符修饰的成员只能被同包下的其他类继承。(4)构造方法不能被继承。父类+属性1#属性2-属性3+方法()子类图3.2 类的继承关系(5)不管父类是否是abstract的,子类可以声明为abstract的,同样,父类中的方法不管是否是abstract的,在子类中都可以把该方法声明为abstract的。,继承的UML表示,this与super关键字,this代表类实例对象自身,super代表父类实例对象。在
12、一个类中可以定义多个构造方法,若在一个构造方法中调用另一个构造方法时,必须使用this。super不可以连续使用。,多态的Java表达,ava表达多态的方式有两种:一是重载(overload)二是覆盖(override)。,重载,重载是指在同一个类中定义多个同名方法,要求他们的参数列表不同。区分重载方法只 能通过参数列表,例如:1 class T 2 public void func()3 System.out.println(func();4 func(10);/输出结果为 a=10 5 6 public void func(int a)7 System.out.println(a=+a);
13、8 9 protected int func(int a,int b).10 String func(String s).11,重载说明,重载方法对修饰符列表、返回类型、抛出异常类型(详见第5章)是否相同均不作要求,区别仅仅在于参数列表。重载方法是程序的一种静态结构,即重载方法之间的关系在编译器编译后就确定了,不会随程序代码的执行来动态确定,这一点和覆盖不同,覆盖是程序的一种动态结构。正是由于重载是一种静态结构,所以完全可以把重载方法看作是各自不同的方法,这一点与不同名的方法之间的关系没有什么区别。在一个重载方法内可以直接调用另外一个重载方法,但在一个重载的构造方法内却不能直接调用另一个重载的
14、构造方法,必须使用this。,覆盖,覆盖是指在具有继承关系的两个不同类中定义同名方法,是建立在继承的基础上的,要求如下:(1)private方法不能被覆盖,因为private方法不允许被继承。(2)方法名、返回类型、参数列表必须相同。(3)子类方法的访问修饰符父类方法的访问修饰符。(4)子类中的覆盖方法的修饰符不能是final、static,因为final修饰的标识符是不可改变的,而覆盖就是对父类方法的一种修改,若父类方法不需要修改,只采用继承就好了。static是一种静态行为,而覆盖则是一种动态行为。(5)子类中的覆盖方法声明的抛出异常不能是父类被覆盖方法声明的抛出异常的祖先类,只能是其子类
15、或同类。子类中的覆盖方法也可以不声明抛出异常,尽管父类中的被覆盖方法声明抛出了异常。详见第5章。,成员变量的覆盖,方法可以被覆盖,成员变量也可以被覆盖。举例1 class T1 2 public String s=T1;3 public String getS()4 return s;5 6 7 class T2 extends T1 8 public String s=T2;9 public String getS()10 return s;11 12 13 class Test 14 public static void main(String args)15 T1 t1=new T1()
16、;16 T2 t2=new T2();17 18 System.out.println(t1.s);/输出 T1 19 System.out.println(t1.getS();/输出 T1 20 System.out.println(t2.s);/输出 T2 21 System.out.println(t2.getS();/输出 T2 22 23 t1=t2;24 System.out.println(t1.s);/输出 T1,而不是 T2 25 System.out.println(t1.getS();/输出 T2,而不是 T1 26 27,程序分析,从上面程序24、25两行代码的输出结果
17、,可以得出如下结论:(1)成员变量可以被覆盖。(2)若直接访问发生覆盖的成员变量,则只能访问引用类型的成员变量,上例中第24行,虽然t1指向的对象是T2类型的,但引用t1的类型是T1,故输出结果是T1。(3)若通过发生覆盖的方法来访问发生覆盖的成员变量,则访问的成员变量和方法属于同一个对象,例如第25行,t1指向的对象是T2类型的,方法getS()是属于T2实例对象的,故访问的变量是T2实例对象的。所以,若上例中没有第8行代码,则成员变量s会被继承,从而第25行代码的输出是T1。若没有第911行代码,会发生方法的继承,但方法本身还是类T1的,不是T2的,故第25行代码的输出是T1。,小结,物理世界与面向对象 类与对象 面向对象基本特征封装访问修饰符继承多态重载覆盖,作业,习题 3:1,2,3,