1、知识点概述
java作为一门面对对象的语言,首先具有的便是三大特性:封装、继承、多态;个人认为多态之所以会放在封装、继承之后成为第三大特性,有一定的程度上是因为其部分建立在前两大特性的基础上的,继承是指某一类继承了其父类的一些属性和方法。而多态讲的是在存在父类与子类的基础上,即有继承性上的另一种性质,而封装性则在类这一定义上便有了体现,因此说多态是建立在前两个基础上的。常说的多态指的是使用父类对象的地方都可以使用子类的对象,即意味着父类型的变量可以引用子类型的对象。
2、背景知识
有了多态,自然会有人会说为什么会有多态。多态存在的好处体现在下面五个方面:
1、可替换性。
例如对圆Circle类工作时,对于其他的任何圆形几何体像圆柱等也可以工作。
2、可扩容性。
即在父类上添加新的子类不会影响父类的多态性,从而使其是一种动态可变的方式。
3、接口性。
多态其实和接口很像,为他的子类提供了一个共同接口,从而使两个子类可以同时调用。
4、灵活性。
多态性的存在使得代码整体上更加灵活,更加富有多变。
5、简化性。
利用多态性可以减少代码得数量和简化修改过程,减少了程序员的工作量。
3、知识点详述
(1).动态绑定
在讲述多态性之前,首先要介绍java中的动态绑定机制。动态绑定中有着两个重要的术语:声明类型和实际类型。在创建变量时,一定要对此变量进行一个类型的说明,即为某种类型的变量。这个类型称作声明类型。但是对类型赋值时我们可以将别的类型的值赋给他,这个值的类型叫做实际类型。而变量的调用以及其方法与属性都是由实际类型决定,这就叫做动态绑定。
(2).向上转型和向下转型
知晓动态绑定机制后,接下来就是转型了。转型分为向上转型和向下转型。向上转型指的是把一个子类的实例转化为一个父类的变量,因为子类的实例总是父类的实例。向下转型指的是当需要把一个父类的实例转化为其子类变量。所以必须使用转换标记符(子类名)来进行向下转型,向编译器表达你的要求。但是向下转型并不是都可以转换成功的,会存在转换的变量并不是原来实例的子类,所以会出现异常。因此在进行向下转型时,可以先通过操作符instanceof来判断转换的变量是否为原来实例的子类,从而使程序成功运行。
(3).多态性
1.为了更好地去理解多态性,我先从多态性的一些现实意义中先去描述,再从代码中去描述。首先,多态性的现实意义可以描述为现实的一个事物中会出现多种形态,如学生,是属于人的一种,而同学张三,他既是人又是学生,因此说其有着多种形态。
2. 而在java中我们可以这么去理解,我们建立了一个person类和person类的子类student类,当我们去new一个student对象zhangsan时,那么zhangsan既是person类的实例,也是student类的实例,因此我们在定义时便可以将张三定义为person类或者是student类。
3. 用比较学术性的语言描述便是多态体现为父类引用变量可以指向子类对象(或子类的对象赋给父类)。
4.多态的定义和格式:
定义格式:父类类型 变量名=new 子类类型();
5.多态的其他理解:
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
二:下面为java中多态性的代码展示。
父类Person类
package duotai;
public class Person {
int age;
String name;
public void eat(){
System.out.println("吃饭");
}
public void walk(){
System.out.println("走路");
}
}
子类Student类
package duotai;
public class Student extends Person {
String grade;
public void eat(){
System.out.println("学生吃肉");
}
public void walk(){
System.out.println("学生骑车");
}
}
PersonTest
package duotai;
public class PersonTest {
public static void main(String[] args) {
Person zhangsan=new Student();
zhangsan.eat();
zhangsan.walk();
}
}
运行结果:
从代码中可以发现,张三是Person类,但其指向一个Students类,因此我们在调用eat和walk方法时调用的是重写之后的Student中的eat和walk方法。而非person中的eat和walk方法。但是如果我们调用一个Person类中不存在的方法,但在Student类中存在的方法,会发现在运行时会报错。
上述所描述的情况其实是java中动态绑定机制下的一个结果,张三作为一个实例,在调用其方法时,首先会从其最底层的子类先去寻找相对应的方法,也便是重写的方法,如果不存在则会一层一层往上去寻找,知道找到为止,然后实现并停止查找。如果没有找到那么自然就会报错。
与方法相比较,多态性是不会对属性起作用的,即属性为父类的属性,属性的值也为父类的属性,而不会去由子类里的属性,这是一个与方法的区别,需要特别关注!!!
在多态性中存在一个对象转换的概念:即我们上面对多态定义的格式称之为隐式转换,但当我们需要将一个已经存在的对象赋值给一个新的变量时,便要使用显示转换,即在对象前加一个其是属于哪种类的对象,来告诉编译器。语法为用圆括号把目标对象的类型括起来,然后放到要转换的对象面前,例如这样子:student lisi=(student)zhangsan,(而这种student lisi=zhangsan则是错误的)。显示转换和隐式转换用在什么地方呢?当我们要把子类的实例转换为父类的变量的时,可以用隐式转换,也称之为向上转换。但把父类的实例转换为子类的变量时便要用显示转换,也为向下转换。
但有时会存在着要转换为子类的变量并不是子类的实例的情况,因此便要去判断一下是否为子类的实例来防止程序出错,因此便可以使用instanceof关键字来判断,若是则返回True,不是则返回False。
4、扩展使用场景
多态性在代码书写中有着巨大的作用。例如当我们需要通过调用一个类的一个方法来实现不同的功能时,便可以使用多态性。在父类上创建一个方法,然后在不同的子类里进行重写,从而能够使不同的子类的声明类型都定义为父类的类型,从而使得能够在一个循环内将不同的子类方法都进行调用。这是其中的一个使用场景。
5、小结
多态性看似是一个十分简单的性质,对于其使用貌似也并不是特别需要,但是当你在项目的进行过程中,会逐渐发现多态性的应用场景之妙,应用多态性的代码的美丽。因此,要想真正的熟悉和理解多态性,最关键的是要从项目中找取经验。