day10

多态性

理解多态性:可以理解为一个事物的多种形态。

何为多态性:对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)

多态的使用:虚拟方法调用,有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。

总结:编译,看左边;运行,看右边。

多态性的使用前提: ① 类的继承关系 ② 方法的重写

对象的多态性,只适用于方法,不适用于属性(编译和运行都看左边)

演示:

package cap13;
//Person.java
public class Person {
	String name;
	int age;
	
	int id = 1001;
	public void eat() {
		System.out.println("人:吃饭");
	}
	public void walk() {
		System.out.println("人:走路");
	}
}
package cap13;
//Man.java
public class Man extends Person{
	boolean isSmoking;
	int id = 1002;
	public void earnMoner() {
		System.out.println("男人要赚钱养家");
	}
	public void eat() {
		System.out.println("男人:多吃饭,长肌肉");
	}
	public void walk() {
		System.out.println("男人霸气的走路");
	}
}
package cap13;
//Woman.java
public class Woman extends Person{
	boolean isBeatury;
	int id = 1003;
	
	public void eat() {
		System.out.println("女人少吃一点,减肥");
	}
	public void walk() {
		System.out.println("女人优雅的走路");
	}
	public void useMoney() {
		System.out.println("shopping");
	}
}
package cap13;
//PersonTest.java
public class PersonTest {
	public static void main(String[] args) {
		PersonTest personTest = new PersonTest();
		personTest.test(new Man());
		personTest.test(new Woman());
	}
	public void test(Person p) {
        //虚拟方法调用,有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
		p.eat();
        //虚拟方法调用,有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
		p.walk();
        //属性(编译和运行都看左边)
		System.out.println(p.id);
	}
}
/*
结果:
	男人:多吃饭,长肌肉
	男人霸气的走路
	1001
	女人少吃一点,减肥
	女人优雅的走路
	1001
*/

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

虚拟方法调用(多态情况下)子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。

编译时类型和运行时类型

编译时p为Person类型,而方法的调用是在运行时确定的,所以调用的是Woman或者Man类 的重写方法。——动态绑定

小结:

方法的重载与重写

重载,是指允许存在多个同名方法,而这些方法的参数不同。编译器根据方法不同的参数表,对同名方法的名称做修饰。对于编译器而言,这些同名方法就成了不同的方法。它们的调用地址在编译期就绑定了。Java的重载是可以包括父类和子类的,即子类可以重载父类的同名不同参数的方法。

所以:对于重载而言,在方法调用之前,编译器就已经确定了所要调用的方法,这称为“早绑定”或“静态绑定”;

而对于多态,只有等到方法调用的那一刻,解释运行器才会确定所要调用的具体方法,这称为“晚绑定”或“动态绑定”。

多态作用

提高了代码的通用性,常称作接口重用

前提

需要存在继承或者实现关系

有方法的重写

成员方法

编译时:要查看引用变量所声明的类中是否有所调用的方法

运行时:调用实际new的对象所属的类中的重写方法。

编译看左边运行看右边

成员变量

不具备多态性,只看引用变量所声明的类

instanceof操作符

x instanceof A:检验x是否为类A的对象,返回值为boolean型

要求x所属的类与类A必须是子类和父类的关系,否则编译错误。

如果x属于类A的子类B,x instanceof A值也为true。

对象类型转换

  1. 对Java对象的强制类型转换称为造型
  2. 从子类到父类的类型转换可以自动进行
  3. 从父类到子类的类型转换必须通过造型(强制类型转换)实现
  4. 无继承关系的引用类型间的转换是非法的
  5. 在造型前可以使用instanceof操作符测试一个对象的类型

在这里插入图片描述

练习:

package cap13Exe;


public class InstanceTest {
	/*
	 * 建立InstanceTest 类,在类中定义方法method(Person e);
			在method中:
				(1)根据e的类型调用相应类的getInfo()方法。
				(2)根据e的类型执行:
					如果e为Person类的对象,输出: “a person”;
					如果e为Student类的对象,输出:
						“a student”
						“a person ” 
					如果e为Graduate类的对象,输出:
						“a graduated student”
						“a student”
						“a person”
	 */
	public static void main(String[] args) {
		InstanceTest instanceTest = new InstanceTest();
		instanceTest.test(new Student());
		System.out.println("=======");
		instanceTest.test(new Graduate());
		System.out.println("=======");
		instanceTest.test(new Person());
	}
	public void test(Person p) {
		p.getInfo();
		if(p instanceof Graduate) {
			System.out.println("a graduated student");
			System.out.println("a student");
			System.out.println("a person");
		}else if(p instanceof Student) {
			System.out.println("a student");
			System.out.println("a person");
		}else {
			System.out.println("a person");
		}
	}

}
class Person{
	public void getInfo() {
		System.out.println("Person...getInfo");
	}
}
class Student extends Person{
	public void getInfo() {
		System.out.println("Student...getInfo");
	}
}
class Graduate extends Student{
	public void getInfo() {
		System.out.println("Graduate...getInfo");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值