Java——面向对象的编程学习之多态性

编程入门 行业动态 更新时间:2024-10-25 04:21:57

Java——面向对象的编程学习之<a href=https://www.elefans.com/category/jswz/34/1764710.html style=多态性"/>

Java——面向对象的编程学习之多态性

详解Java面向对象的三大特征之三——多态性

  • 何为多态性
  • 多态性的使用前提:
  • 多态的使用:虚拟方法调用
  • 向下转型
  • instanceof关键字

何为多态性

  1. 多态性可以理解为一个事物的多种形态。在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。
  2. 对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用
  3. 如在方法的重写中提到:多态性分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,主要指方法的重写,它是通过动态绑定来实现的,也就是大家通常所说的多态性。

举例

class Person{}class Man extends Person{}public class Test{public static void main(String[] args){Person p1 = new Man();}
} 

在上面代码中,定义了两个类,并且Man()类继承了Person()类,“Person p1 = new Man();”,此行代码即为父类的引用指向子类的对象。

多态性的使用前提:

  • 需有类的继承关系
  • 方法的重写
  • 向上转型:在多态中需要将子类的对象赋给父类的引用,只有这样该引用才既能调用父类的方法,又能调用子类的方法。

多态的使用:虚拟方法调用

  1. 子类中定义了与父类同名同参数的方法(即方法的重写),在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
  2. 有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类中重写父类的方法。
    一句话概括就是:编译,看左边;运行,看右边。
public class Test{public static void main(String[] args) {Person p1 = new Chinese();p1.speak();// p1不能调用子类中特有的方法,会报错// p1.skin();System.out.println("age:" + p1.age);}
}class Person{int age = 20;private String name;public void speak(){System.out.println("人可以说话");}
}class Chinese extends Person{int age = 30;@Overridepublic void speak() {System.out.println("中国人说汉语");}public void skin(){System.out.println("黄皮肤");}
}

在上面代码中,父类Person()中定义了方法speak(),在子类Chinese()中,重写了此方法。根据前面总结的:编译时看左边,运行时看右边,此时如果我们想要查看“ p1.speak() ”具体调用的是哪个方法(将鼠标放在p1.speak()上,按住Ctrl键,然后点击鼠标),会发现eclipse指向了父类Person()中定义的speak()方法;但是,当我们运行程序时,实际输出的内容是“中国人说汉语”,说明运行时,实际调用的是子类Chinese()中重写的speak()方法。
注意:

  • 对象p1不能调用子类中特有的方法,如代码中的“ skin() ”。
  • 对象的多态性只适用于方法,不适用于属性。
    上述代码运行结果:

向下转型

按照上面代码中的写法“ Person p1 = new Chinese(); ”,我们可以调用子类中重写父类的方法,但不能调用子类特有的方法,如果我们想要调用子类特有的方法,就需要用到向下转型(使用强制类型转换)。即

public class Test{public static void main(String[] args) {Person p1 = new Chinese();p1.speak();// p1不能调用子类中特有的方法,会报错// p1.skin();System.out.println("age:" + p1.age);System.out.println("-----------------------");Chinese c1 = (Chinese)p1;   // 向下转型c1.skin();}
}

输出结果:
但是,在使用向下转型时,有可能出现ClassCastException的异常,例如:

class American extends Person{@Overridepublic void speak() {System.out.println("美国人说英语");}
}public class Test {public static void main(String[] args) {Person p1 = new Chinese();p1.speak();// p1不能调用子类中特有的方法,会报错// p1.skin();System.out.println("age:" + p1.age);System.out.println("-----------------------");Chinese c1 = (Chinese)p1;c1.skin();American a1 = (American)p1;}
}

上面代码中,子类American()同样继承了父类Person(),在程序运行时,会在“ American a1 = (American)p1; ”出现异常:
为了避免在向下转型时,出现此异常,我们可以使用instanceof关键字。

instanceof关键字

  1. a instanceof A:判断对象a是否是类A的实例。如果是,返回true;如果不是,返回false
  2. 使用情境:为了避免在向下转型时出现ClassCastException的异常,我们在向下转型之前,先进行instanceof的判断,一旦返回true,就进行向下转型。如果返回false,就不进行向下转型。
  3. 如果a instanceof A返回true,则a instanceof B也返回true。其中,类B是类A的父类。

举例

public class Test {public static void main(String[] args) {Person p1 = new Chinese();p1.speak();// p1不能调用子类中特有的方法,会报错// p1.skin();System.out.println("age:" + p1.age);System.out.println("-----------------------");Chinese c1 = (Chinese)p1;c1.skin();Person p2 = new American();if(p2 instanceof Chinese){System.out.println("p2 is a Chinese");}if(p2 instanceof American){System.out.println("p2 is a American");}}
}

输出结果:

更多推荐

Java——面向对象的编程学习之多态性

本文发布于:2023-07-28 15:26:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1235716.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:多态性   面向对象   Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!