Java的多态性,抽象类与接口.ppt_第1页
Java的多态性,抽象类与接口.ppt_第2页
Java的多态性,抽象类与接口.ppt_第3页
Java的多态性,抽象类与接口.ppt_第4页
Java的多态性,抽象类与接口.ppt_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1,第6讲Java 多态性、抽象类与接口,掌握多态的优势和应用场合 实现多态 引用转型 多态性程序实例分析 掌握instanceof运算符的使用 抽象类与抽象方法 接口与接口的应用,继承是指从一个父类(父类)派生出派生类(子类)的过程; 继承使用关键字extends; 对于类成员,可以使用public、protected、缺省和private这4种访问权限修饰符; 对于类,可以使用public和缺省这2个访问权限; 创建子类实例时,必须先执行父类的构造方法,然后再执行子类的构造方法; super关键字有两种主要用途,都与父类有关。,回顾,为什么使用多态?,宠物生病了,需要主人给宠物看病 不同宠物看病过程不一样 不同宠物恢复后体力值不一样,打针,吃药,吃药,疗养,狗狗,Q仔,为什么使用多态?,编码实现,public class Master public void Cure(Dog dog) if (dog.getHealth() 50) dog.setHealth(60); System.out.println(“打针、吃药“); public void Cure(Penguin penguin) if (penguin.getHealth() 50) penguin.setHealth(70); System.out.println(“吃药、疗养“); ,主人类, Master master = new Master(); master.Cure(dog); master.Cure(penguin); ,测试方法,为什么使用多态?,如果又需要给XXX看病,怎么办? 添加XXX类,继承Pet类 修改Master类,添加给XXX看病的方法,使用多态优化设计,频繁修改代码,代码可扩展性、可维护性差,为什么使用多态?,使用多态优化后的代码, Pet pet = new Dog(); Master master = new Master(); master.Cure(pet); ,测试方法,public class Dog extends Pet public void toHospital() this.setHealth(60); System.out.println(“打针、吃药“); ,public class Penguin extends Pet public void toHospital() this.setHealth(70); System.out.println(“吃药、疗养“); ,public class Master public void Cure(Pet pet) if (pet.getHealth() 50) pet.toHospital(); ,主人类,Dog类,Penguin类,1,2,3,4,又要给XXX看病时,只需: 1. 编写XXX类继承Pet类(旧方案也需要) 2. 创建XXX类对象(旧方案也需要) 3. 其他代码不变(不用修改Master类),什么是多态?,生活中的多态 你能列举出一个多态的生活示例吗? 程序中的多态,同一个引用类型,使用不同的实例而执行不同操作,父类引用,子类对象,同一种事物,由于条件不同,产生的结果也不同,8,多态性(polymorphism),概念:是面向对象程序设计的另一个重要特征,其基本含义是“拥有多种形态”,具体指在程序中用相同的名称来表示不同的含义。例如:用同一方法名来表示不同的操作。 类型:有两种 静态多态性:包括变量的隐藏、方法的重载 动态多态性:在编译时不能确定调用方法,只有在运行时才能确定调用方法,又称为运行时的多态性。,静态多态,静态多态也称为编译时多态,即在编译时决定调用哪个方法; 静态多态一般是指方法重载; 只要构成了方法重载,就可以认为形成了静态多态的条件; 静态多态与是否发生继承没有必然联系。,动态多态,动态多态也称为运行时多态,即在运行时才能确定调用哪个方法; 形成动态多态必须具体以下条件: 必须要有继承的情况存在; 在继承中必须要有方法覆盖; 必须由父类的引用指向派生类的实例,并且通过父类的引用调用被覆盖的方法; 由上述条件可以看出,继承是实现动态多态的首要前提。,11,下面主要介绍动态多态性,/多态性的例子 class Animal public void roar() System.out.println(“动物:.“); class Cat extends Animal public void roar() System.out.println(“猫:喵,喵,喵,.“); class Dog extends Animal public void roar() System.out.println(“狗:汪,汪,汪,.“); ,12,/多态性的例子(续) public class AnimalTest public static void main(String args) Animal am=new Animal(); am.roar(); am=new Dog(); am.roar(); am=new Cat(); am.roar(); ,程序运行结果: 动物:. 狗:汪,汪,汪,. 猫:喵,喵,喵,.,根据对象的赋值规则,可以把子类对象赋给父类对象名,这是允许。当用同一形式: 父类对象名.roar() 去调用时,能够根据子类对象的不同,得到不同的结果,这就是多态性。,实现多态的流程,用多态实现打印机 分为黑白打印机和彩色打印机 不同类型的打印机打印效果不同,黑白打印机,彩色打印机,打印,实现多态的设计思路,使用多态实现思路 编写父类 编写子类,子类重写(覆盖)父类方法 运行时,使用父类的类型,子类的对象,计算机可以连接各种打印机,无论连接何种打印机打印方法都相同,根据连接打印机不同,效果也不同,实现多态,编码实现,实现多态的两个要素: 1. 方法重写 2. 使用父类类型,class Printer() print(String str); ,class ColorPrinter extends Printer print(String str) System.out.println(“输出彩色的“+str); ,class BlackPrinter extends Printer print(String str) System.out.println(“输出黑白的“+str); ,public static void main(String args) Printer p = new ColorPrinter(); p.print(); p = new BlackPrinter(); p.print(); ,父类,子类,运行,同一种操作方式,不同的操作对象,只能调用父类已经定义的方法,继承是子类使用父类的方法,而多态则是父类使用子类的方法。 (把父类当做子类来用),方法重写(覆盖),方法重写的规则 在继承关系的子类中 重写的方法名、参数、返回值类型必须与父类相同 私有方法不能继承因而也无法重写,方法重写 override,方法重载overload,VS,17,实现运行时多态技术的条件: 有一个继承层次关系; 在子类中重写父类的方法; 通过父类的引用对子类对象进行调用。,采用多态技术的优点: 引进多态技术之后,尽管子类的对象千差万别,但都可以采用 父类引用.方法名(参数) 统一 方式来调用,在程序运行时能根据子对象的不同得到不同的结果。这种“以不变应万变”的形式可以规范、简化程序设计,符合软件工程的“一个接口,多种方法”思想。,多态的运行机制,多态的运行机制 Java多态机制是基于“方法绑定(binding)”,就是建立method call(方法调用)和method body(方法本体)的关联。如果绑定动作发生于程序执行前(由编译器和连接器完成),称为“先期绑定”。对于面向过程的语言它们没有其他选择,一定是先期绑定。比如C编译器只有一种method call,就是先期绑定。(C+有先期联编和后期联编),当有多态的情况时,解决方案便是所谓的后期绑定(late binding):绑定动作将在执行期才根据对象型别而进行。后期绑定也被称为执行期绑定(run-time binding)或动态绑定(dynamic binding)。,Java的所有方法,除了被声明为final者,都使用后期绑定。 将方法声明为final型可以有效防止他人覆写该函数。但是或许更重要的是,这么做可以“关闭”动态绑定。或者说,这么做便是告诉编译器:动态绑定是不需要的。于是编译器可以产生效率较佳的程序代码。,引用转型,父类的引用可以指向子类的对象,如: BaseClass obj = new DerivedClass(); 这样的语句是合法的; 但是子类的引用则不可以指向父类的对象,如: DerivedClass obj = new BaseClass(); 这样的语句将引发错误。,引用转型示例,class Person /定义人类 class Student extends Person /学生类继承于人类 public class OverriddenDemo public static void main(String args) /正确,所有的学生一定是人 Person per = new Student(); /错误,并不是所有的人都是学生 Student std = new Person(); ,多态性实例分析,Example 例如动物园的饲养员能够给各种各样的动物喂食。 图1显示了饲养员Feeder、食物Food和动物Animal以及它的子类的类框图。,多态性实例分析,图1 饲养员Feeder、食物Food和动物Animal以及它的子类的类框图,多态性实例分析,可以把Feeder、Animal和Food都看成独立的子系统。Feeder类的定义如下: public class Feeder public void feed(Animal animal,Food food) animal.eat(food); 以下程序演示一个饲养员分别给一只狗喂肉骨头,给一只猫喂鱼。 Feeder feeder=new Feeder(); Animal animal=new Dog(); Food food=new Bone(); feeder.feed(animal,food); animal=new Cat(); food=new Fish(); feeder.feed(animal,food);,/给狗喂肉骨头,/给猫喂鱼,多态性实例分析,Java语言允许某个类型的引用变量引用子类的实例,而且可以对这个引用变量进行类型转换: Animal animal=new Dog(); Dog dog=(Dog)animal; Creature creature=animal; 如图2所示,如果把引用变量转换为子类类型,称为向下转型,如果把引用变量转换为父类类型,称为向上转型。在进行引用变量的类型转换时,会受到各种限制。而且在通过引用变量访问它所引用的实例的静态属性、静态方法、实例属性、实例方法,以及从父类中继承的方法和属性时,Java虚拟机会采用不 同的绑定机制。,/向下转型,把Animal类型转换为Dog类型,/向上转型,把Animal类型转换为 Creature类型,多态,图2 类型转换,多态性实例分析,下面通过具体的例子来演示多态的各种特性。 在下面的例程中,Base父类和Sub子类中都定义了实例变量var、实例方法method()、静态变量staticVar和静态方法staticMethod(),此外,在Sub类中还定义了实例变量subVar和subMethod()。 Sub.java package poly; class Base String var=“BaseVar“; static String staticVar=“StaticBaseVar“; void method() System.out.println(“Base method“); static void staticMethod() System.out.println(“Static Base method“); ,/成员(实例)变量,/静态变量,/成员(实例)方法,/静态方法,public class Sub extends Base String var=“SubVar”; /成员(实例)变量 static String staticVar=“StaticSubVar“; /静态变量 void method() /覆盖父类的method()方法 System.out.println(“Sub method“); static void staticMethod() /隐藏父类的staticMethod()方法 System.out.println(“Static Sub method“); String subVar=“Var only belonging to Sub“; void subMethod() System.out.println(“Method only belonging to Sub“); public static void main(String args) Base who=new Sub(); /who被声明为Base类型,引用Sub实例 System.out.println(“who.var=“+who.var); System.out.println(“who.staticVar=“+who.staticVar); who.method(); who.staticMethod(); ,/打印Base类的var变量,/打印Base类的staticVar变量,/打印Sub实例的method()方法,/打印Base类的staticMethod()方法,多态的一些细节,(1)对于一个引用类型的变量,Java编译器按照它声明的类型来处理。 例如在以下代码中,编译器认为who是Base类型的引用变量,不存在subVar成员变量和subMethod()方法,所以编译出错: Base whonew Sub(); /who是Base类型 who.subVar=“123”; /编译出错,提示在Base类中没有subVar属性 who.subMethod(); /编译出错,提示在Base类中没有subMethod()方法 如果要访问Sub类的成员,必须通过强制类型的转换: Base whonew Sub(); /who是Base类型 (Sub)who).subVar=“123“; /编译成功,把Base引用类型强制转换为Sub引用类型 (Sub)who).subMethod(); /编译成功,把Base引用类型强制转换为Sub引用类型,多态的一些细节,Java编译器允许具有直接或间接继承关系的类之间进行类型转换. 对于向上转型,不必使用强制类型转换,因为子类的对象肯定也可看作父类的对象。例如一个Dog对象是一个Animal对象,也是一个Creature对象,也是一个Object对象: Dog dog=new Dog(); Creature creature=dog; /编译成功,把Dog引用类型直接转换为Creature引用类型 Object object=dog; /编译成功,把Dog引用类型直接转换为Object引用类型 对于向下转型,必须进行强制类型转换: Creature creature=new Cat(); Animal animal=(Animal)creature; /编译成功,把Creature引用类型强制转换为Animal引用类型 Cat cat=(Cat)creature; /编译成功,把Creature引用类型强制转换为Cat引用类型 Dog dog=(Dog)creature; /编译成功,把Creature引用类型强制转换为Dog引用类型,多态的一些细节,假如两种类型之间没有继承关系,即不在继承树的同一个继承分支上,那么Java编译器不允许进行类型转换,例如: Dog dog=new Dog(); Cat cat=(Cat)dog; /编译出错,不允许把Dog引用类型转换为Cat引用类型 (2)对于一个引用类型变量,运行时Java虚拟机按照它实际引用的对象来处理。例如以下代码虽然编译可以通过,但运行时会抛出ClassCastException运行时异常: Base who=new Base(); /who引用Base类的实例 Sub s=(Sub)who; /运行时抛出ClassCastException 在运行时,子类的对象可以转换为父类类型,而父类的对象实际上无法转换为子类类型。因为通俗的讲,父类拥有的成员子类肯定也有,而子类拥有的成员父类不一定有。,多态的一些细节,假定Java虚拟机能够把子类对象转换为父类类型,那么以下代码中的sub.subMethod()方法无法执行: Base who=new Base(); /who引用Base类的实例 Sub sub=(Sub)who; /假定运行时未出错 sub.subMethod(); /sub引用变量实际上引用Base实例,而Base实例没有subMethod()方法 由此可见,在运行时,Java虚拟机无法把子类对象转变为父类类型。以下代码尽管能够编译成功,但在运行时,creature变量引用的Cat对象无法转变为Dog类型,因此会抛出ClassCastException: Creature creature=new Cat(); Animal animal=(Animal)creature; /运行正常,Cat对象可转换为Animal类型 Cat cat=(Cat)creature; /运行正常,Cat对象可以被Cat类型的引用变量引用 Dog dog=(Dog)creature; /运行时抛出ClassCastException,Cat对象不可转换为Dog类型 (但是会编译成功),(3)在运行时环境中,通过引用类型变量来访问所引用对象的方法和属性时,Java虚拟机采用以下绑定规则: 1)成员(实例)方法与引用变量实际引用的对象的方法绑定,这种绑定属于动态绑定,因为是在运行时由Java虚拟机动态决定的。 2)静态方法与引用变量所声明的类型的方法绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经作了绑定。 3)成员变量(包括静态变量和实例变量)与引用变量所声明的类型的成员变量绑定,这种绑定属于静态绑定,因为实际上是在编译阶段就已经作了绑定。,多态的一些细节,例如,对于以下这段代码: Base who=new Sub(); /who被声明为Base类型,引用Sub实例对象 System.out.println(“who.var=“+who.var); /打印Base类的var变量 System.out.println(“who.staticVar=“+who.staticVar); /打印Base类的staticVar变量 who.method(); /打印Sub实例的method()方法 who.staticMethod(); /打印Base类的staticMethod()方法 运行时将会输出如下结果: who.var=BaseVar who.staticVar=StaticBaseVar Sub method Static Base method,多态的一些细节,再看一个例子: public abstract class A abstract void method(); void test() method(); /到底调用哪个类的mehtod()方法? public class B extends A void method() /覆盖父类的method()方法 System.out.println(“Sub“); public static void main(String args) new B().test(); ,多态的一些细节,运行类B的main()方法将打印“Sub“。 方法test()在父类A中定义,它调用了方法method()。虽然方法method()在类A 中被定义为是抽象的,它仍然可以被调用,因为在运行时环境中,Java虚拟机会执行类B的实例的method()方法。一个实例所属的类肯定实现了父类中 所有的抽象方法(否则这个类不能被实例化)。 再看一个例子: public class A void method()System.out.println(“Base“); void test()method(); public class B extends A void method()System.out.println(“Sub“); public static void main(String args) new A().test(); /调用类A的method()方法 new B().test(); /调用类B的method()方法 ,多态的一些细节,运行这段代码将打印: Base Sub test()方法在父类A中定义,它调用了method()方法,和上面一个例子的区别是父类A的method()方法不是抽象的。但是通过new B().test()调用method()方法,执行的仍然是子类B的method()方法。由此可以更深入地体会动态绑定的思想:在运行环境中,当通过 B类的实例去调用一系列的实例方法(包括一个方法调用的另一个方法),将优先和B类本身包含的实例方法动态绑定,如果B类没有定义这个实例方法,才会和从 父类A中继承来的实例方法动态绑定。,多态的一些细节,37,instanceof 运算符: 功能:用于判断一个类是否实现接口,也可用来判断一个对象是否属于一个类。 格式:对象 instanceof 类或接口 结果:true 或 false,/程序片断 Person p=new Person(); Student s=new Student(); System.out.println(“人:p“); System.out.println(“学生: s“); System.out.println(“s instanceof Student:“+(s instanceof Student) ); System.out.println(“s instanceof Person:“+(s instanceof Person) ); System.out.println(“p instanceof Person:“+(p instanceof Person) ); System.out.println(“p instanceof Student:“+(p instanceof Student) );,程序运行结果: 人:p 学生: s s instanceof Student:true s instanceof Person:true p instanceof Person:true p instanceof Student:false,instanceof运算符,在强制类型转换之前通过instanceof运算符检查对象的真实类型,可以避免类型转换异常,从而提高代码健壮性,对象 instanceof 类或接口,/* * 测试instanceof运算符的使用。 */ public class TestPoly2 public static void main(String args) Pet pet = new Penguin(“Q仔”, “QQ企鹅“); / Pet pet = new Dog(“旺财”, “土狗“); pet.eat(); if (pet instanceof Dog) Dog dog = (Dog) pet; dog.catchingFlyDisc(); else if (pet instanceof Penguin) Penguin pgn = (Penguin) pet; pgn.swimming(); ,/* * 测试instanceof运算符的使用。 */ public class TestPoly2 public static void main(String args) / Pet pet = new Penguin(“Q仔”, “QQ企鹅“); Pet pet = new Dog(“旺财”, “土狗“); pet.eat(); if (pet instanceof Dog) Dog dog = (Dog) pet; dog.catchingFlyDisc(); else if (pet instanceof Penguin) Penguin pgn = (Penguin) pet; pgn.swimming(); ,注释创建Penguin 对象语句,取消创建Dog对象语句的注释,回顾继承:,继承,导入:为什么使用抽象类?,如果我们想访问调用子类Dog的print()方法。以下代码有什么问题? Java中也使用抽象类,限制实例化,Pet pet = new Pet(); pet.print();,实例化Pet没有意义,public abstract class Pet ,通过抽象类来改进实现,导入:为什么使用抽象方法?,如果父类的方法没机会被访问调用,以下代码有什么问题? 可以使用抽象方法来优化 抽象方法没有方法体 抽象方法必须在抽象类里 抽象方法必须在子类中被实现,除非子类是抽象类,public abstract void print();,没有方法体,public abstract class Pet public void print() / ,每个子类的print()方法实现不同,父类print()方法的实现是多余的。,42,抽象类(abstract),引例 抽象是面向对象的一种重要方法,通过抽象我们能够设计一个更普通、更通用的类,例:从许许多多学生中,抽象出Student类,再从学生、工人、农民、抽象出Person类。 下面,我们来分析一个例子:,Shape类是假想出的共同父类,现实中不存在叫“形状”的东西,若去实例化这样的对象很勉强。为阻止生成Shape类对象,可以将该类声明为抽象类。,43,抽象方法与抽象类 关键字abstract 可用来修饰方法和类,表示“尚未实现”的含义: 如果方法的声明中使用了abstract 修饰符,那么该方法就称为抽象方法。这表示该类中不提供方法的实现,即不定义方法体。,格式:访问权限 abstract 返回类型 方法名(参数表 ); /无方法体,例如:将前面Shape类的两个方法声明为抽象方法: public abstract double getArea(); public abstract double getPerimeter(); 注意:无方法体与方法体为空是两个不同的概念。,44,如果一个类的声明中有abstract 修饰符,那么该类就成为抽象类。,格式:访问权限 abstract class 类名,例如:将前面Shape类声明为抽象类: abstract class Shape ,说明: 抽象类不能进行实例化,否则出现编译错误; 通常,一个抽象类至少定义一个抽象方法,但并不是说非要定义一个抽象方法,即使类体没有一个抽象方法也是允许; 当一个类中包含有抽象方法时,该类一定要声明为抽象类;,45,说明: (续) 当子类继承了一个抽象类时,必须实现该抽象类中定义的全部抽象方法,否则必须声明为抽象类; 当类实现了一个接口,但并没有实现该接口的所有方法时,该类必须声明为抽象类,否则出错; 抽象方法不能被private、final或static修饰。为什么? (抽象方法必须被子类所覆盖,如果说明为private,则外部无法访问,覆盖也无从谈起。若说明为Static,即是不创建对象也能访问:类名.方法名() ,这要求给出方法体,但与抽象方法的定义相矛盾。),问题:以下哪个是抽象方法的正确形式? (1) abstarct void example() (2) abstarct void example() (3) static abstarct void example() (4) final abstarct void example(),(1),46,抽象类与具体类的比较,47,抽象类引用 虽然不能实例化抽象类,但可以创建它的引用。Java支持多态性,允许通过父类引用来引用类的对象。,/使用抽象类引用的例子 abstract class A /抽象类 abstract void m1(); /抽象方法 class B extends A void m1() System.out.println(“In m1.“); /实现了m1()方法 void m2() System.out.println(“In m2.“); public class AbstractRef public static void main(String args) B b=new B(); A a=b; /父类引用 a.m1(); ,程序运行结果: In m1.,48,接口(interface),如果一个抽象类中的所有方法都是抽象的,可以采用另一种方式“接口”来定义。,接口的概念 接口是抽象方法和常量值的定义的集合。从本质上讲,接口是一种特殊的抽象类,这种抽象类中只包含常量和方法的定义,而没有方法的实现。 从语法上看,接口是一种与“类”很相似的结构,只是接口中的所有方法都是抽象的,只有声明、没有方法体。接口声明的关键字是interface。,什么是接口?,认识一下接口 接口特性: 接口不可以被实例化 实现类必须实现接口的所有方法 实现类可以实现多个接口 接口中的变量都是静态常量,public interface MyInterface public void foo(); /其他方法 ,所有方法都是: public abstract,抽象类除外,Java中的多继承,常作为类型使用,50,接口的声明格式:,权限修饰符 interface 接口名 extends 父接口列表 /抽象方法和静态常量 ,例如:public interface Runner int id = 1; public void start(); public void run(); public void stop(); ,51,说明: 接口的修饰符可以是public或缺省; 接口中的方法都是抽象的和公有(public)的,仅有方法说明,没有方法体; 接口中的常量默认是公共的、静态的和最终的,在声明时一般不需要用public、static、final。 接口关心的是“做什么”,不关心“怎样做”,即是声明一种规范,而不是实现;生活中类似的例子:电脑主板中的各种插槽等; 通过接口可以间接实现多重继承。,52,接口的实现,接口规定了类的“原型”,具体实现由实现该接口的类来完成,格式如下:,修饰符 class 类名extends 父类implements 接口,接口, /包含对接口的所有方法的实现 ,/例子 public class Person implements Runner public void start() / 准备工作:弯腰、蹬腿、咬牙、瞪眼 / 开跑 ,public void run() / 摆动手臂 / 维持直线方向 public void stop() / 减速直至停止、喝水。 ,53,说明: 一个类可以实现多个接口,从而达到多重继承的目的; 多个无关的类可以实现同一个接口; 一个具体类实现接口时,必须实现接口中的所有抽象方法;当一个类未实现接口中的所有抽象方法时,应声明为抽象类; 类在实现某个接口的抽象方法时,必须使用完全相同的方法头,例如:接口定义中通常省略public修饰符,但在实现抽象方法时必须显式使用public修饰符; 通过接口可以实现不相关类的相同行为,而不需要考虑这些类之间的层次关系; 通过接口可以指明多个类需要实现的方法; 与继承关系类似,接口与实现类之间存在多态性。,54,下面类A的定义形式中,哪一个是正确的?,(1) class A extends B,C ,(2) class A implements B,C ,(3) class A extends B implements C ,(4) class A extends B implements C,D ,答案: (2)、(3)、(4),55,通过接口可以实现不相关类的相同行为,56,/接口应用例子 interface Runner /接口 public void run(); interface Swimmer /接口 public void swim(); abstract class Animal /抽象类,去掉关键字abstract是否可行? public abstract void eat(); class Person extends Animal implements Runner,Swimmer /继承类,实现接口 public void run() System.out.println(“我是飞毛腿,跑步速度极快!“); public void swim() System.out.println(“我游泳技术很好,会蛙泳、自由泳、仰泳、蝶泳.“); public void eat() System.out.println(“我牙好胃好,吃啥都香!“); ,57,public class InterfaceTest public static void main(String args) InterfaceTest t = new InterfaceTest(); Person p = new Person(); t.m1(p); /接口回调,下同 t.m2(p); t.m3(p); public void m1(Runner r) r.run(); /接口作参数,下同 public void m2(Swimmer s) s.swim(); public void m3(Animal a) a.eat(); ,程序运行结果: 我是飞毛腿,跑步速度极快! 我游泳技术很好,会蛙泳、自由泳、仰泳、蝶泳. 我牙好胃好,吃啥都香!,58,接口的使用 接口变量:声明格式 接口 变量名(又称为引用) 接口回调:可以把实现某一接口的类创建的对象引用赋给该接口声明的接口变量中,那么该接口变量就可以调用被类实现的接口中的方法。 实际上,当接口变量调用被类所实现的接口中的方法时,就是通知相应的对象调用接口的方法。 即: 接口变量=实现该接口的类所创建的对象; 接口变量.接口方法(参数列表); 接口做参数:如果一个方法的参数是接口类型,就可以将任何实现该接口的类的实例的引用传递给接口参数,那么接口参数就可以回调类实现的接口方法。,59,/上一例分析: interface Runner interface Swimmer class Person extends Animal implements Runner,Swimmer public class InterfaceTest public static void main(String args) InterfaceTest t = new InterfaceTest(); Person p = new Person(); t.m1(p); /接口回调,下同 t.m2(p); t.m3(p); public void m1(Runner r) r.run(); /接口作参数,下同 public void m2(Swimmer s) s.swim(); public void m3(Animal a) a.eat(); ,60,接口的继承,Java允许一个接口用extends继承另一个接口,格式如下:,接口名 extends 父接口,父接口, /新增的抽象方法或静态常量 ,说明: 与类继承不同,一个接口可以继承多个父接口; 一个public接口只

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论