多态在程序设计中指“一种定义,多种实现”
多态性是面向对象的核心特征之一,主要有方法的多态和类型的多态。方法的多态包括方法的重载和覆盖,为一种功能提供多种实现;类型的多态表现为,子类是一种父类类型。
子类声明多态成员
1.子类声明的成员与父类同名,多态成员当子类从父类继承来的成员不能满足子类需要时,子类不能删除它们,但可以重定义它们,使父类成员能够适应子类新的需求。子类重定义父类成员的设计方法是,子类声明与父类同名的成员,包括以下情况。
(1)子类声明的成员变量与父类同名,则隐藏父类的成员变量,变量类型可以不同。
(2)子类声明的成员方法与父类同名,有以下两种情况,以参数列表是否相同区别。
①如果参数列表相同,则覆盖(Override)父类的成员方法,返回值类型必须与父类方法的返回值类型赋值相容,否则编译器会指出存在二义性的语法错误。覆盖父类方法时,子类方法的访问权限不能小于父类方法的访问权限。
②如果参数列表不同,则重载(Overload)父类的成员方法。子类继承了父类的成员,如果子类又声明了与父类同名的成员变量x,覆盖了父类的成员方法f(),则子类实际上有两个×和两个成员方法f(),这就是多态,默认访问/调用子类声明的x或f()方法。
对于(2)的①,大家可以想象一种场景,动物有一种属性是吃,猫和狗继承了动物,但猫吃鱼,狗吃狗粮.
2. 当子类有多态成员时,在子类的实例成员方法中,需要调用父类成员,可使用“super引用”,语法格式如下:
super.成员变量//当子类隐藏父类成员变量时,引用父类成员变量
super.成员方法([参数列表])//当子类覆盖父类成员方法时,调用父类成员方法
super将当前对象作为其父类的一个实例引用。注意:在静态方法中不能使用 super。
类型的多态
子类对象即是父类对象,而父类对象不是子类对象
对象运算符instanceof判断一个实例是否属于指定类,包括其子类实例。
例如:
new Dog() instance of Dog//true
new Dog() instance of Animal//true
new Animal() instance of Dog//false
父类对象引用子类实例
例如:
Animal ani =new Dog();//这种是可以的
但是
Dog dog=new Animal();//这种就是不可以的
在调用方法时,调用的参数传递也可以如此
例如在Animal类中声明一个方法为
public int olderThan(Animal ani){
return this.age-ani.age;
}
public class Main {public static void main(String[] args) {Animal a = new Animal(18);Animal b = new Animal(20);Dog d=new Dog(21);Dog e=new Dog(21);System.out.println(a.olderThan(b));System.out.println(a.olderThan(d));System.out.println(d.olderThan(a));System.out.println(d.olderThan(e));}
}
这四种情况都是可以的
编译时多态和运行时多态
编译时多态主要是指方法重载(overloading),也称为静态多态。在编译时,根据方法名、参数类型和返回类型来确定调用哪个方法。而运行时多态主要是指方法重写(overriding),也称为动态多态。在运行时,根据对象的实际类型来确定调用哪个重写的方法。
在运行时多态中,方法的选择是根据对象的实际类型来确定的。例如:
class Animal {public void makeSound() {System.out.println("Some sound");}
}class Dog extends Animal {public void makeSound() {System.out.println("Bark");}
}class Cat extends Animal {public void makeSound() {System.out.println("Meow");}
}
public class Main {public static void main(String[] args) {Animal animal = new Animal();Animal dog = new Dog();Animal cat = new Cat();animal.makeSound();dog.makeSound();cat.makeSound();}
}
输出结果为:
Some sound
Bark
Meow
运行时多态的意义:①在父类中约定通用的方法声明,如Object类声明toStringO方法,并为子类提供默认实现。②子类继承父类方法,说明多个子类具有共同的行为能力;子类覆盖父类方法,提供不同的方法实现,体现子类的个性,由运行系统确定执行多态的方法实现。