一、原理讲解
1.多态性的理解:一类事物的多种形态
2.广义上多态性的体现:①方法的重写,方法的重载 ②子类对象的多态性
3.狭义上多态性的体现:子类对象的多态性
4.何为子类对象多态性:父类的引用指向子类的对象
5.多态性的说明:
思考:属性有没有多态性?没有
思考:如果需要调用子类中的特有(父类没有的)的属性和方法怎么办?用(强转的类型)向下转型
6.多态性使用的前提:
①要有继承关系 ②要有方法的重写 ③父类的引用指向子类的对象
7.关于向上转型与向下转型:
向上转型:多态(父类的引用指向子类的对象)
向下转型:把父类的引用再转成子类的
8.1 为什么要使用向下转型:为了调用子类对象中独有的属性和方法。
①向下转型可能会出现:ClassCastException
原因:拟转换的对象实例没有指向希望转换为的子类的对象
②②向下转型可以使用类型判断运算符instanceof :
boolean result = obj instanceof Class
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。
https://www.cnblogs.com/ysocean/p/8486500.html
③向下转型需要使用:强制类型转换符 - ( )
9.面试题:
①多态是编译时行为还是运行时行为?运行时行为
10. instanceof的使用
a instanceof A : 对象实例a是否是A类或者A的子类的一个实例
a指向的对象 instanceof a对象所在的类或者其父类 : true
a指向的对象 instanceof a对象所在类的子类 : false
注意 : 如果使用if-else if判断多个类型,那么子类在上面,父类在下面。
package com.atguigu.java;
public class Creature {
public void say(){
System.out.println("Creature say");
}
public void show(){
System.out.println("Creature show");
}
}
package com.atguigu.java;
public class Person extends Creature{
String name ="person";
public void say() {
System.out.println("person say");
}
public void show() {
System.out.println("person show");
}
}
package com.atguigu.java;
public class Man extends Person {
@Override
public void say() {
System.out.println("男人恶狠狠的说话");
}
@Override
public void show() {
System.out.println("男人肌肉秀");
}
public void smoking() {
System.out.println("男人不抽烟,女人不喜欢");
}
}
package com.atguigu.java;
public class Man extends Person {
@Override
public void say() {
System.out.println("男人恶狠狠的说话");
}
@Override
public void show() {
System.out.println("男人肌肉秀");
}
public void smoking() {
System.out.println("男人不抽烟,女人不喜欢");
}
}
package com.atguigu.java;
public class Woman extends Person {
public String name = "woman";
@Override
public void say() {
System.out.println("女人嘤嘤的说话");
}
@Override
public void show() {
System.out.println("女人美美的秀");
}
public void buy() {
System.out.println("女人逛街买买买");
}
}
package com.atguigu.java;
public class PersonTest {
private static Creature c;
public static void main(String[] args) {
/*
* 本态
*/
//Person p = new Person();
//p.show();
//多态--动态绑定
Person p = new Woman(); //p引用的是父类Person,指向的是Woman子类的对象,即p是Woman子类的实例(对象)
p.show();//虚拟方法调用(调用的被重写的方法)--编译(javac)看左边,运行(java)看右边,看左边的Person有木有这个方法show,看右边是哪个对象调用就运行哪个对象的这个方法
p.say();
//p.buy(); 编译错误-因为左边的Person父类中没有buy方法
//思考:属性有多态性吗?-没有
//System.out.println(p.name);
System.out.println("------------------------------");
//思考:如果需要调用子类中的特有(父类没有的)的属性和方法怎么办? 用(强转类型转换符)向下转型
Woman w = (Woman)p;//注意:p指向的对象必须Woman子类的对象才可以这么强转
w.buy();
System.out.println( w.name);
//Man m = (Man)p; //抛出错误:ClassCastException类型转换异常
/*
* 为了解决类型转换异常可以在向下强转时使用intanceof
* a instanceof Woman : 对象实例a是否是Woman类的一个实例(对象)
*/
if(p instanceof Man){
System.out.println("我是一个爷们");
Man m =(Man)p;
}else if(p instanceof Woman){
System.out.println("我美女");
Woman wm =(Woman)p;
}
System.out.println("-------------------------");
p = new Woman();
System.out.println(p instanceof Man); //false
System.out.println(p instanceof Woman);//true
System.out.println(p instanceof Person);//true
System.out.println(p instanceof Creature);//true
System.out.println("-------------------------");
Creature c = new Creature();
System.out.println(c instanceof Man); //false
System.out.println(c instanceof Woman);//false
System.out.println(c instanceof Person);//false
System.out.println(c instanceof Creature);//true
System.out.println("-------------------------");
Creature cre = new Woman();
cre.show();
Person per =(Person) cre;
per.show();
//常见错误
Object obj =new String ("ccc");
//Person person = (Person) obj;//抛出ClassCastException,因为obj指向的是String
}
}
二、案例讲解
package com.atguigu.java2;
public class PhoneTest {
public static void main(String[] args) {
PhoneTest pt = new PhoneTest();
/* //1.创建手机对象并调用方法
WindowPhone wp = new WindowPhone();
wp.call();
wp.sentMessage();
//-------1000多个方法--------------
WindowPhone wp2 = new WindowPhone();
wp2.call();
wp2.sentMessage();
//-------1000多个方法--------------
*/
//1.创建手机对象并调用方法
WindowPhone wp4 = new WindowPhone();
// WindowPhone wp3 = new WindowPhone();
// pt.useWP(wp3);
pt.useWP(wp4);
AndroidPhone ap = new AndroidPhone();
pt.useWP(ap);
}
//Phone phone = wp4; 多态 :wp4是子类WindowPhone的对象实例,赋值给了父类Phone的引用
//Phone phone = ap; 多态
public void useWP(Phone Phone){
Phone.call();
Phone.sentMessage();
//-------1000多个方法--------------
}
/* public void useWP(AndroidPhone ap){ //把多个方法封装在一起
ap.call();
ap.sentMessage();
//-------1000多个方法--------------
}
public void useWP(WindowPhone wp){ //把多个方法封装在一起
wp.call();
wp.sentMessage();
//-------1000多个方法--------------
}
*/
}
class WindowPhone extends Phone{
public void call(){
System.out.println("WindowPhone call");
}
public void sentMessage(){
System.out.println("WindowPhone sentMessage");
}
}
class AndroidPhone extends Phone{
public void call(){
System.out.println("AndroidPhone call");
}
public void sentMessage(){
System.out.println("AndroidPhone sentMessage");
}
}
class Phone{
public void call(){
System.out.println("phone call");
}
public void sentMessage(){
System.out.println("phone sentMessage");
}
}