第四章、Java面向对象(五)
本人也是刚入门Java语言,可能会有一些地方出现错误,描述的不对。如果发现不对的地方请及时指出,好对其进行修改。这样不仅可以让我学到东西,也可以让其他刚入门的朋友学习更正确的内容。
所有内容仅供参考。不具有完全的准确性!
注:关于Java的所有内容都会参考到尚硅谷在网上公开的学习视频及其提供的PPT
一、面向对象特征之多态性
推荐:https://www.cnblogs.com/chenssy/p/3372798.html
(一)什么是多态
-
可以理解为一个事物的多种形态
-
对象的多态性:父类的引用指向子类的对象(可以直接应用在抽象类和接口上)
-
语法格式:
父类 引用名 = new 子类(); -
Java引用变量有两个类型:编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简称:编译时,看左边;运行时,看右边。
若编译时类型和运行时类型不一致,就出现了对象的多态性。 -
多态情况下:
“看左边”:看的是父类的引用(父类中不具备子类特有的方法)
“看右边”:看的是子类的对象(实际运行的是子类重写父类的方法)
(二)多态的使用
实现多态有三个必要条件:继承、重写、向上转型。
**继承:**在多态中必须存在有继承关系的子类和父类。
**重写:**子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
**向上转型:**在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
一个引用类型变量如果声明为父类的类型,但实际引用的是子类对象,那么该变量就不能再访问子类中添加的属性和方法
Student m = new Student();
m.id= 1001; //合法,Student类有id成员变量
Person e = new Student();
e.id= 1001; //非法,Person类没有school成员变量
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译错误。
例:
class Person{
String name;
public void eat(){
System.out.println("我是Person类中的eat()方法");
}
}
class Student extends Person{
int id;
public void eat(){
System.out.println("我是Student类中的eat()方法");
}
}
class Test{
public static void main(String[] args){
//父类类型的引用可以指向子类的对象:可以称之为向上转型
Person p = new Student();
p.eat();
p.name = "张三";
p.id = 1001; //此时编译报错,不能调用子类中独有的属性和方法
}
}
(三)多态的作用
- 可替换性。多态对已存在的代码具有可替换性。
- 可扩充性。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。
- 接口性。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
- 灵活性。它在应用中体现了灵活多样的操作,提高了使用效率。
- 简化性。多态简化了对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。值得注意的是,多态并不能够解决提高执行速度的问题,因为它基于动态装载和地址引用,或称动态绑定。
补充
注意:
new 的对象(子类),该对象及父类中的属性和方法都存在堆空间中,但不能调用子类特有的属性和方法。也并不是完全的无法调用子类特有的方法和属性
实现方法:通过向下转型(强制类型转换)
Person p1 = new Man();
Man m = (Man)p1;
或((Man)p1).goShopping();