JAVA程序员培训定制课程c06.ppt
第六章,Java类设计,2,本章内容,Java类的继承方法的重载、重写多态性及其应用成员访问控制对象的创建和初始化细节几种常用的Java类,3,类的继承(1),为描述和处理个人信息,定义类Person:,public class Person public String name;public int age;public Date birthDate;public String getInfo().,4,类的继承(2),为描述和处理学生信息,定义类Student:,public class Student public String name;public int age;public Date birthDate;public String school;public String getInfo().,5,类的继承(3),通过继承,简化Student类的定义:,public class Person public String name;public int age;public Date birthDate;public String getInfo().public class Student extends Person public String school;,6,类的继承(4),类继承语法规则:class extends*Object类是所有Java类的最高层父类Java只支持单继承,不允许多重继承一个子类只能有一个父类一个父类可以继承出多个子类,7,单继承举例(1),8,单继承举例(2),public class TestAnimals public static void main(String args)Horse b=new Horse();System.out.println(b.getI();class Animal private int i=1;public int getI()return i;public void setI(int i)this.i=i;class Horse extends Animal int i=2;,9,访问控制,可以对Java类中定义的属性和方法进行访问控制-规定不同的保护等级:,10,访问控制举例(1),class Parent private int f1=1;int f2=2;protected int f3=3;public int f4=4;private void fm1()System.out.println(in fm1()f1=+f1);void fm2()System.out.println(in fm2()f2=+f2);protected void fm3()System.out.println(in fm3()f3=+f3);public void fm4()System.out.println(in fm4()f4=+f4);,11,访问控制举例(2),class Child extends Parentprivate int c1=21;public int c2=22;private void cm1()System.out.println(in cm1()c1=+c1);public void cm2()System.out.println(in cm2()c2=+c2);public static void main(String args)int i;Parent p=new Parent();i=p.f2;/i=p.f3;i=p.f4;p.fm2();/p.fm3();p.fm4();Child c=new Child();i=c.f2;/i=c.f3;i=c.f4;i=c.c1;/i=c.c2;c.cm1();c.cm2();,12,访问控制分析,f1_private,f2_default,c2_public,f3_protected,f4_public,c1_private,内存空间中子类对象携带的数据,子类的对象可以调用的方法,fm2()_default,fm3()_ protected,fm4()_ public,cm2()_public,cm1()_private,父类Parent和子类Child在同一包中定义时:,13,Ex,改造上述应用程序后,分析其结果,体会Java访问控制机制,可分下述几种情形:应用程序入口main()方法定义在一个非子类中Parent和Child类位于不同包中Parent和Child类位于不同包中,main()方法定义在不同包内的非子类中,14,方法的重写,在子类中可以根据需要对从父类中继承来的方法进行改造-方法的重写重写方法必须和被重写方法具有相同的方法名称、参数列表和返回值类型重写方法不能使用比被重写方法更严格的访问权限,15,方法重写举例(1),public class Person protected String name;protected int age;protected Date birthDate;/java.util包中定义过类Datepublic String getInfo()return Name:+name+n+age:+age;public class Student extends Person protected String school;public String getInfo()return Name:+name+nage:+age+nschool:+school;,16,方法重写举例(2),public class Parent public void method1()public class Child extends Parent private void method1()/illegalpublic class UseBoth public void doOtherThing()Parent p1=new Parent();Child p2=new Child();p1.method1();p2.method1();,17,关键字super,在Java类中使用super来引用父类的成分super可用于访问父类中定义的属性super可用于调用父类中定义的成员方法super可用于在子类构造方法中调用父类的构造方法super的追溯不仅于直接父类,18,关键字super举例,public class Person private String name;private int age;private Date birthDate;public String getInfo()return Name:+name+nage:+age;public class Student extends Person private String school=New Oriental;public String getSchool()return school;public String getInfo()/调用父类的方法 return super.getInfo()+nschool:+school;,19,多态性(1),多态-在Java中,子类的对象可以替代父类的对象使用一个对象只能有一种确定的数据类型一个引用类型变量可能指向(引用)多种不同类型的对象Person p=new Student();Object o=new Person();o=new Student();,20,多态性(2),一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法Student m=new Student();m.school=pku;/合法Person e=new Student();e.school=pku;/非法,21,虚方法调用(Virtual Method Invocation),正常的方法调用 Person e=new Person();e.getInfo();Student e=new Student();e.getInfo();虚拟方法调用(多态情况下)Person e=new Student();e.getInfo();编译时类型和运行时类型,22,多态性应用举例(1),同类收集(homogenous collections)MyDate m=new MyDate2;m0=new MyDate(22,12,1964);m1=new MyDate(22,7,1964);异类收集(heterogeneous collections)Person p=new Person3;p0=new Student();p1=new Person();p2=new Graduate();,23,多态性应用举例(2),方法声明的参数类型为父类类型,可以使用子类的对象作为实参调用该方法public class Test public void method(Person e)/e.getInfo();public static void main(Stirng args)Test t=new Test();Student m=new Student();t.method(m);,24,instanceof 操作符,public class Person extends Object public class Student extends Person public class Graduate extends Person-public void method1(Person e)if(e instanceof Student)/处理Student类型及其子类类型对象 else if(e instanceof Graduate)/处理Graduate类型及其子类类型对象 else/处理Person类型对象,25,对象造型(Casting),对Java对象的强制类型转换称为造型在造型前可以使用instanceof操作符测试一个对象的类型从子类到父类的类型转换可以自动进行从父类到子类的类型转换必须通过造型(强制类型转换)实现无继承关系的引用类型间的转换是非法的,26,对象造型举例,public class Test/Person及Student类的定义见第17页 public void method(Person e)System.out.pritnln(e.getschool();/非法 if(e intstanceof Student)Student me=(Student)e;System.out.pritnln(me.getschool();public static void main(Stirng args)Test t=new Test();Student m=new Student();t.method(m);,27,方法名重载,在同一个类中可以定义多个同名方法-方法名重载public class PrintStreampublic void println(int i)public void println(float f)public void println(String s)重载方法的参数列表必须不同 重载方法的返回值类型可以相同,也可以不同,28,构造方法重载,构造方法重载举例:public class Personpublic Person(String name,int age,Date d)public Person(String name,int age)public Person(String name,Date d)构造方法重载,参数列表必须不同可以在构造方法的第一行使用this关键字调用其它(重载的)构造方法,29,构造方法重载举例,public class Person private String name;private int age;private Date birthDate;public Person(String name,int age,Date d)this.name=name;this.age=age;this.birthDate=d;public Person(String name,int age)this(name,age,null);public Person(String name,Date d)this(name,30,d);public Person(String name)this(name,30);,30,构造方法不能继承,子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法在一个Java类中可以通过两种方式获得构造方法使用系统默认的无参构造方法显式定义一个或多个构造方法一旦显式定义了构造方法,则系统不再提供默认构造方法,31,调用父类构造方法,在子类的构造方法中可使用super(argument_list)语句调用父类的构造方法如果子类的构造方法中没有显示地调用父类构造方法,也没有使用this关键字调用重载的其它构造方法,则系统默认调用父类无参数的构造方法如果子类构造方法中既未显式调用父类构造方法,而父类中又没有无参的构造方法,则编译出错,32,调用父类构造方法举例(1),1 public class Person 2 3 private String name;4 private int age;5private Date birthDate;67 public Person(String name,int age,Date d)8 this.name=name;9 this.age=age;10 this.birthDate=d;11 12 public Person(String name,int age)13 this(name,age,null);14 15 public Person(String name,Date d)16 this(name,30,d);17 18 public Person(String name)19 this(name,30);2021/22,33,调用父类构造方法举例(2),1 public class Student extends Person 2 private String school;34 public Student(String name,int age,String s)5 super(name,age);6 school=s;7 8 public Student(String name,String s)9 super(name);10 school=s;11 12 public Student(String s)/编译出错:no super()13 school=s;14 15,34,对象构造和初始化细节,分配存储空间并进行默认的初始化按下述步骤初始化实例变量绑定构造方法参数如有this()调用,则调用相应的重载构造方法,然后跳转到步骤5显式或隐式追溯调用父类的构造方法(Object类除外)进行实例变量的显式初始化操作执行当前构造方法的方法体,35,构造和初始化对象举例,public class Object public Object().public class Person extends Object private String name;private int age=0;private Date birthDate;public Person(String n,Date d)/implicit super();name=n;birthDate=d;public Person(String n)this(n,null);public class Student extends Person private String school;public Student(String n,String d)super(n);school=d;,36,Ex2 初始化过程引申,public class Person private String name;private int age=0;private Date birthDate;private String info;public Person(String n,Date d)/step 3 name=n;birthDate=d;info=getInfo();public Person(String n)this(n,null);/step 2 public String getInfo()return Name:+name+nage:+age+nBirth Date:+birthDate;public class Student extends Person private String school;public Student(String n,String d)/step 0 super(n);/step 1 school=d;/step 4 public String getInfo()return super.getInfo()+nSchool:+school;,37,Object 类,Object类是所有Java类的根父类如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类 public class Person.等价于:public class Person extends Object.,38,=操作符与equals方法,=操作符与equals方法的区别:引用类型比较引用;基本类型比较值;equals()方法只能比较引用类型,=可以比较引用类型及基本类型;特例:当用equals()方法进行比较时,对类File、String、Date及封装类(Wrapper Class)来说,是比较类型及内容而不考虑引用的是否是同一个实例;用=进行比较时,符号两边的数据类型必须一致(可自动转换的基本数据类型除外),否则编译出错;,39,=操作符与equals方法举例,class TestEquals/请自行定义能满足需要的MyDate类 public static void main(String args)MyDate m1=new MyDate(24,3,2001);MyDate m2=new MyDate(24,3,2001);if(m1=m2)System.out.println(m1=m2);else System.out.println(m1!=m2);if(m1.equals(m2)System.out.println(m1 is equal to m2);else System.out.println(m1 is not equal to m2);Integer n1=new Integer(2);Integer n2=new Integer(2);if(n1.equals(n2)System.out.println(n1 equals n2);else System.out.println(n1 not equals n2);,40,toString 方法,toString()方法在Object类中定义,其返回值是String类型,描述当前对象的有关信息在进行String与其它类型数据的连接操作时,自动调用toString()方法可以根据需要在用户自定义类型中重写toString()方法基本类型数据转换为String类型时,调用了对应封装类的toString()方法,41,封装类,针对八种基本定义相应的引用类型封装类,42,封装类用法举例,int i=500;Integer t=new Integer(i);int j=t.intValue();/j=500String s=t.toString();/s=500String s1=Integer.toString(314);/s1=314,43,Ex3,练习M3-38页=操作符与equals方法用法例子;其中用到的数据类型MyDate 的定义见m6TestEqualsMyDate.java将1中的数据类型MyDate 改为String或封装类型;体会其区别;参见m6TestEquals_StringTestEquals_String.java,