面向对象 (三) iSoftStone Technologies Ltd. 2013-7-14 目标 ? ? ? ? ? 掌握方法的重载 掌握构造方法的重载 掌握类的继承 了解super关键字 了解垃圾回收机制 2 ?2005 iSoftStone Technologies Ltd. All rights reserved. 多态 ? Java 多态最重要的一个特征就是支持方法的重载 ? 重载(overloading) ? 那什么是重载呢? 3 ?2005 iSoftStone Technologies Ltd. All rights reserved. 方法重载(overloading) ? 同一个类中多个方法有相同的名字,不同的参数列表,这 种情况称为方法重载。 ? 返回类型不同并不足以构成方法重载。 ? 当重载方法被调用时,编译器根据参数的类型和数量来确 定实际调用哪个重载方法的版本。 4 ?2005 iSoftStone Technologies Ltd. All rights reserved. 方法重载示例 ? public class Demo { ? public void add(int i,int j){ ? System.out.println(i+j); ? } ? public void add(float i,float j){ ? System.out.println(i+j); ? } ? public void add(String s1,String s2){ ? System.out.println(s1+s2); ? } ? public static void main(String args[]){ Demo d = new Demo(); ? d.add(1, 2); 由编译器决定调用那个方法 ? d.add(2.56f, 7.44f); ? d.add("Hello", " World"); ? } ? } 5 ?2005 iSoftStone Technologies Ltd. All rights reserved. 重载方法的规则 ? 被重载的方法必须改变参数列表 ? 被重载的方法可以改变返回类型 ? 被重载的方法可以改变访问修饰符 ? 被重载的方法可以声明新的或更广的检查异常 ? 方法能够在同一个类中或者在一个子类中被重载 6 ?2005 iSoftStone Technologies Ltd. All rights reserved. 重载兼容 ? 在调用方法时,若没有找到类型匹配的方法,编译器会找 可以兼容的类型来进行调用,如:int类型可以找到使用 double类型的方法: ? 示例 ? public class Demo{ ? ? ? ? ? ? ? ? ? } public void add(double i,double j){ System.out.println("double :" + (i+j)); } public static void main(String[] args){ Demo d = new Demo(); int i = 10 ; int j = 20 ; d.add(i,j); // 可以兼容 } 7 ?2005 iSoftStone Technologies Ltd. All rights reserved. 构造函数重载 Java 为每一个类自动提供缺省构造函数 缺省构造函数将成员变量的值初始化为缺省值 构造函数也可以重载,要求使用不同的参数个数,不同的 参数类型。构造函数的重载,可以让用户用不同的参数来 构造不同的对象。 8 ?2005 iSoftStone Technologies Ltd. All rights reserved. this的使用 在方法中,可以使用一个关键字this,来表 示这个对象的本身,使用this还可以解决局 部变量和域变量同名的问题 在构造方法中还可以用this来调用另一构造 方法 在构造方法中调用另外一个构造方法,this 必须放在第一句 9 ?2005 iSoftStone Technologies Ltd. All rights reserved. 构造方法的调用 ? 示例 class Example{ int age ; String name ; public Example(int age){ this.age = age ; } public Example(int age,String name){ Example(age) ; // 错误 this(age) ; // 正确 } } 10 ?2005 iSoftStone Technologies Ltd. All rights reserved. 继承的概念 继承实际上是存在与面向对象程序中的两个类之间的一 种关系。 当一个类拥有另一个类的所有数据和操作时, 就称这两个类之间具有继承关系。 被继承的类称为父类 或超类,继承了父类的所有数据和操作的类称为子类。 使用继承的主要优点是,使得程序结构清晰,减少编码, 减少维护的工作量。 11 ?2005 iSoftStone Technologies Ltd. All rights reserved. 单继承和多重继承 ? 单重继承是指任何一个类都只有一个单一的父类;多重继 承是指一个类可以有一个以上的父类。 ? 支持多重继承的程序,其结构为复杂的网状,能更自然地 模拟现实世界,但设计、实现都比较复杂。JAVA出于安 全、可靠性的考虑,只支持单重继承。 12 ?2005 iSoftStone Technologies Ltd. All rights reserved. Java的继承 [类的修饰符] class <子类名> extends <父类名> { <域定义> ; <方法定义>; } 在定义子类时用extends关键字指明新定义类的父 类,就在两个类之间建立了继承关系。新定义的类称为子 类,它可以从父类那里继承所有非private的域和方法作 为自己的属性。 13 ?2005 iSoftStone Technologies Ltd. All rights reserved. 继承示例 class Student{ private int age ; protected String name ; public void showName(){ System.out.println("Name: " + name); } } public class ExtendsDemo_1 extends Student { public static void main(String[] args) { Student s = new ExtendsDemo_1(); s.name = "Soft"; s.showName(); } } 14 ?2005 iSoftStone Technologies Ltd. All rights reserved. 继承在开发中的作用 继承允许代码重用 扩展新功能适应新情况 15 ?2005 iSoftStone Technologies Ltd. All rights reserved. super 的使用 1 使用super可以调用父类的构造方法 2 由于继承,使用this可以访问父类的域和方法, 但有时候需 要明确的指明父类的域和方法, 就有用的super 16 ?2005 iSoftStone Technologies Ltd. All rights reserved. 调用父类的构造函数 当一个子类调用super( ),它调用它的直接超类的构造函数。这样, super( )总是引用调用类直接的超类。这甚至在多层次结构中也是成立 的。还有,super( )必须是子类构造函数中的第一个执行语句 ? class Box { ? Box(double wigth,double heigth,double depth){} ? } ? public class SuperDemo_1 extends Box { ? public SuperDemo_1(double w,double h,double d){ ? super(w,h,d); ? } ? } 17 ?2005 iSoftStone Technologies Ltd. All rights reserved. 调用超类的方法和变量 ? ? class People{ protected int age ; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 18 protected void show(){ System.out.println("父类 Show"); } } public class SuperDemo_2 extends People { protected void show(){ System.out.println("子类 Show"); } public void testShow(){ this.show(); super.show(); } public static void main(String[] args) { SuperDemo_2 s = new SuperDemo_2(); s.testShow(); } } ?2005 iSoftStone Technologies Ltd. All rights reserved. 父类对象与子类对象的转换 1 子类对象可以视作是一个父类的对象 如: Student对象也是一个People对象 2 父类对象不能被当作一个子类对象 3 如果一个方法的形参是父类对象,调用这个方法时 可以使用子类的对象作为实际参数 4 如果父类对象指向的实际是一个子类对象,那个这个 父类对象可以用强制类型转换成子类对象的引用 19 ?2005 iSoftStone Technologies Ltd. All rights reserved. 垃圾回收 Java中的对象使用new进行创建,而由系统自动 进行对象的清除,清除无用对象的过程,称为垃圾回收 对象的回收是由Java虚拟机的垃圾回收线程来完成 的,该线程对无用的对象在适当的时机进行回收 与C++等语言相比,其最大特色之一就是:无用的 对象由系统自动进行清除和内存的回收,程序员可以不 用关心如何回收以及何时回收,大大减轻了工作的负担 和回收对象是带来的潜在错误 20 ?2005 iSoftStone Technologies Ltd. All rights reserved. finalize() 方法 finalize()方法类似C++中的析构函数,当一个对象变成 垃圾,它所引用的对象没有被别的有效的句柄引用的话, finalize()方法将对象从内存中释放。 垃圾回收机制不由程序员控制,也无规律可循,并不会 一产生了垃圾,它就被唤起,我们无法保证每个对象的 finalize()方法最终都会被调用 21 ?2005 iSoftStone Technologies Ltd. All rights reserved. finalize()示例 public class FinalizeDemo { public void finalize(){ System.out.println(" Finalize() "); } public static void main(String[] args) { System.out.println("Begin....."); new FinalizeDemo(); new FinalizeDemo(); new FinalizeDemo(); System.out.println("End....."); ? } ? } 22 ?2005 iSoftStone Technologies Ltd. All rights reserved. 运行结果 运行结果: Begin..... End..... 我们创建的三个对象在End语句之前都已经变成了垃圾, 但是我们并没有看到垃圾回收的时finalize()方法备调用 Java垃圾回收的这种不可靠性有时候也会给程序带来一 些麻烦,比如有时候程序产生了大量的垃圾,如果不能及 时释放垃圾所占据的大量的内存也是一件棘手的事情,为 此java提供了System.gc()方法 23 ?2005 iSoftStone Technologies Ltd. All rights reserved. System.gc() 方法 使用这个方法可以可以强制启动垃圾回收机制来回收垃圾, 就像我们主动给环卫局打电话,通知他们提前来清扫垃圾 的道理时一样的 将上面的示例修改如下: System.out.println("Begin....."); new FinalizeDemo(); new FinalizeDemo(); new FinalizeDemo(); System.gc(); // 启动垃圾回收机制 System.out.println("End....."); 这时候编译运行的结果我们可以看到finalize()方法已经被调用 24 ?2005 iSoftStone Technologies Ltd. All rights reserved. 谢谢! iSoftStone Technologies Ltd. 2013-7-14