31--面向对象特征之三--多态性

对象多态性的体现形式:

  1. 方法的重载与重写
  2. 对象的多态性:父类的引用指向子类的对象
    对象的多态性的类型:
    1.向上转型:子类对象→父类对象
    2.向下转型:父类对象→子类对象
    对于向上转型,程序会自动完成,而对于向下转型必须明确指定要转换为的类型。
    实例1:定义父类
package com.qwy.bean;
public class Person {
    
    
	public void sayHello(){
    
    
		System.out.println("Person.sayHello()");;
	}
}

实例2:定义子类

package com.qwy.bean;
public class Student extends Person{
    
    
	public void sayHello(){
    
    
		System.out.println("Student.sayHello()");
	}
}

实例3:测试类

package com.qwy.test;
import com.qwy.bean.Person;
import com.qwy.bean.Student;
public class TestDemo {
    
    
	public static void main(String[] args) {
    
    
		Student student= new Student();//定义子类实例化对象
		Person person=student;//发生向上转型的关系:自动转换
		person.sayHello();//此方法被子类覆写过
	}
}

运行结果:
Student.sayHello()
以上程序就是一个对象向上转型的关系,从程序的运行结果中可以发现,此时虽然使用父类对象调用了person.sayHello()方法,但是实际上调用的方法是被子类覆写过的方法,也就是如果发生了向上转型关系后,所调用的方法一定是被子类覆写过的方法,但是对象Person是无法调用用子类student中的其他方法的。

实例4:修改子类

package com.qwy.bean;
public class Student extends Person{
    
    
	public void sayHello(){
    
    
		System.out.println("Student.sayHello()");
	}
	public void tell(){
    
    
		System.out.println("Student.tell()");
	}
}

此时person对象是无法调用tell()方法的。因为tell()方法只在子类中定义了,父类并没有定义。如果想要调用tell()方法,此时需要向下转型:
实例5:测试类

package com.qwy.test;
import com.qwy.bean.Person;
import com.qwy.bean.Student;
public class TestDemo {
    
    
	public static void main(String[] args) {
    
    
		Person person= new Student();//使用子类实例化父类,发生向上转型
		Student student=(Student) person;//此时发生向下转型
		student.sayHello();//调用方法被覆写的方法
		student.tell();//调用子类自己的方法
		student.speak();//调用父类的方法
	}
}

运行结果:
Student.sayHello()
Student.tell()
Person.speak()

注意: 一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法

实例6:修改测试类(错误演示)

package com.qwy.test;
import com.qwy.bean.Person;
import com.qwy.bean.Student;
public class TestDemo {
    
    
	public static void main(String[] args) {
    
    
		Person person= new Person ();//使用子类实例化父类,发生向上转型
		Student student=(Student) person;//此时发生向下转型
		student.sayHello();//调用方法被覆写的方法
		student.tell();//调用子类自己的方法
		
	}
}

此时运行时会报错误: java.lang.ClassCastException: com.qwy.Person cannot be cast to com.qwy.Student
意思是无法将Person类型转换为Student类型。
instanceof关键字:
检验对象是否为某个类的对象,返回值为boolean型。
实例7:

package com.qwy.test;
import com.qwy.bean.Person;
import com.qwy.bean.Student;
public class TestDemo {
    
    
	public static void main(String[] args) {
    
    
		Person person= new Student();//使用子类实例化父类,发生向上转型
		System.out.println("Person person= new Student():"+(person instanceof Student));
		System.out.println("Person person= new Student():"+(person instanceof Person));
		Person person2= new Person();
		System.out.println("Person person2= new Person():"+(person2 instanceof Student));
		System.out.println("Person person2= new Person():"+(person2 instanceof Person));
	}
}

运行结果:
Person person= new Student():true
Person person= new Student():true
Person person2= new Person():false
Person person2= new Person():true

从运行结果可以发现,使用子类实例化的对象同时是子类和父类的实例,所以可以直接进行向上或向下转型,但是如果使用了父类实例化本类对象,则一定就不再是子类的实例了,所以是不能转型的。

猜你喜欢

转载自blog.csdn.net/qwy715229258163/article/details/114650024