一、多态介绍
一、多态简介
1、介绍
接口的多种不同的实现方式即为多态。
由于子类与父类之间存在"is - a"关系,这种规则的另外一种表述是替换原则(substitution principle)。因此父类对象出现的任何对象的地方都可以使用子类对象替换,简单来说即,父类型的变量可以引用子类型的对象。
public class Animal{
...
}
public class People extends Animal{
}
public class Polymorphic{
public static void main(String[] args){
Animal animal = new People(); //父类型的变量可以引用子类型的对象
}
}
声明类型: 一个变量必须被声明为某种类型,这个变量的类型被称为声明类型。比如上述的Animal
实际类型: 是指被变量引用的对象所对应的实例类。比如上述的People
注:实例可以使用声明类型或者是它的子类的构造方法。例如类People是Animal的子类。
2、特点
一个引用类型变量声明为父类的类型,而实际引用的是子类的对象,则这个变量不能访问子类中添加的属性和方法。
public class Polymorphic {
public static void main(String[] args) {
Animal animal = new People();
animal.PeoplePrint();//编译时直接报找不到符号
}
}
class Animal{
public void AnimalPrint(){
System.out.println("AnimalPrint");
}
public void print(){
System.out.println("animal");
}
}
class People extends Animal{
public void PeoplePrint(){
System.out.println("PeoplePrint");
}
@Override
public void print() {
System.out.println("people");
}
}
二、静态绑定与动态绑定
1、静态绑定
即方法在编译期就能够确定。例如:private、static、final方法或者构造方法(不会发生重写)。
2、动态绑定
即在运行时的那一刻才知道具体要调用哪个方法。例如:如果要调用的方法依赖于实际类型。
public class Polymorphic {
public static void main(String[] args) {
Animal animal = new People();
animal.print();//实际类型为People
}
}
class Animal{
public void AnimalPrint(){
System.out.println("AnimalPrint");
}
public void print(){
System.out.println("animal");
}
}
class People extends Animal{
public void PeoplePrint(){
System.out.println("PeoplePrint");
}
@Override
public void print() {
System.out.println("people");
}
}
三、编译时多态与运行时多态
1、重载解析
-
编译器查看对象的声明类型和方法名,并一 一列举本类中的重载方法和超类中所有同名的可访问方法(超类私有方法不可访问)。
-
编译器确定方法调用中提供的参数类型。如果在上述列表中存在与所提供参数类型完全匹配的方法,就选择这个方法,这个过程称之为重载解析。
2、编译时多态
主要是方法重载,根据重载解析,在编译期就能确定方法的调用。
public class Polymorphic {
public static void main(String[] args) {
Animal animal = new Animal();
animal.print();//animal
}
}
class Animal{
public void print(){
System.out.println("animal");
}
public void print(int i){
System.out.println("animal, age = " + i);
}
}
3、运行时多态(动态绑定)
指在执行期间(非编译期间)判断引用对象的实际类型,根据实际类型判断并调用相应的属性和方法。主要用于继承父类和实现接口时,父类引用指向子类对象。(前提:存在类的继承或接口实现关系、方法重写)
public class Polymorphic {
public static void main(String[] args) {
Animal animal = new People();
animal.print();//people
}
}
class Animal{
public void AnimalPrint(){
System.out.println("AnimalPrint");
}
public void print(){
System.out.println("animal");
}
}
class People extends Animal{
public void PeoplePrint(){
System.out.println("PeoplePrint");
}
@Override
public void print() {
System.out.println("people");
}
}
二、对象转换
一、instanceof
1、作用
用于检查左边的变量能否转换为右边类的对象。
通常用于在对象的类型强转之前用作判断。
2、格式
对象变量名 instanceof 类名
3、示例
Animal animal = new People();
if(people instanceof People){
System.out.pringln("可以转换");
}
二、对象转换
1、介绍
对于基本数据而言:
自动类型转换
强制类型转换
对于引用数据类型而言:
向上转型:子类可以转换为父类类型
向下转型:但父类类型转换子类类型需要强制转换(注意:无继承关系的引用类型之间的转换是非法的)。
2、示例
public class Polymorphic {
public static void main(String[] args) {
Animal animal = new People();
if(animal instanceof People){
((People) animal).PeoplePrint(); //PeoplePrint
}
}
}
class Animal{
public void AnimalPrint(){
System.out.println("AnimalPrint");
}
public void print(){
System.out.println("animal");
}
}
class People extends Animal{
public void PeoplePrint(){
System.out.println("PeoplePrint");
}
@Override
public void print() {
System.out.println("people");
}
}
参考资料:
《Java核心技术卷》、《Java语言程序设计》、尚硅谷资料。