第8章 继承 抽象类和接口.ppt
主要内容主要内容8.1 类的继承8.2 抽象类8.3 接口8.4 内部类和匿名类8.5 包类的说明符类的说明符n n类的访问说明符类的访问说明符(1)public(2)friendly(不加访问说明符时)(不加访问说明符时)n n类的其它修饰符类的其它修饰符(1)final(2)abstract类的继承类的继承n n理解继承是理解面向对象程序设计的关键。理解继承是理解面向对象程序设计的关键。n n在在Java中,通过关键字中,通过关键字extends继承一个已有继承一个已有的类,被继承的类称为父类(超类,基类)的类,被继承的类称为父类(超类,基类),新的类称为子类(派生类)。,新的类称为子类(派生类)。n n子类可以有自己的成员方法及成员变量子类可以有自己的成员方法及成员变量n n如何访问如何访问?n n在在Java中,不允许多继承。中,不允许多继承。特殊变量特殊变量supern n特殊变量特殊变量super,提供了对父类的访问。提供了对父类的访问。n n可以使用可以使用super访问父类被子类隐藏的变量访问父类被子类隐藏的变量或覆盖的方法。或覆盖的方法。n n每个子类构造方法的第一条语句,都是隐每个子类构造方法的第一条语句,都是隐含地调用含地调用super(),如果父类没有这种形式如果父类没有这种形式的构造函数,那么在编译的时候就会报错。的构造函数,那么在编译的时候就会报错。class person public person(int i)System.out.println(“creating person”+i);class student extends person .class test public static void main(String args)person p=new person(2);判断判断:程序将输出程序将输出”creating person 2”class person public person()System.out.println(“person”);class student extends person public student()System.out.println(“student”);class test public static void main(String args)new student();new person();写出右边写出右边程序的输程序的输出结果出结果:class person public int m1;public person(int d)m1=d;class student extends person public int m2;public student(int ds,int d)_;/初始化初始化m1为为ds的值的值 m2=d;class test public static voic main(String args)student s=new student(2,3);System.out.println(s.m1+s.m2);1.1.给划线出填给划线出填上合适的语句上合适的语句2.2.请给出程序请给出程序运行结果运行结果方法的覆盖(方法的覆盖(override)n n在子类中定义一个与父类同名、返回类型、在子类中定义一个与父类同名、返回类型、参数类型均相同一个方法,称为方法的覆参数类型均相同一个方法,称为方法的覆盖。盖。n n覆盖发生在子类与父类之间。覆盖发生在子类与父类之间。n n出现覆盖时允许用父类的变量访问子类的出现覆盖时允许用父类的变量访问子类的成员成员n n静态方法静态方法,final修饰的方法均不可被覆盖修饰的方法均不可被覆盖下面哪个方法定义于划线处会导致编译错误下面哪个方法定义于划线处会导致编译错误?class person public float getNum()return 3.0f;public class student extends person _;A.public float A.public float getNUmgetNUm()return 4.0f;()return 4.0f;B.public void B.public void getNUmgetNUm()()C.public void C.public void getNum(doublegetNum(double d)d)D.public double D.public double getNum(floadgetNum(fload d)return 4.0d;d)return 4.0d;public class student extends person public void set()System.out.println(“student”);public static void main(String args)Object a=new student();(person)a).set();请给出程序运行结果请给出程序运行结果class person public void set()System.out.println(“person”);class person void set()System.out.println(in person);static void get()System.out.println(in person get();class student extends person void set()System.out.println(in student);static void get()System.out.println(in student get();person st1=new student();st1.set();st1.get();student st2=new student();st2.set();st2.get();请给出程序运行结果请给出程序运行结果class person public int m=5;public void print()System.out.print(m);class student extends person public int m=2;public void print()System.out.print(m);person p=new person p=new student();student();p.printp.print();();System.out.println(p.mSystem.out.println(p.m););执行如下语句后的结果是执行如下语句后的结果是_class person public void set()System.out.println(person);class student extends person public void set()System.out.println(student);public static void main(String args)mstudent ms=new mstudent();_;class mstudent extends person public void set()System.out.println(“mstudent);划线处填写适当语句划线处填写适当语句以输出以输出”personperson”class personclass student extends person public void set()System.out.println(student);public static void main(String args)person p=new student();_;划线处填写哪个语句能输出划线处填写哪个语句能输出”studentstudent”?A.A.p.setp.set();();B.(B.(person)p.setperson)p.set();();C.(C.(student)p.setstudent)p.set();();D.D.(student)p).setstudent)p).set();();Object 类类n nequals()方法方法n ntoString()方法方法n ngetClass()方法方法 instanceof运算符运算符 getClass().getName()方法方法 getClass().getSupername()方法方法class person void set()System.out.println(person:set);void fun()System.out.println(“person:fun);this.set();class student extends person void set()System.out.println(student:set:begin);super.fun();System.out.println(“student:set:end);执行下列语句后程序的输出是执行下列语句后程序的输出是?student s=new student();student s=new student();s.sets.set();();final方法方法n为了确保某个函数的行为在继承过程中保持不变,并且不能被覆盖(overridden),可以使用final方法。n为了效率上的考虑,将方法声明为final,让编译器对此方法的调用进行优化。要注意的是:编译器会自行对final方法进行判断,并决定是否进行优化。通常在方法的体积很小,而我们确实不希望它被覆盖时,才将它声明为final。nclass中所有的private和static方法自然就是final。class person public final void set()System.out.print(“1”);class student extends person public final void set(int i)System.out.print(“i”);student s=new student();student s=new student();s.sets.set();();s.set(2);s.set(2);执行上述程序后执行上述程序后,结果为结果为?A.输出输出”12”B.无法编译无法编译,因为具有因为具有final属属性的方法不能被覆盖性的方法不能被覆盖C.无法通过编译无法通过编译,因为方法调因为方法调用有问题用有问题D.可以通过编译可以通过编译,但无法正常但无法正常运行运行抽象方法和抽象类抽象方法和抽象类n在类中在类中没有方法体的方法,就是抽象方法。没有方法体的方法,就是抽象方法。n含有抽象方法的类,即为抽象类。含有抽象方法的类,即为抽象类。n如果一个子类没有实现抽象基类中所有的如果一个子类没有实现抽象基类中所有的抽象方法,则子类也成为一个抽象类。抽象方法,则子类也成为一个抽象类。n抽象类中可以包含一般方法及构造方法抽象类中可以包含一般方法及构造方法,且且能被其子类正常调用能被其子类正常调用n静态方法、私有方法、静态方法、私有方法、finalfinal方法不能被声方法不能被声明为抽象的方法。明为抽象的方法。class person public abstract void set();class student extends person public void set()System.out.print(“1”);class worker extends person public void set()System.out.print(“2”);person p=new student();person p=new student();p.setp.set();();p=new worker();p=new worker();p.setp.set()()执行上述程序后执行上述程序后,结果为结果为?A.输出输出”12”B.输出输出”11”C.无法通过编译无法通过编译,因为类型转因为类型转换不合法换不合法D.无法通过编译无法通过编译,因为因为person的定义不对的定义不对abstract class person int set()return 5;class test public static void main(String args)person a=new person();person b=new person();System.out.println(a.set()+b.set();若下列程序是否能正常运行若下列程序是否能正常运行,则写出运行结果则写出运行结果,否否则指出错误之处则指出错误之处,并修改并修改接口接口n n接口中所有的方法默认为接口中所有的方法默认为public abstract。n n在接口中声明方法时,不能使用在接口中声明方法时,不能使用native、static、final、synchronized、private、protected等修饰符。等修饰符。n n接口中的成员变量一定要赋初值,且不能接口中的成员变量一定要赋初值,且不能被修改,默认修饰符为被修改,默认修饰符为public static final。n n接口与抽象类的区别:不可有一般方法接口与抽象类的区别:不可有一般方法interface Math double PI=3.1415926;class Arithmetic implements Math double roundArea(double radius)return PI*radius*radius;Arithmetic a=new Arithmetic();判断以下语句有无错误判断以下语句有无错误?A.System.out.println(a.roundArea(3);B.System.out.println(Math.PI);C.System.out.println(Arithmetic.PI);D.System.out.println(a.PI);接口接口n n一个接口可以继承自另一个接口。n nJava中不允许类的多继承,但允许接口的多继承。interface Sittablevoid sit();interface Lievoid sleep();interface Chair extends Sittableinterface Sofa extends Sittable,Lie接口接口n n在Java中,一个类可以实现多个接口。n n一个类在继承另外一个类的同时,可以实现多个接口。/实现多个接口实现多个接口interface Sittablevoid sit();interface Lievoid sleep();class Sofa implements Sittable,Liepublic void sit()public void sleep()Sofa.java/在继承类的同时,实现多个接口interface Sittablevoid sit();interface Lievoid sleep();interface HealthCarevoid massage();class Chair implements Sittablepublic void sit();class Sofa extends Chair implements Lie,HealthCarepublic void sleep();public void massage();内内部类部类n n在一个类中定义另外一个类,这个类就叫做内部类或在一个类中定义另外一个类,这个类就叫做内部类或内置类内置类 (inner class)(inner class)。n n内部类可以让我们将逻辑上相关的一组类组织起来,内部类可以让我们将逻辑上相关的一组类组织起来,并由外部类并由外部类(outer class)(outer class)来控制内部类的可见性。来控制内部类的可见性。n n当我们建立一个当我们建立一个inner classinner class时,其对象就拥有了与外部时,其对象就拥有了与外部类对象之间的一种关系,这是通过一个特殊的类对象之间的一种关系,这是通过一个特殊的this this referencereference形成的,使得内部类对象可以随意的访问外形成的,使得内部类对象可以随意的访问外部类中所有的成员。部类中所有的成员。内部类内部类n n在方法中定义的内部类,如果要访问方法中定义的本在方法中定义的内部类,如果要访问方法中定义的本地变量或方法的参数,则变量必须被声明地变量或方法的参数,则变量必须被声明finalfinal。n n内部类可以声明为内部类可以声明为privateprivate或或protectedprotected;还可以声明为还可以声明为abstractabstract或或finalfinal。n n内部类内部类可以声明为可以声明为staticstatic的,但此时就不能再使用外部的,但此时就不能再使用外部类的非类的非staticstatic的成员变量和非的成员变量和非staticstatic的成员方法;的成员方法;n n非非staticstatic的的内部类内部类中的成员不能声明为中的成员不能声明为staticstatic的,只有的,只有在顶层类或在顶层类或staticstatic的内部类中才可声明的内部类中才可声明staticstatic成员。成员。内部类内部类n n我们为什么使用内部类1、在内部类(inner class)中,可以随意的访问外部类的成员,这可以让我们更好地组织管理我们的代码,增强代码的可读性。2、内部类可以用于创建适配器类,适配器类是用于实现接口的类。使用内部类来实现接口,可以更好地定位与接口关联的方法在代码中的位置。3、内部类的更多用法。包(包(package)n n为了便于管理大型软件系统中数目众多的类,解为了便于管理大型软件系统中数目众多的类,解决类命名冲突的问题决类命名冲突的问题,JavaJava引入了包(引入了包(packagepackage)。)。包(包(package)n npackage语句必须是文件中的第一条语句。也就是说,在package语句之前,除了空白和注释之外不能有任何语句。n n如果不加package语句,则指定为缺省包或无名包。n n包对应着文件系统的目录层次结构。n n在package语句中,用“.”来指明包(目录)的层次。编译并生成包编译并生成包n n在当前目录下生成包 javac d .Test.javan n在指定目录下生成包 javac d E:JavaLesson Test.javaimport语句语句n n引入包中的类。import java.io.File;n n引入整个包。import java.io.*;n n在同一包中的类可以互相引用,无需import语句。Java的垃圾回收的垃圾回收n n只有当一个对象不被任何引用类型的变量使用时,才可以被回收n n不能强制回收垃圾,但可以通过System.gc()提示回收器进行内存回收n nfinalize()方法