目标理解:Java面向对象编程中多态的概念掌握:在继承中实现方法覆盖,应用多态进行面向对象编程。掌握:Object类和final关键字概述 多态(polymorphism)性是指对类的成员方法的调用将形成不同的实现方式(一个接口,多种方法)多态必须存在于继承的环境之中, 是对面向对象程序设计的补充概述多态性分为静态多态和动态多态两种 静态多态—方法重载动态多态—建立在继承和方法覆盖基础上本章内容:动 态多态性,即动态绑定(或叫运行期绑定) 方法覆盖(Override)假如有100个类,分别为Sub1,Sub2 … Sub100 ,它们的一个共同行为是写字,除了Sub1类用脚写字外,其余的类都用手写字抽象出基类Base,并定义公共的行为writeclass Base { public void write() { //用手写字 }}Sub2…Sub100都用手写字class SubN extends Base {}Sub1类用脚写字class Sub1 extends Base { public vo id write(){ //用脚写字 } }方法覆盖(Override)如果在派生类中定义的一个方法,其名称、返回类型及参 数正好与基类中某个方法完全匹配,称:派生类的方法覆盖(重写)了基类的方法 方法覆盖(Override) 方法覆盖示例class Animal { public void eat() { System.out.println("动物进食"); }}class Cat extends Animal { public void eat() { System.o ut.println("猫吃鱼"); }}class Dog extends Animal { public void eat () { System.out.println("狗啃骨头"); }}public class AnimalTes t { public static void main(String[] args) { Animal animal = new Animal(); animal.eat(); Cat cat = new Cat(); c at.eat(); Dog dog = new Dog();//基类的引用指向派生类的对象 animal = dog; animal.eat(); }}方法覆盖(Override)重要特性: 基类的引用可以指向派 生类的对象 当一个基类的引用指向派生类的对象,然后通过该引用调用方法时,总是去调用派生类重写的方法 方法覆盖(Override )覆盖方法必须满足多种约束:派生类方法的名称、参数和返回类型必须与基类方法一致派生类方法不能缩小基类方法的访问权限 在同一个类中方 法只能重载,不能覆盖……动态绑定子类的对象赋给基类的引用,这种行为称为“向上转型” Dog dog = new Dog(); Animal animal = dog; Animal animal = new Dog();当基类的引用指向派生 类的对象时,对方法的调用是动态解析的,即根据对象的实际类型动态选择这称为动态绑定(或运行期绑定)动态绑定动态多态的实现public class AnimalTest { public static void fun(Animal animal) { // 形参为基类的对象 System.out.println("在fun方法中"); animal.eat(); //动态绑定 } public static void main(String[] args) { Cat cat = new Cat(); fun(cat); //实参为派生类的对象 Dog dog = new Dog(); fun(dog); //实参为派生类的对象 }}深入多态动物园饲养员 能够给各种各样的动物喂食 //饲养员类public class Feeder{ //喂食方法 public void feed (Animal a,Food f){ animal.eat( f ); }}//喂食程序Feeder feeder=new Feeder();Animal animal=new Dog();Food food=new Bone();feeder.fee d(animal,food); //给狗喂肉骨头animal=new Cat();food=new Fish();feeder.f eed(animal,food); //给猫喂鱼深入多态深入多态引用类型转换 Animal animal = new Dog(); Creature creature = animal; //向上转型Dog dog = (Dog)animal; //向下转型,强 制转换Object类Object类是所有Java类的直接或间接基类可以用类型为Object的变量来引用任意类型的对象 Ob ject obj = new Animal( );如果了解Object变量所引用对象的实际类型,可以进行强制类型转换 An imal an = (Animal)obj;Object类equals( ) 方法 使用equals()方法的目的是用于检测两个 对象是否相等 Object类提供的equals()方法的实现是:判断两个对象是否指向同一个内存区域 如果想在自定义类中测试同 类对象是否相等,最好重写(覆盖) equals方法Object类调用equals( ) 方法示例//Integer类已重写equa lsInteger one = new Integer(10);Integer two = new Integer(10);if( one.equasl(two) ) { System.out.println("对象相等");}//自定义坐标点类Point public class Point { int x , y ; public Point(int a, int b) { x = a; y = b; }}//调用Object类的equals 方法Point p1 = new Point(2, 3);Point p2 = new Point(2, 3);if ( p1.equals(p2) ) { System.out.println("坐标相同");}Object类在 Point 类中重写 equals 方法publi c class Point { int x , y ; public Point(int a, int b){ x = a ; y = b ; } //重写equals方法 public boolean equals(Object obj) { if( obj == null) return false ; if( this == obj) return true ; if(getClass() != obj.get Class()) return false ; Point p = (Point)obj ; ret urn x == p.x && y == p.y ; }}Object类toString()方法 返回一个描述该对象的字 符串 几乎每个类都会重写该方法 大多数toString()方法都遵循如下格式类名[ 各属性的值 ]Object类在Point类中 重写toString()方法public class Point{ …… public String toString (){ return "Point [ x = " + x + " , y = " + y + " ]" ; }}//调用toString()方法Point p = new Point(3, 5);System.out.println( p.toString() );//或者System.out.println( p );final关键字final关键字可应用于类、 方法和变量final表示不可改变final关键字final类 声明为final的类不能被继承 常见final类如:String、I nteger等final class Base { int i = 1; void fun() { }}class S ub extends Base { //错误 ……}final关键字final方法声明为final的方法不能被覆盖类中的pr ivate方法都是隐式final方法final类的所有方法都是隐式final方法class Base { final voi d fun() { … }}class Sub extends Base { public void fun() { …} //错误}final关键字final变量 一个final变量实质是一个常量。 final修饰符可以修饰静态变量、实例变量和局部变 量,分别表示静态常量、实例常量和局部常量//Math类中定义了一个静态常量public class Math { ..... . public static final double PI = 3.14159265358979323846; . .....}final关键字final变量final变量必须显式初始化final类型的实例变量,可以在定义时或者在构造方法中进行初 始化class Sample { final int var1; //定义var1实例常量 final in t var2=0; //定义var2实例常量并初始化 Sample() { var1 = 1; / /初始化var1实例常量 var2 = 2; //编译出错,var2已经初始化 } }总结在继承关系中,派生类继承基类的方法可能对派生类并不适用,派生类可以重新定义该方法,这称为方法覆盖当基类的引用指向派生类的对象时,对方法的调用是动态绑定的,即根据所引用的实际对象的类型动态地选择相应的方法Object类是所有Java类的基类,它位于Java类体系结构的顶层final关键字可以修饰类、方法和变量,final在修饰类、方法和变量时的意义是不同的,但它们的本质是一样的:final表示不可改变 |
|