1、 Java类的继承 方法的重写、覆盖 访问控制 super 关键字 多态性及其应用 Object 类及其主要方法 JavaJava类的继承类的继承 方法的重写、覆盖 多态性及其应用 成员访问控制 对象的创建和初始化细节 几种常用的Java类 为描述和处理个人个人信息,定义类Person:public class Person public String name;public int age;public Date birthDate;public String getInfo().PersonPerson+name:String+age:int+birthDate:Date+getInfo(
2、):String 为描述和处理学生学生信息,定义类Student:public class Student public String name;public int age;public Date birthDate;public String school;public String getInfo().StudentStudent+name:String+age:int+birthDate:Date+school:String+getInfo():String 通过继承继承,简化Student类的定义:public class Person public String name;publ
3、ic int age;public Date birthDate;public String getInfo().public class Student extends Person public String school;/Student类继承了父类Person的所有属性和方法,并增加了一个属性school。Person中的属性和方法,Student都可以利用。PersonPerson+name:String+age:int+birthDate:Date+getInfo():StringStudentStudent+school:String类继承语法规则:class class ext
4、endsextends Java只支持单继承,不允许多重继承一个子类只能有一个直接父类一个父类可以派生出多个子类PersonPerson+name:String+age:int+birthDate:Date+getInfo():StringStudentStudent+school:StringSoldierSoldierOfficerOfficerGraduateGraduate+major:String+register():void父类子类孙子类子类继承了父类,就继承了父类的方法和属性。在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和方法。因而,子类通常比父类的功能更多子类
5、通常比父类的功能更多。在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”。关于继承的规则:子类不能继承父类中私有的子类不能继承父类中私有的(private)(private)的成员变量和方法的成员变量和方法。1.(1)定义一个ManKind类,包括 成员变量 int sex 和 int salary;方法 void manOrWorman():根据sex的值显示“man”(sex=1)或者“women”(sex=0);方法 void employeed():根据salary的值显示“no job”(salary=0)或者“job”(salary!=
6、0)。(2)定义类Kids1继承ManKind,并包括 成员变量 int yearsOld;方法 printAge()打印 yearsOld 的值。(3)在Kids1类的main方法中实例化Kids1的对象 someKid,用该对象访问其父类的成员变量及方法。2.根据下图实现类。在TestCylinder类中创建Cylinder类的对象,设置圆柱的底面半径和高,并输出圆柱的体积。Circle (Circle (圆圆)-radius:double Circle():构造方法,将radius属性初始化为1+setRadius(double radius):void+getRadius():doub
7、le+findArea():double 计算圆的面积Cylinder (Cylinder (圆柱圆柱)-length:doubleCylinder():构造方法,将length属性初始化为1+setLength(double length):void+getLength():double+findVolume():double 计算圆柱体积 Java类的继承 访问控制访问控制 方法的重载、覆盖 super 关键字 多态性及其应用 Object 类及其主要方法修饰符修饰符同一个类同一个类同一个包同一个包子类子类整体整体privateprivateYesdefaultdefaultYesYesp
8、rotectedprotectedYesYesYespublicpublicYesYesYesYes可以对Java类中定义的属性属性和方法方法进行访问控制-规定不同的保护等级:public、protected、default、privateclass 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);protecte
9、d void fm3()System.out.println(in fm3()f3=+f3);public void fm4()System.out.println(in fm4()f4=+f4);class Child extends Parent /设父类和子类在同一个包内private 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 ma
10、in(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();c.fm2();c.fm3();c.fm4()f2_defaultc2_publicf3_protectedf4_publicc1_private子类对象可以访问的数据子类的对象可以调用的方法fm2()_defaultfm3()_ protectedfm4()_ publ
11、iccm2()_publiccm1()_private父类Parent和子类Child在同一包中定义时:Java类的继承 访问控制 方法的重写、覆盖方法的重写、覆盖 super 关键字 多态性及其应用 Object 类及其主要方法 在子类中可以根据需要对从父类中继承来的方法进行改造覆盖方法覆盖方法(方法的重置、重置、重写重写),在程序执行时,子类的方法将覆盖父类的方法。覆盖方法必须和被覆盖方法具有相同的方法名称、参数列表和返回值类型。方法名称、参数列表和返回值类型。覆盖方法不能使用比被覆盖方法更严格的访问权限。覆盖方法不能使用比被覆盖方法更严格的访问权限。public class Person
12、 public String name;public int age;public String getInfo()public String getInfo()return Name:+name+n+age:+age;public class Student extends Person public String school;public String getInfo()public String getInfo()/覆盖方法 return Name:+name+nage:+age +nschool:+school;public static void main(String args)
13、Student s1=new Student();s1.name=Bob;s1.age=20;s1.school=school2;System.out.println(s1.getInfo();/Name:Bob age:20 school:school2 Person p1=new Person();p1.getInfo();/调用Person类的getInfo()方法Student s1=new Student();s1.getInfo();/调用Student类的getInfo()方法这是一种“多态性”:同名的方法,用不同的对象来区分调用的是哪一个方法。class Parent publ
14、ic public void method1()class Child extends Parent private private void method1()/非法,子类中的method1()的访问权限private比被覆盖方法的访问权限public弱public class UseBoth public void doOtherThing()Parent p1=new Parent();Child p2=new Child();Child p2=new Child();p1.method1();p2.method1();修改练习1中定义的类Kids1,在Kids1中重新定义employe
15、d()方法,覆盖父类ManKind中定义的employed()方法,输出“Kids should study and no job.”Java类的继承访问控制方法的重载、覆盖super super 关键字关键字super super 关键字关键字子类对象的实例化过程子类对象的实例化过程多态性及其应用Object 类及其主要方法 在Java类中使用super来引用父类的成分 super可用于访问父类中定义的属性 如果使用super关键字引用父类属性或者方法必须在方法块的第一行出现 super可用于调用父类中定义的成员方法 super可用于在子类构造方法中调用父类的构造方法 super的追溯不仅限
16、于直接父类 public class Person private String name;private int age;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.getInfosuper.getInfo()+nschool:+
17、school;1.修改练习3中定义的类Kids1中employed()方法,在该方法中调用父类ManKind的employed()方法,然后再输出“but Kids should study and no job.”2.修改练习1中定义的Cylinder类,在Cylinder类中覆盖findArea()方法,计算圆柱的表面积。考虑:findVolume方法怎样做相应的修改?在TestCylinder类中创建Cylinder类的对象,设置圆柱的底面半径和高,并输出圆柱的表面积和体积。附加题:在TestCylinder类中创建一个Circle类的对象,设置圆的半径,计算输出圆的面积。体会父类和子类
18、成员的分别调用。子类继承父类所有的成员变量和成员方法,但不继承父类的构造方法 在一个Java类中可以通过两种方式获得构造方法 使用系统默认的无参数构造方法 显式定义一个或多个构造方法 一旦显式定义了构造方法,则系统不再提供默认构造方法 在子类的构造方法中在子类的构造方法中可使用super(参数列表)语句调用父类的构造方法 如果子类的构造方法中没有显示地调用父类构造方法,也没有使用this关键字调用重载的其它构造方法,则系统默认调用父类无参数的构造方法 如果子类构造方法中既未显式调用父类构造方法,而父类中又没有无参的构造方法,则编译出错1 public class Person 2 3 priv
19、ate 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(Strin
20、g name)19 this(name,30);2021/22 1 public class Student extends Person 2 private String school;34 public Student(String name,int age,String s)5 super(namesuper(name,age),age);6 school=s;7 8 public Student(String namename,String s)9 super(name)super(name);10 school=s;11 12 public Student(String s)1313
21、 /编译出错编译出错:no super(),:no super(),系统将调用父类无参数的构造方法。系统将调用父类无参数的构造方法。13 school=s;14 15 思考 1).为什么super()和this()调用语句不能同时在一个构造函数中出现?2).为什么super()或this()调用语句只能作为构造函数中的第一句出现?子类对象的实例化过程练习7 修改练习1中定义的Circle类和Cylinder类的构造方法,利用构造方法参数为对象的所有属性赋初值。Java类的继承方法的重载、覆盖访问控制super 关键字多态性及其应用多态性及其应用多态多态instanceof instanceof
22、 运算符运算符类型转换异常类型转换异常Object 类及其主要方法 多态在Java中,子类的对象可以替代父类的对象使用 一个变量只能有一种确定的数据类型 一个引用类型变量可能指向(引用)多种不同类型的对象Person p=new Student();Object o=new Person();/Object();/Object类型的变量类型的变量o o,指向,指向PersonPerson类型的对象类型的对象o=new Student();/Object/Object类型的变量类型的变量o o,指向,指向StudentStudent类型的对象类型的对象父类类型的变量可以指向子类的对象一个引用类型
23、变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法Student m=new Student();m.school=“pku”;/合法,Student类有school成员变量Person e=new Student();e.school=“pku”;/非法,Person类没有school成员变量 属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。(Virtual Method Invocation)正常的方法调用正常的方法调用 Person e=new Person();e.getInfo();Student
24、e=new Student();e.getInfo();虚拟方法调用虚拟方法调用(多态情况下多态情况下)Person e=new Student();e.getInfo();/调用Student类的getInfo()方法 编译时类型和运行时类型编译时类型和运行时类型编译时编译时e e为为PersonPerson类型,而方法的调用是在运行时确定的,所以调用的是类型,而方法的调用是在运行时确定的,所以调用的是StudentStudent类的类的getInfo()getInfo()方法。方法。动态绑定动态绑定方法声明的形参类型为方法声明的形参类型为父类父类类型,可以使用类型,可以使用子类的对象子类的
25、对象作为实参调用该方法作为实参调用该方法public class Test public class Test public void method(Person e)public void method(Person e)/e.getInfo();e.getInfo();public static void main(Stirng args)public static void main(Stirng args)Test t=new Test();Test t=new Test();Student m=new Student();Student m=new Student();t.metho
26、d(m);t.method(m);/子类的对象子类的对象mm传送给父类类型的参数传送给父类类型的参数e e x instanceof A:检验x是否为类A的对象,返回值为boolean型。要求x所属的类与类A必须是子类和父类的关系,否则编译错误。如果x属于类A的子类B,x instanceof A值也为true。public class Person extends Object public class Person extends Object public class Student extends Person public class Student extends Person p
27、ublic class Graduate extends Person public class Graduate extends Person-public void method1(Person e)public void method1(Person e)if(e instanceof Person)if(e instanceof Person)/处理处理PersonPerson类及其子类对象类及其子类对象if(e instanceof Student)if(e instanceof Student)/处理处理StudentStudent类及其子类对象类及其子类对象if(e instan
28、ceof Graduate)if(e instanceof Graduate)/处理处理GraduateGraduate类及其子类对象类及其子类对象 class Person protected String name=person;protected int age=50;public String getInfo()return Name:+name+n+age:+age;class Student extends Person protected String school=pku;public String getInfo()return Name:+name+nage:+age +n
29、school:+school;class Graduate extends Studentpublic String major=IT;public String getInfo()return Name:+name+nage:+age +nschool:+school+nmajor:+major;建立建立TestInstance TestInstance 类,在类中定义方法类,在类中定义方法method1(Person e);method1(Person e);在在method1method1中中:(1)(1)根据根据e e的类型调用相应类的的类型调用相应类的getInfo()getInfo
30、()方法。方法。(2)(2)根据根据e e的类型执行:的类型执行:如果如果e e为为PersonPerson类的对象,输出:类的对象,输出:“a person”;a person”;如果如果e e为为StudentStudent类的对象,输出类的对象,输出“a student”a student”“a person”“a person”如果如果e e为为GraduateGraduate类的对象,输出:类的对象,输出:“a graduated student”a graduated student”“a student”“a student”“a person”“a person”(ex8)(e
31、x8)基本数据类型的Casting:小的数据类型可以自动转换成大的数据类型如long g=20;double d=12.0f可以把大的数据类型强制转换(casting)成小的数据类型如 floate f=(float)12.0 int a=(int)1200L 对Java对象的强制类型转换称为造型 从子类到父类的类型转换可以自动进行 从父类到子类的类型转换必须通过造型(强制类型转换)实现 无继承关系的引用类型间的转换是非法的 在造型前可以使用instanceof操作符测试一个对象的类型public class Test public void method(Person e)/设Person类
32、中没有getschool()方法 System.out.pritnln(e.getschool();/非法,编译时错误 if(e instanceof Student)Student me=(Student)e;/将e强制转换为Student类型 System.out.pritnln(me.getschool();public static void main(Stirng args)Test t=new Test();Student m=new Student();t.method(m);Java类的继承方法的重载、覆盖访问控制super 关键字多态性及其应用Object Object 类及
33、其主要方法类及其主要方法Object Object 类类equals()equals()方法方法toString()toString()方法方法封装类封装类Object 类(熟悉和掌握)Object类是所有Java类的根父类如果在类的声明中未使用extends关键字指明其父类,则默认父类为Object类 public class Person.等价于:public class Person extends Object.例:method(Object obj)/可以接收任何类作为其参数Object o=new Person;method(o);=操作符与equals方法(重点)=操作符与操作符
34、与equalsequals方法的区别:方法的区别:=:引用类型比较引用:引用类型比较引用(是否指向同一个对象是否指向同一个对象);Person p1=new Person();Person p2=new Person();Person p1=new Person();Person p2=new Person();if(p1=p2)if(p1=p2)基本类型比较值;基本类型比较值;int a=5;if(a=6)int a=5;if(a=6)用用=进行比较时,符号两边的数据类型必须一致进行比较时,符号两边的数据类型必须一致(可自动转换的基本数据类型除外可自动转换的基本数据类型除外),否则编译出错;
35、,否则编译出错;equals()equals()方法是方法是ObjectObject类的方法,由于所有类都继承类的方法,由于所有类都继承ObjectObject类,也就继承了类,也就继承了equals()equals()方法。方法。只能比较引用只能比较引用类型,其作用与类型,其作用与“=”=”相同相同,比较是否指向同一个对象比较是否指向同一个对象。格式。格式:obj1.equals(obj2):obj1.equals(obj2)特例:当用特例:当用equals()equals()方法进行比较时,对类方法进行比较时,对类FileFile、StringString、DateDate及封装类(及封装
36、类(Wrapper ClassWrapper Class)来说,是比较)来说,是比较类型及内容而不考虑引用的是否是同一个对象类型及内容而不考虑引用的是否是同一个对象;原因:在这些类中覆盖了原因:在这些类中覆盖了equals()equals()方法。方法。class TestEquals public static void main(String args)MyDate m1=new MyDate(14,3,1976);MyDate m2=new MyDate(14,3,1976);if(m1=m2)System.out.println(m1=m2);else System.out.print
37、ln(m1!=m2);/m1!=m2 if(m1.equals(m2)System.out.println(m1 is equal to m2);/m1 is equal to m2 else System.out.println(m1 is not equal to m2);请给据以下代码自行定义能满足需要的MyDate类,在MyDate类中覆盖equals方法,使其判断当两个MyDate类型对象的年月日都相同是,结果为ture,否则为false。public boolean equals(Object o)toString()方法在Object类中定义,其返回值是String类型,返回类名
38、和它的引用地址。在进行String与其它类型数据的连接操作时,自动调用toString()方法Date now=new Date();System.out.println(“now=”+now);相当于 System.out.println(“now=”+now.toString();/now=Date122345 可以根据需要在用户自定义类型中重写toString()方法如String 类重写了toString()方法,返回字符串的值。s1=“hello”;System.out.println(s1);/相当于System.out.println(s1.toString();在ToStrin
39、g1.java中的类A里覆盖toString方法,使其输出类A对象的cint属性值。基 本 类 型 数 据 转 换 为 S t r i n g 类 型 时,调 用 了 对 应 封 装 类 的 t o S t r i n g()方 法 i n t a=1 0;System.out.println(“a=”+a);定义两个类,父类GeometricObject代表几何形状,子类Circle代表圆形。GeometricObjectGeometricObjectprotected String color protected double weightprotected GeometricObject
40、()protected GeometricObject(String color,double weight)属性的getter和setter方法CircleCircle初始化对象的color属性为“white”,weight属性为1.0GeometricObjectGeometricObjectprotected String color protected double weightCircleCircleprivate double radiuspublic Circle()public Circle(double radius)public Circle(double radius,S
41、tring color,double weight)radius属性的setter和getter方法public double findArea():计算圆的面积public boolean euqals(Object c)public String toString()初始化对象的color属性为“white”,weight属性为1.0,radius属性为1.0。初始化对象的color属性为“white”,weight属性为1.0,radius根据参数构造器确定。重写equals方法,比较两个圆的半径是否相等,如相等,返回true。重写toString方法,输出圆的半径。写一个测试类,创建两个Circle对象,判断其颜色是否相等;利用equals方法判断其半径是否相等;利用toString()方法输出其半径。针对八种基本定义相应的引用类型封装类基本数据类型封装类 boolean Boolean byte Byte short Short int Integer long Long char Character float Float double Double